·您当前的位置:首页 > 技术教程 > Rtsp技术 >

[Rtsp]rtsp协议转换为rtmp协议用处理方法

时间:2014-07-06 18:24酷播
用户需要通过flash或手机看监控视频,而目前绝大多数摄像机都是RTSP协议,所以需要做一个中转

一 背景:
用户需要通过flash或手机看监控视频,而目前绝大多数摄像机都是RTSP协议,所以需要做一个中转。
参考资料:
http://blog.csdn.net/firehood_/article/details/8813587
http://blog.csdn.net/firehood_/article/details/8783589
这两篇文章详细说明了mp4v2保存文件和把264文件通过RTMP直播,对这两方面感兴趣的可以直接看这两文章。本文只是把这两文章中读264转存转发改成读rtsp转存转发,多了一点live555的内容,其他基本一样,只稍调整了一点点接口部分。

二 流程:
1 live555从摄像机读音视频,为了便于讲解这里只讨论视频。
2 mp4v2保存成.mp4
3 librtmp上传视频流到nginx
4 web用户通过flash观看

三 技术讲解:
1  live555读RTSP视频,可以参考playCommon.cpp或testRTSPClient.cpp,前者功能全,后者简洁一些,不过支持多路流同时访问。如果自己写RTSP Client,环境不是很复杂,可以参考这份代码。
RTSP接收到H264视频后,不管是读写文件还是发送流,主要的问题就在SPS和PPS上面。这两个名字这里不做解释,自行google,这里只讲怎么取到这两个参数。
读live的源码,注意 playCommon.cpp中有一段:

else if (strcmp(subsession->mediumName(), "video") == 0 &&
   (strcmp(subsession->codecName(), "H264") == 0)) {
 // For H.264 video stream, we use a special sink that adds 'start codes', and (at the start) the SPS and PPS NAL units:
 fileSink = H264VideoFileSink::createNew(*env, outFileName,
 subsession->fmtp_spropparametersets(),
 fileSinkBufferSize, oneFilePerFrame);


这里调用H264VideoFileSink保存264文件,播放正常,所以我们需要研究H264VideoFileSink的源码。
只需注意H264VideoFileSink.cpp里面的afterGettingFrame函数,如下:
if (!fHaveWrittenFirstFrame) {
    // If we have PPS/SPS NAL units encoded in a "sprop parameter string", prepend these to the file:
    unsigned numSPropRecords;
    SPropRecord* sPropRecords = parseSPropParameterSets(fSPropParameterSetsStr, numSPropRecords);
    for (unsigned i = 0; i < numSPropRecords; ++i) {
      addData(start_code, 4, presentationTime);
      addData(sPropRecords[i].sPropBytes, sPropRecords[i].sPropLength, presentationTime);
    }
    delete[] sPropRecords;
    fHaveWrittenFirstFrame = True; // for next time
  }

  // Write the input data to the file, with the start code in front:
  addData(start_code, 4, presentationTime);
  
  注释的很明显了,这里再简单说一下:
  for (unsigned i = 0; i < numSPropRecords; ++i) {
      addData(start_code, 4, presentationTime);
      addData(sPropRecords[i].sPropBytes, sPropRecords[i].sPropLength, presentationTime);
    }
    这里的sPropRecords是从外面传进来的参数:subsession->fmtp_spropparametersets(),从名字上看就是sps和pps合在一起的内容。
    debug就可以发现,numSPropRecords==2,for循环两次,第一次是sps,第二次就是pps了。把这两个记住,保存264和发送RTMP时写在相应的位置,所有的工作基本就完成了。
    
2 mp4v2的api非常简单,没什么好说,唯一注意一点就是先从sps中读取视频的宽和高。可以参考后面代码。
3 librtmp,也很简单,只要注意先发关sps和pps
4 直播服务器用nginx+nginx_rtmp_module, google一下,文档很多。

四 运行环境: CentOS6.4及Ubuntu 12下运行正常。windows也可以,多平台时需要类型统一,比如UINT,BYTE,uint32_t, uint8_t ,稍稍改动一下就好。

 

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器