文章实时采集(C++实现RTMP协议发送H.264编码及AAC编码的音视频RTMP )

优采云 发布时间: 2021-11-02 09:02

  文章实时采集(C++实现RTMP协议发送H.264编码及AAC编码的音视频RTMP

)

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

  RTMP(Real Time Messaging Protocol)是一种专门用于传输音视频数据的流媒体协议。它最初由Macromedia 创建,后来归它所有。它是一个私有协议,主要用于联系Flash Player和RtmpServer,如FMS、Red5、crtmpserver等。RTMP协议可以实现直播和点播应用,通过FMLE(Flash Media Live Encoder)将音视频数据推送到RtmpServer,可以实现摄像机的实时直播。但是,毕竟FMLE的应用范围是有限的。如果想嵌入到自己的程序中,还是要自己实现RTMP协议推送。我已经实现了一个 RTMPLiveEncoder,通过 采集 *敏*感*词*视频和麦克风音频,以及 H.264 和 AAC 编码,然后发送到FMS和crtmpserver实现实时直播,通过flash播放器可以正常观看,目前效果不错。延迟时间约为 2 秒。本文介绍了RTMPLiveEncoder的主要思想和关键点,希望对需要该技术的朋友有所帮助。

  技术分析

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

  其中,前两项技术在我之前的文章《采集音频和*敏*感*词*视频和实时H264编码和AAC编码》中已经介绍过,这里就不啰嗦了.

  将音频和视频数据封装到可播放的流中是一个难点。仔细研究,你会发现RTMP Packet中封装的音视频数据流其实和FLV封装音视频数据的方式是一样的。所以我们只需要根据FLV封装H264和AAC就可以生成Play流了。

  我们再来看看RTMP协议。Adobe 曾经发布过一个文档《RTMP 规范》,但维基百科指出该文档隐藏了很多细节,仅凭它是无法正确实现 RTMP 的。不过还是有参考意义的。事实上,在Adobe发布之前RTMP协议几乎就已经被破解了,现在已经有了比较完善的实现,比如RTMPDump,它提供了一个C语言的接口,这意味着它可以很容易地被其他语言调用。

  计划框架

  和我之前的文章《采集音视频与实时H264编码与AAC编码》文章一样,使用DirectShow技术实现音视频采集,音视频编码, 循环在各自的线程(AudioEncoderThread 和 VideoEncoderThread)中,RTMP的push开始一个新的线程(RtmpThread)。两个编码线程实时对音视频数据进行编码后,将数据交给Rtmp线程,Rtmp线程循环封装Rtmp Packet,然后发送出去。

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

  

  RtmpThread的主要工作是发送音频数据流的解码信息头和视频数据流的解码信息头,不断地从DataBufferQueue中取出数据,封装成RTMP Packet,发送出去。流程如下代码所示:(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

>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控制台项目,指定为静态链接库

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

  

  

  c) 在项目设置中,添加之前编译好的openssl和zlib库,然后编译。

  

  二、librtmp 的使用

  首先初始化RTMP结构

  

  启动后需要向RTMP Server发起握手连接消息

  

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

  

  关闭

  

  终于发布了

  

  H264 和 AAC 数据流

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

  AVC 序列头是 AVCDecoderConfigurationRecord 结构,在标准文档“ISO-14496-15 AVC 文件格式”中有详细描述。

  

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

  

  这样就可以基本确定AVC序列头和AAC序列头的内容了。更详细的信息,您可以查看相关文档。

  运行结果

  RtmpLiveEncoder 开始运行

  

  用 FMS 自带的 flash 播放器玩

  

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

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线