最近在用FFmpeg实时解码安卓MediaRecorder录制的H264视频流,碰到了诸多问题,在自己的坚持不懈的努力下,终于搞定了。下面跟大家分享一下整个过程。
1. 获取SPS与PPS信息
SPS与PPS信息主要用于FFmpeg分析码流数据,确定解码器等信息。MediaRecorder发送过来的MP4数据是不带SPS与PPS信息的,所以只能预先录制一小段视频形成MP4文件,然后通过分析MP4文件内容来获取sps与PPS信息,具体分析方法传送门:。分析得到SPS、PPS信息后,保存下来,今后相同手机相同分辨率就可以用这个信息啦。
注意,不同手机以及分辨率,SPS与PPS可能不同,在新设备上工作时,务必重新获取SPS与PPS。息。
2. 从MP4的mdat内获取H264流数据
MP4的H264视频数据保存在名为mdata的box当中,MediaRecorder通过socket发送出来的MP4数据包含四部分:填充符、ftyp、mdat、slice。其中slice就是我们要找的视频数据,slice是mdata的一部分,slice与mdata之间可能存在填充符,而slice与slice之间是连在一起的。slice由视频数据长度(4字节,前两个字节通常为0)和视频数据组成,其中视频数据是不带起始码的H264 Nalu单元,不难看出其第一个字节为0x65(关键帧)、0x41等。数据长度描述的是 H264 Nalu单元的长度,这样我们已经找到一帧完成的H264码流数据了,接下来我们只需将 Nalu单元提取出来前面加上0x00 00 00 01的4字节起始码我们就得到了H264裸数据,这样的数据在播放器上还不能播放,需在H264裸数据文件的最前端加上SPS与PPS信息(他们也是有起始码的哦),至此,播放器能够正常播放文件了。
3. FFmpeg播放H264流数据
不过要强调的是:ffmpeg需要通过分析数据来确定输入格式,所有程序启动时,ffmpeg收到的数据最先应该是SPS与PPS的nalu单元,然后是具体的视频数据。