RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播

RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司建立,后来归Adobe公司全部,是一种私有协议,主要用来联系Flash Player和RtmpServer,如FMS, Red5, crtmpserver等。RTMP协议可用于实现直播、点播应用,经过FMLE(Flash Media Live Encoder)推送音视频数据至RtmpServer,可实现摄像头实时直播。不过,毕竟FMLE应用范围有限,想要把它嵌入到本身的程序中,仍是要本身来实现RTMP协议的推送。本人实现了一个RTMPLiveEncoder,经过采集摄像头视频和麦克风音频,并进行H.264和AAC编码,而后发送到FMS和crtmpserver上,实现实时直播,能够经过flash player正常观看,目前效果良好,延迟时间在2秒左右。本文就介绍一下RTMPLiveEncoder的主要思路和关键点,以期对须要这方面技术的朋友有所帮助。html

技术分析

  要实现RTMPLiveEncoder,须要如下四种关键技术:linux

  • 采集摄像头视频和麦克风音频
  • H264编码和AAC编码
  • 视频和音频数据封装为可被流媒体服务器识别的可播放流
  • RTMP协议实现报文发送

  其中,前两项技术在我以前的文章“采集音频和摄像头视频并实时H264编码和AAC编码”中已经介绍过了,这里就再也不啰嗦了。windows

  把音视频数据封装为可播放流,这个是一个难点。仔细研究一下,你会发现,RTMP Packet中封装的音视频数据流,其实和FLV封装音频和视频数据的方式是相同的,因此,咱们只须要按照FLV封装H264和AAC的方式,便可生成可播放流。服务器

  咱们再看一下RTMP协议。Adobe曾经发布过一份文档《RTMP Specification》,不过wikipedia指出这份文档隐藏了不少细节,单独根据它是没法正确实现RTMP的。不过,它仍是有参考意义的。其实Adobe发布以前,RTMP协议就已经被破解的差很少了,如今也已经有比较完善的实现,好比:RTMPDump,它提供的是C语言的接口,这意味着能够很方便的在其余语言中调用。框架

程序框架

  与我以前写的“采集音频和摄像头视频并实时H264编码和AAC编码”这篇文章相同,采用DirectShow技术来实现音视频采集,音频编码和视频编码,在各自线程(AudioEncoderThread和VideoEncoderThread)中循环进行,RTMP的推送另起一个线程(RtmpThread)。两个编码线程实时编码音视频数据后,将数据交与Rtmp线程,由Rtmp线程循环封装为Rtmp Packet,而后发出去。ide

  线程之间的数据交换,经过一个队列DataBufferQueue来实现。AudioEncoderThread和VideoEncoderThread把数据指针post到DataBufferQueue以后,当即返回,这样就能够避免由于发送Rtmp报文的而影响到编码线程的正常执行时间。post

    

  RtmpThread的主要工做就是发送音频数据流的解码信息头和视频数据流的解码信息头,并不断从DataBufferQueue中取出数据,封装为RTMP Packet,发送出去。流程以下列代码所示:(process_buf_queue_,便是上图中的DataBufferQueue)编码

librtmp

1、编译librtmp

  下载rtmpdump的代码,你会发现,它是一个地道的linux项目,除了一个简单的Makefile,其余什么都没有。好像librtmp不依赖于系统,咱们能够不用费太多功夫,把它在windows上编译。不过,librtmp依赖于openssl和zlib,咱们须要首先编译好它们。spa

  1. 编译openssl1.0.0e.net

  a) 下载并安装ActivePerl

  b) 下载并安装nasm(http://nasm.sourceforge.net/)

  c) 解压openssl压缩包

  d) 运行cmd命令行,切到openssl目录,分别执行如下命令

>perl Configure VC-WIN32 --prefix=c:\some\dir >ms\do_nasm

  e) 运行Visual Studio Command Prompt(2010),切到openssl目录,分别执行如下命令。

>nmake -f ms\nt.mak >nmake -f ms\nt.mak install

  f) 编译完毕后,便可在第一个命令所指定的目录下发现编译好的sdk。

  2. 编译zlib

  a) 解压zlib压缩包

  b) 运行Visual Studio Command Prompt(2010),切到openssl目录,分别执行如下命令

>cd contrib\masmx86 >bld_ml32.bat

  c) 回到zlib目录,进入contrib\vstudio\vc10目录,打开vs2010解决方案文件,

     在zlibstat工程属性中,去掉预编译宏 ZLIB_WINAPI

  d) 选择debug或release编译便可

  3. 编译librtmp

  a) 首先打开visual studio 2010,新建一个win32 console工程,指定为静态连接库

  b) 将librtmp的代码导入工程,把openssl、zlib的头文件和librtmp放在一块儿,把编译好的openssl和zlib的静态库放在一块儿

        

  c) 在工程设置中,添加以前编译好的openssl和zlib的库,编译便可。

    

2、librtmp的使用

  首先初始化RTMP结构

  开始以后,就要向RTMP Server发起握手链接报文

  链接成功,就能够开始循环发送报文了,这里须要指定时戳和数据类型(Audio、Video、Metadata)。这里有一点须要注意的是,在调用Send以前,buf中的数据,必须是已经封装好的H264或AAC数据流。

  关闭

  最后是释放

 

H264和AAC数据流

  本文提到过,RTMP推送的音视频流的封装形式和FLV格式类似,由此可知,向FMS推送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”中描述。AudioSpecificConfig结构的描述很是复杂,这里我作一下简化,事先设定要将要编码的音频格式,其中,选择"AAC-LC"为音频编码,音频采样率为44100,因而AudioSpecificConfig简化为下表:

    

  这样,AVC sequence header和AAC sequence header的内容能够基本肯定了,更详细的信息,你们能够去翻阅相关文档。

    

运行效果

  RtmpLiveEncoder开始运行

    

  用FMS自带的一个flash播放器播放

    

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  HaibinDev软件工做室,合做请联系QQ。(转载请注明做者和出处~)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

相关文章
相关标签/搜索