【主题】
如何修改 testRTSPClient 来接收音视频流,并通过mp4v2 将音视频流录制为mp4(audio:aac,video:h264)
【测试 rtsp url】
rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
【介绍】
1. testRTSPClient是live555提供的测试client,和live555提供的另一款client——openRTSP相比,简单、好用的多,只需要在原版testRTSPClient.cpp修改即可。
2. mp4v2是一款录制mp4的开源库,感觉比ffmpeg的mp4录制更简单、更高效
3. 本文所用的testRTSPClient、mp4v2均为最新版(2014/05),VS 2010工程见附录,下载资源1分,thanks
4. 录制文件为 “lsh.mp4", 位于工程当前目录
【关键代码】
摘自testRTSPClient..cpp中的DummySink::afterGettingFrame
// 通过循环来停止录制,录制时间90秒左右
static int count = 1;
//
if(count++ == 6000){
m_mp4Encoder->CloseMp4Encoder();
MessageBoxA(NULL,"end","end",MB_OK);
}
// 录制视频
if ( 0==strcmp(fSubsession.mediumName(),"video") )
{
// testRTSPClient接收h264时会去掉起始码,此处手动添加
m_recvBuf[0] = 0x00;
m_recvBuf[1] = 0x00;
m_recvBuf[2] = 0x00;
m_recvBuf[3] = 0x01;
// 有些rtsp服务器不发送sps、pps,此处手动写入sps、pps至mp4v2
if(m_isInitSpsPps)
{
m_isInitSpsPps = false;
unsigned int num=0;
SPropRecord * sps=parseSPropParameterSets(fSubsession.fmtp_spropparametersets(),num);
//
for(int i=0;i<2;i++){
memcpy(&m_recvBuf[4], sps[i].sPropBytes, sps[i].sPropLength);
m_mp4Encoder->Mp4VEncode(m_recvBuf,sps[i].sPropLength+4);
}
delete[] sps;
}
// 不能直接将fReceiveBuffer传入mp4v2,需要拷贝,否则写入失败,原因未知
memcpy(&m_recvBuf[4], fReceiveBuffer, frameSize);
m_mp4Encoder->Mp4VEncode(m_recvBuf,frameSize+4);
}
if ( 0==strcmp(fSubsession.mediumName(),"audio") )
{
// testRTSPClient接收aac时,会去掉adts头,为RAW数据
memcpy(m_recvBuf,fReceiveBuffer,frameSize);
m_mp4Encoder->Mp4AEncode(m_recvBuf,frameSize);
}
【提示】
1.testRTSPClient可以切换底层传输协议,方法是 #define REQUEST_STREAMING_OVER_TCP false/true (udp/tcp)
如果你电脑位于局域网,则切换为tcp,不然只能rtsp通信,却无法接收流媒体数据
2.本文封装的mp4v2通过音频同步视频,同步效果良好,详见附件源码
【效果图】
【附件】
该源码已包括live555和mp4v2,编译即可运行,效果见上图