我目前正在尝试使用Android作为一个Skype的端点。 在这个阶段,我需要对视频编码为H.264(因为它是由Skype支持的唯一格式),以使工作流与RTP封装它。
显然, MediaRecorder
不是很适合这种因各种原因。 其一是因为它完成后增加了MP4或3GP头。 另一个原因是因为为了减少延迟到最小,硬件accelaration可能会派上用场。 这就是为什么我想利用最近的低级别增列和框架,是MediaCodec
, MediaExtractor
等。
目前,我计划工作如下。 相机写入其视频到缓冲区中。 该MediaCodec编码与H264视频并将结果写入到另一个缓冲区。 此缓冲区由一个RTP-封装,其中所述流数据发送到服务器读取。 这是我的第一个问题:这是否计划你的声音是否可行?
现在,我已经买了第一步。 由于如何将摄像头在互联网上的所有文件利用了MediaRecorder
,我不能找到一种方法,它的原始数据保存到缓冲区在编码之前。 是addCallbackBuffer适合呢? 任何人有一个例子链接?
接下来,我无法找到一个关于MediaCodec大量的文档资料(因为它是相当新的)。 任何人谁拥有了坚实的教程?
最后:在RTP库中的任何建议?
非常感谢提前!
UPDATE
我终于能够从H264帧创建适当的RTP包。 这里是你必须记住(这其实很简单)是什么:
编码器确实产生针对每一帧NAL标头。 但它返回每一帧作为H264 字节流 。 这意味着,每个帧有三个0字节和1字节开始。 所有你需要做的是去除那些开始前缀,并把帧转换为RTP数据包(或使用FU-作为他们分手了)。
现在,您的问题:
我不能找到一种方法,它的原始数据保存到缓冲区在编码之前。 是addCallbackBuffer适合呢?
您应该使用camera.setPreviewCallback(...),每帧添加到编码器。
我无法找到一个关于MediaCodec大量的文档资料(因为它是相当新的)。 任何人谁拥有了坚实的教程?
这应该是一个很好的介绍,以该MediaCodec是如何工作的。 http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/
最后:在RTP库中的任何建议?
我使用jlibrtp它能够完成任务。
我不知道MediaCodec或MediaExtractor做任何事,但我相当熟悉MediaRecorder,并已成功实现的RTSP服务器,基于SpyDroid,捕捉从MediaRecorder H264 / AMRNB输出。 其基本思路是,该代码创建一个本地套接字对,并使用MediaRecorder的setOutputFile将输出写入在组插座一个。 然后,该程序读出从其他插座的视频或音频流,其解析为数据包,然后包裹每个分组为一个或多个被通过UDP发送RTP分组。
这是真的,MediaRecorder添加MOOV头,它的完成之后,但是,如果你在RTP格式服务H264视频不是一个问题。 基本上,有一个“mdat存储”头在视频流的开始。 它有4个字节用于报头的长度,接着的4个字节“的mdat”。 阅读长度,找出标题是怎么长的,验证它是MDAT头,然后跳过头数据的其余部分。 从那里,你会得到NAL单元,这与4个字节为单位的长度开始流。 小NAL单元可以在一个RTP包发送,较大的单位获得分成FU包。 对于RTSP,您还需要服务的SDP头描述流。 SpyDroid写一个很短的电影文件计算的SDP报头中的信息,然后读取该文件,从中提取结束moov头部。 我的应用程序总是使用相同的大小,格式和比特率,所以我只是起到一个静态的字符串:
public static final String SDP_STRING =
"m=video 5006 RTP/AVP 96\n"
+ "b=RR:0\n"
+ "a=rtpmap:96 H264/90000\n"
+ "a=fmtp:96 packetization-mode=1;profile-level-id=428028;sprop-parameter-sets=Z0KAKJWgKA9E,aM48gA==;\n"
+ "a=control:trackID=0\n"
+ "m=audio 5004 RTP/AVP 96\n"
+ "b=AS:128\n"
+ "b=RR:0\n"
+ "a=rtpmap:96 AMR/8000\n"
+ "a=fmtp:96 octet-align=1;\n"
+ "a=control:trackID=1\n";
这是我对640x480x10fps头,H264视频,与8000/16/1 AMRNB音频。
有一件事我可以向您发出警告:如果您使用MediaRecorder,您的预览回调将永远不会被调用。 这只能在相机模式,而不是当你录制视频。 我一直没能找到能够访问这些预览图像中未压缩格式,而视频记录的任何方式。
我强烈建议找过了SpyDroid的代码。 这需要一些周围挖掘,但我敢打赌,你想要的是在那里了。
您打算什么definetly可行的。 你可以注册一个Camera.PreviewCallback这需要的图像数据,并把它放入MediaCodec。 你读的输出,并把它作为RTP。 一般来说很容易,但也有各种缺陷如无证色彩空间和不同设备上的不同MediaCodec行为,但它是definetly可能。