2011-04-08 129 views
1

我開發了允許通過網絡傳播視頻流的Android應用程序的第一部分。目前,我以非常直接的方式發送視頻,如下所示:通過Android的套接字發送緩衝數據

Socket socket = new Socket(InetAddress.getByName(hostname), port); 
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); 
recorder.setOutputFile(pfd.getFileDescriptor()); 

但不幸的是,它不是很流暢。我想在通過套接字發送數據流之前緩衝數據流。我嘗試的一種方法是使用Android API for recording media將文件流寫入文件中,並使用另一個線程將文件流式傳輸到計算機上的服務器上。

所以我的問題是:我怎麼能通過一個套接字發送一個仍在寫入的文件? 作爲BufferedInputStream還沒有閱讀阻塞的方法,我試圖做這樣的事情之一,但沒有任何成功

while (inputStream.available() >= BUFFER_SIZE) { 
    inputStream.read(buffer); 
    outputStream.write(buffer); 
} 
outputStream.flush(); 

但是,當我做了,如果網絡比數據流速度,我得到迅速走出循環。

有沒有一個'好'的方法來做到這一點?我雖然在做積極的等待,但這不是一個好的解決方案,特別是對於手機。另一種方法是做這樣的事情:

while (true) { 
    while (inputStream.available() < BUFFER_SIZE) { 
    wait(TIME); 
    } 
    inputStream.read(buffer); 
    outputStream.write(buffer); 
} 
outputStream.flush(); 

但它聽起來對我來說很骯髒......有沒有光滑的解決方案?

回答

0

我想不出一個漂亮的方法來做到這一點,但一個選擇可能是創建一個本地套接字對,使用該客戶端的客戶端作爲MediaRecorder輸出fd,服務器套接字和遠程服務器。這樣,您可以阻止本地服務器,直到有數據。

另一種可能性是使用基於文件的管道/ FIFO(所以磁盤沒有填滿),但我不記得Java層是否公開mkfifo功能。

無論如何,你可能想看看FileReader,因爲讀取應該阻止。

希望這有助於

菲爾Lello

+0

好吧菲爾,感謝您的解決方案!我實現了它,它似乎很好地工作:) – Rob 2011-04-09 09:12:38

1

我在這些情況下做了什麼,如果只是填充一個字節數組(我的緩衝區),直到我碰到要傳輸的數據的末尾或緩衝區已滿。在這種情況下,緩衝區已準備好傳遞給我的Socket傳輸邏輯。無可否認,我不會在視頻或音頻上做到這一點,儘管......只是在「常規」數據上。

值得注意的是,這會給該數據的接收者帶來一個「非常棒」的用戶體驗(它可能看起來像網絡正在短暫停止,然後再次正常運行......緩衝區用於填充向上)。因此,如果您必須在視頻或音頻上使用緩衝方法,請注意您決定使用哪種緩衝區大小。

對於像視頻這樣的事情,我一直在使用基於流的邏輯與緩衝的邏輯,但你顯然有一些不同的和有趣的需求。

+0

您好,謝謝您的回答!不幸的是,在這種情況下,緩衝解決方案由於數據量而無法工作......而且,流量非常小的數據包(以及大量數據包)導致我使用的網狀網絡中的數據丟失。 – Rob 2011-04-08 04:38:39

+0

我承認當你問一個緩衝解決方案時我很好奇,但我同意對於視頻緩衝使得答案不好。有趣的是,流式傳輸似乎無法工作 - 至少在這種情況下 - 也適用於您。這一直是流媒體技術之間的一個折中方案,就是幾個數據包休息一會兒。大多數情況下,這是用戶無法接受的,但我可以看到網絡如何使這一聲明無效。 – BonanzaDriver 2011-04-08 15:02:02