2011-04-08 127 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