思路本文为博主原创文章,未经博主允许不得转载。(合作洽谈请联系QQ:1010316426)
基本思路分为两个步骤,第一个步骤是拉取rtsp码流,分离出视频帧和音频帧;第二个步骤是将这两种数据帧按照rtmp的码流封装格式进行打包,按照rtmp的推流流程进行推送到服务器。这样就完成了整个拉推的流程。
上一篇博客《基于live555制作RtspClientDLL库》讲解了上面流程的第一个步骤的主要部分,调用封装好的RtspClientDLL库就可以轻松得到分离后视频帧和音频帧。
本篇讲讲步骤二。步骤二也分两步:封装和推送。
封装
由于rtmp流封装的方法与flv的封装方法相同,因此我们最主要的是要掌握flv的封装协议,笔者使用的协议版本是《Adobe Flash Video File Format Specification_v10.pdf》。
FLV的封装格式并不复杂,只是里面涉及到的与具体码流有关的若干字段,如果没有一定的理论知识做积累是比较难以认识和理解的。
FLV的格式总体上是Header+Body的模式,其中Body又是T-L-V的模式。所谓T-L-V,即Type-Length-Value。只是Flv Body的TLV并不严格,稍稍有些变种。读者可以通过查看文档、网上浏览等途径整理出完整的FLV格式封装。
这里特别指出的是,FLV支持码流格式较多,我们常用的包括视频H264,音频AAC。因诞生FLV协议的当年H264刚出现不久,还没有H265,且近两年FLV协议也没有更新,所以视频并没有支持H265。
在rtmp推送H264和AAC直播流时,需要首先发送"AVC sequence header"和"AAC sequence header",这两项数据包含的是重要的编码信息,没有它们,解码器将无法解码。
AVC sequence header就是AVCDecoderConfigurationRecord结构,该结构在“ISO-14496-15 AVC file format”中有详细说明。
AAC sequence header存放的是AudioSpecificConfig结构,该结构则在“ISO-14496-3 Audio”中描述。
推送
笔者使用了librtmp库来进行推送,版本是v2.4,由于该库的输入buffer是flv格式,因此笔者自己编写代码实现A/V的flv封装打包。
它的接口调用流程如下图所示:
通过本篇博客的介绍,整理出一个完整的方法论,可以将任何的码流送到云端。通过推送rtmp到CDN,借助CDN,便可以实现监控转直播以及海量分发能力:
1.首先,调用SDK、rtsp/onvif、或GB28181,来获取前端摄像机的音视频实况流。(当然也可以获取到录像流)。
2.其次,将获取到的码流解复用,分离出一路视频通道和一路音频通道。分离出的通道必须是裸流,它的元数据(配置信息)必须存在或可知。
3.再次,将裸流封装打包成rtmp所需的flv格式。
4.最后,将flv流通过librtmp推送到云端的流媒体服务或CDN。