从Android到PC /网络流式传输音频和视频。

时间:2011-07-28 19:10:23

标签: java android video audio streaming

我是Android SDK的新手,这个项目的总体目标是创建一个非常类似于Ustream或Qik的应用程序(是的,我知道不是初学者的最佳想法)。我需要将实时音频和视频流式传输到网络上。将有一个视频服务器,很可能使用Wowza,将视频编码处理为正确的格式。

从目前为止我发现,我需要使用android的MediaRecorder将相机作为源并将输出定向到服务器。这对我来说很有意义,但我不确切知道如何去做。任何人都可以给我一个正确的方向吗?我浏览了一下“http://ipcamera-for-android.googlecode.com/svn/trunk”中的一个例子,但这似乎比我需要做的事情要复杂得多,我一直无法得到无论如何,它在eclipse中工作以测试它。

2 个答案:

答案 0 :(得分:8)

这样做并不简单,但可能。

MediaRecorder API假设输出是一个随机访问文件,这意味着它可以前进和后退以写入mp4(或其他)文件容器。 正如您在ipcamera-for-android中看到的那样,输出文件被定向到一个非随机访问的套接字。 事实上,解析传出流很困难,因为MediaRecorder API只会在录制完成后“写入”某些数据,如fps,sps / pps(在h264上)等等。 API将尝试回寻到流的开头(文件头存在的位置),但由于流被发送到套接字而不是文件,因此它将失败。

使用ipcamera-for-android是一个很好的参考,如果我没记错,在流式传输之前,它会将视频记录到文件中,打开标题并从那里获取所需内容,然后开始录制到套接字并使用从标题中获取的数据来解析流。

在解析mp4(或您想要使用的其他文件容器)时,您还需要一些基本的了解才能捕获帧。 您可以在设备上或服务器端执行此操作。

这是将流写入套接字的良好开端: Tutorial

我希望它有用,没有很好的教程可以解析和解码传出流,因为它不是那么简单......但同样,可以付出一些努力。

另请查看如何将输出流定向到可以发送到服务器的流: MediaRecorder Question

答案 1 :(得分:0)

SipDroid完全符合您的需要。

它涉及到一个黑客来规避需要文件描述符的MediaRecorder类的限制。它将MediaRecorder视频流的结果保存到本地套接字(用作一种管道),然后重新读取(在同一应用程序中,但另一个线程)另一端的这个套接字,从接收的数据中创建 RTP数据包,最后将RTP数据包广播到网络(你可以在这里使用广播或单播模式,如你所愿)。

基本上归结为以下(简化代码):

// Create a MediaRecorder
MediaRecorder mr = new MediaRecorder();
// (Initialize mr as usual)
// Create a LocalServerSocket
LocalServerSocket lss = new LocalServerSocket("foobar");
// Connect both end of this socket
LocalSocket sender = lss.accept();
LocalSocket receiver = new LocalSocket();
receiver.connect(new LocalSocketAddress("foobar"));
// Set the output of the MediaRecorder to the sender socket file descriptor
mr.setOutputFile(sender.getFileDescriptor());
// Start the video recording:
mr.start();
// Launch a background thread that will loop, 
// reading from the receiver socket,
// and creating a RTP packet out of read data.
RtpSocket rtpSocket = new RtpSocket();
InputStream in = receiver.getInputStream();
while(true) {
    fis.read(buffer, ...);
    // Here some data manipulation on the received buffer ...
    RtpPacket rtp = new RtpPacket(buffer, ...);
    rtpSocket.send(rtpPacket);
}

RtpPacketRtpSocket类的实现(相当简单),以及操纵视频流内容的确切代码可以在SipDroid项目中找到(尤其是VideoCamera.java)。< / p>