オーディオとビデオの開発 H.264 エンコードおよび AAC エンコードのオーディオとビデオを送信するための RTMP プロトコル (C++ 実装)

RTMP (Real Time Messaging Protocol) は、オーディオとビデオのデータを送信するために特別に使用されるストリーミング メディア プロトコルです. もともとは Macromedia によって作成され、後に Adob​​e によって所有されました. これは、主に Flash Player や RtmpServer などに接続するために使用されるプライベート プロトコルです。FMSRed5crtmpserverなど_ RTMP プロトコルを使用して、ライブ ブロードキャストおよびオンデマンド アプリケーションを実装し、オーディオおよびビデオ データをFMLE (Flash Media Live Encoder)を介して RtmpServer にプッシュし、カメラのリアルタイム ライブ ブロードキャストを実現できます。しかし、やはりFMLEの適用範囲は限られており、自分のプログラムに組み込みたい場合はRTMPプロトコルのプッシュを自分で実装する必要があります。カメラのビデオとマイクのオーディオをキャプチャし、H.264 と AAC でエンコードし、FMS と crtmpserver に送信して、フラッシュ プレーヤーで通常どおり視聴できるリアルタイムのライブ ブロードキャストを実現する RTMPLiveEncoder を実装しまし現時点では良好で、遅延時間は2 秒程度です。この記事では、RTMPLiveEncoder の主なアイデアとキー ポイントを紹介し、この技術を必要としている友人を助けたいと考えています。

テクニカル分析


RTMPLiveEncoderを実装するには、次の 4 つの主要なテクノロジが必要です。

  • カメラのビデオとマイクのオーディオをキャプチャする

  • H264エンコーディングとAACエンコーディング

  • ビデオとオーディオのデータは、ストリーミング メディア サーバーで認識できる再生可能なストリームにカプセル化されます。

  • メッセージ送信を実現するRTMPプロトコル

オーディオとビデオのデータを再生可能なストリームにカプセル化するのは難しいポイントです。よく調べてみると、RTMP パケットにカプセル化された音声と動画のデータ ストリームは、実際にはFLV が音声と動画のデータをカプセル化する方法と同じであることがわかります.したがって、FLV が H264 と AAC をカプセル化してストリームを再生します。

RTMP プロトコルをもう一度見てみましょう。Adobe はかつて「RTMP 仕様」というドキュメントを公開しましたが、wikipedia は、このドキュメントには多くの詳細が隠されていることを指摘しており、それだけでは RTMP を正しく実装することはできません。しかし、それはまだ有用です。実際、アドビがリリースする前は、RTMP プロトコルはほとんどクラックされていましたが、現在は次のような比較的完全な実装があります。 C 言語インターフェイスを提供するRTMPDump。これは、他の言語で簡単に呼び出すことができることを意味します。

プログラムの枠組み


DirectShow テクノロジーを使用して、オーディオとビデオの取得、オーディオのエンコード、ビデオのエンコードをそれぞれのスレッド (AudioEncoderThread と VideoEncoderThread) で循環的に実行し、RTMP プッシュ用に別のスレッド (RtmpThread) を起動します。2 つのエンコード スレッドがオーディオ データとビデオ データをリアルタイムでエンコードした後、データは Rtmp スレッドに渡され、Rtmp スレッドによって周期的に Rtmp パケットにカプセル化されてから送信されます。

スレッド間のデータ交換は、キュー DataBufferQueue を通じて実現されます。AudioEncoderThread と VideoEncoderThread がデータ ポインターを DataBufferQueue にポストした後、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(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的库,编译即可。

二、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的内容可以基本确定了,更详细的信息,大家可以去翻阅相关文档。

原文地址

FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发 学习

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

おすすめ

転載: blog.csdn.net/yinshipin007/article/details/129249040