C ++实现RTMP协议以发送H.264编码和AAC编码的音频和视频,摄像机直播

优采云 发布时间: 2020-08-07 22:27

  C ++实现RTMP协议以发送H.264编码和AAC编码的音频和视频

  RTMP(实时消息协议)是一种专门用于传输音频和视频数据的流媒体协议. 它最初由Macromedia创建,后来由Adobe拥有. 它是一个专用协议,主要用于联系Flash Player和RtmpServer. 如FMS,Red5,crtmpserver等. RTMP协议可用于实现实时广播和点播应用程序,并通过FMLE(闪存媒体实时编码器)将音频和视频数据推送到RtmpServer,从而可实现实时实时摄像机的广播. 但是,毕竟FMLE的应用范围是有限的. 如果要将其嵌入自己的程序中,则仍然必须自己实现RTMP协议推送. 我实现了一个RTMPLiveEncoder,它可以采集摄像机视频和麦克风音频,并使用H.264和AAC对其进行编码,然后将它们发送到FMS和crtmpserver以实现实时实时广播,可以通过Flash Player正常观看. 当前效果良好,延迟时间约为2秒. 本文介绍了RTMPLiveEncoder的主要思想和要点,希望能帮助需要此技术的朋友.

  技术分析

  要实现RTMPLiveEncoder,需要以下四个关键技术:

  其中,在前一篇文章“音频和摄像机视频的获取以及实时H264编码和AAC编码”中介绍了前两种技术,因此在这里我不会太冗长.

  将音频和视频数据打包到可播放的流中是困难的一点. 如果仔细研究,您会发现封装在RTMP数据包中的音频和视频数据流实际上与封装音频和视频数据的FLV相同. 因此,我们只需要根据FLV封装H264和AAC即可生成Play流.

  让我们再次看看RTMP协议. Adobe曾经发布过一个文档“ RTMP规范”,但是Wikipedia指出该文档隐藏了许多细节,仅凭它不可能正确实现RTMP. 但是,它仍然具有参考意义. 实际上,RTMP协议在Adobe发布之前就几乎被破解了,现在有相对完整的实现,例如RTMPDump,它提供了C语言接口,这意味着可以用其他语言轻松地调用它.

  程序框架

  与我之前在“获取音频和摄像机视频以及实时H264编码和AAC编码”之前写的文章相同,该文章使用DirectShow技术在各自的线程(AudioEncoderThread)中实现音频和视频捕获,音频编码和视频编码和VideoEncoderThread),在中间循环中,RTMP的推送将启动另一个线程(RtmpThread). 两个编码线程对音频和视频数据进行实时编码后,将数据移交给Rtmp线程,然后Rtmp线程循环封装Rtmp数据包,然后将其发送出去.

  线程之间的数据交换是通过队列DataBufferQueue实现的. 将数据指针发布到DataBufferQueue后,AudioEncoderThread和VideoEncoderThread将立即返回,以避免由于发送Rtmp消息而影响编码线程的正常执行时间.

  

  RtmpThread的主要工作是发送音频数据流的解码信息头和视频数据流的解码信息头,并不断从DataBufferQueue中取出数据,将其封装为RTMP数据包,然后发送出来. 该过程如以下代码所示: (process_buf_queue_,即上图中的DataBufferQueue)

  

  librtmp一,编译librtmp

  下载rtmpdump的代码,您会发现它是一个真实的linux项目,除了简单的Makefile,其他都没有. 看来librtmp并不依赖于系统,因此我们可以在Windows上编译它而无需花费太多的精力. 但是,librtmp依赖于openssl和zlib,我们需要首先对其进行编译.

  1. 编译openssl1.0.0e

  a)下载并安装ActivePerl

  b)下载并安装nasm()

  c)解压缩openssl压缩包

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

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

  e)运行Visual Studio命令提示符(2010),切换到openssl目录,并分别执行以下命令.

  >nmake -f ms\nt.mak<br />>nmake -f ms\nt.mak install

  f)编译完成后,您可以在第一个命令指定的目录中找到已编译的SDK.

  2. 编译zlib

  a)解压缩zlib压缩包

  b)运行Visual Studio命令提示符(2010),剪切到openssl目录,并分别执行以下命令

  >cd contrib\masmx86<br />>bld_ml32.bat

  c)返回zlib目录,输入contrib \ vstudio \ vc10目录,然后打开vs2010解决方案文件,

  在zlibstat的项目属性中,删除预编译的宏ZLIB_WINAPI

  d)选择调试或发布进行编译.

  3. 编译librtmp

  a)首先打开Visual Studio 2010,创建一个新的win32控制台项目,并将其指定为静态链接库

  b)将librtmp代码导入到项目中,将openssl,zlib头文件和librtmp放在一起,并将已编译的openssl和zlib静态库放在一起

  

  

  c)在项目设置中,添加先前编译的openssl和zlib库并进行编译.

  

  二,使用librtmp

  首先初始化RTMP结构

  

  启动后,有必要向RTMP服务器发起握手连接消息

  

  如果连接成功,则可以开始循环发送消息. 在这里,您需要指定时间戳和数据类型(音频,视频,元数据). 这里要注意的一件事是,在调用Send之前,buf中的数据必须是封装的H264或AAC数据流.

  

  关闭

  

  最后一个是发布

  

  H264和AAC数据流

  如本文所述,RTMP推送的音频和视频流的封装形式类似于FLV格式. 可以看出,要将H264和AAC实时流推送到FMS,您需要首先发送“ AVC序列头”和“ AAC序列头”. 这两个数据收录重要的编码信息,没有它们,*敏*感*词*将无法解码.

  AVC序列标头是AVCDecoderConfigurationRecord结构,在标准文档“ ISO-14496-15 AVC文件格式”中对其进行了详细说明.

  

  AAC序列标头存储AudioSpecificConfig结构,该结构在“ ISO-14496-3音频”中进行了描述. AudioSpecificConfig结构的描述非常复杂. 在这里我将简化它. 设置要预先编码的音频格式. 其中,选择“ AAC-LC”作为音频编码,音频采样率为44100,因此AudioSpecificConfig简化为下表:

  

  通过这种方式,可以基本确定AVC序列头和AAC序列头的内容. 有关更多详细信息,您可以转到相关文档.

  操作效果

  RtmpLiveEncoder开始运行

  

  使用FMS随附的Flash播放器

  

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

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线