用libmp4v2录制h264和aac rtp流为mp4文件

1、首先解析sdp
以下为sdp示例
v=0\r\n
o=StreamingServer 3677551774 1468548697000 IN IP4 172.16.23.170\r\n
s=/test_0.109.mp4\r\n
u=http:///\r\n
e=admin@\r\n
c=IN IP4 0.0.0.0\r\n
b=AS:1343\r\n
t=0 0\r\n
a=control:*\r\n
a=x-copyright: MP4/3GP File hinted with GPAC 0.6.1-revrelease (C)2000-2005 - http://gpac.sourceforge.net\r\n
a=range:npt=0- 510.11900\r\n
m=video 0 RTP/AVP 96\r\n
b=AS:1215\r\n
a=3GPP-Adaptation-Support:1\r\n
a=rtpmap:96 H264/90000\r\n
a=control:trackID=65536\r\n
a=fmtp:96 profile-level-id=42C00D; packetization-mode=1; sprop-parameter-sets=Z0LADdoBQBbsBEAAAPpAAC7gA8UKqA==,aM4PyA==\r\n
a=framesize:96 1280-720\r\n
m=audio 0 RTP/AVP 97\r\n
b=AS:128\r\n
a=3GPP-Adaptation-Support:1\r\n
a=rtpmap:97 mpeg4-generic/44100/2\r\n
a=control:trackID=65537\r\n
a=fmtp:97 profile-level-id=41; config=1210; streamType=5; mode=AAC-hbr; objectType=64; constantDuration=1024; sizeLength=13; indexLength=3; indexDeltaLength=3\r\n

a、解析出h264的sps(sprop-parameter-sets),pps,并从sps中解析出width,height,帧率
b、解析出video stream id(96), audio stream id(97)
c、解析出audio的采样率44100(a=rtpmap:97 mpeg4-generic/44100),码率(b=AS:128kbps),解码信息(config=0x1210),sample duration (constantDuration=1024)

2、调用libmp4v2接口初始化:
a、创建mp4文件
Mp4File_ = MP4CreateEx(filename.c_str());
b、初始化视频track
MP4SetTimeScale(Mp4File_, 90000);
nVideoTrack_ = MP4AddH264VideoTrack(Mp4File_,
90000, //timescale
90000/iFps, //sample duration
iWidth, //width:
iHeight, //height:
AVCProfileIndication, //sps[1] AVCProfileIndication
profile_compat, //sps[2] profile_compat
AVCLevelIndication, //sps[3] AVCLevelIndication
3); // 4 bytes length before each NAL unit
MP4SetVideoProfileLevel(Mp4File_, AVCProfileIndication);
MP4AddH264SequenceParameterSet (Mp4File_, nVideoTrack_, sps.c_str(), sps.length());
MP4AddH264PictureParameterSet (Mp4File_, nVideoTrack_, pps.c_str(), pps.length());

c、初始化音频track
nAudioTrack_ = MP4AddAudioTrack(Mp4File_, uiAudioSampleRate, uiAudioSampleDuration!=0?uiAudioSampleDuration:MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
MP4SetTrackESConfiguration(Mp4File_, nAudioTrack_, audioConfig, configLen);
MP4SetAudioProfileLevel(Mp4File_, 0x29);

3、收到rtp数据包,根据rtp payload type写视频及音频
注意点:
a、写视频时
解析nalu的类型,type=payload[0]&0x1f
+===============+
|0|1|2|3|4|5|6|7|
+=+=+=+=+=+=+=+=+
|F|NRI| Type |
+===============+
0 没有定义
1-23 NAL单元 单个NAL单元包
24 STAP-A 单一时间的组合包
25 STAP-B 单一时间的组合包
26 MTAP16 多个时间的组合包
27 MTAP24 多个时间的组合包
28 FU-A 分片的单元
29 FU-B 分片的单元
30-31 没有定义

如为FU分片则需根据分片规则,将payload组合起来
如为STAP组合则需根据规则将长度字节解析出来取payload
如为单个nal单元包,则直接取payload

解析到一帧数据将数据写到mp4中,需要在前面加上4个字节长度(大端字节序,不包括长度4字节),然后调用以下接口写入mp4文件;
MP4WriteSample(Mp4File_, nVideoTrack_, (uint8_t*)pPayload, iLen);

如根据时间片来录制视频需要判断是否关键帧,来结束上一段mp4,创建新的mp4文件

b、写音频时
I、解析音频payload时,去掉头2个字节及根据头2字节得到ausize长度

II、需要加上duration,否则不能正常播放:
duration = payloadlen * audiosamplerate * 8 / audiobitrate;

然后将得到的负载写入mp4相应track:
MP4WriteSample(Mp4File_, nAudioTrack_, (uint8_t*)pPayload, iLen, duration);

你可能感兴趣的:(流媒体开发)