C++实现RTMP协议发送H.264编码及AAC编码的音视频(转)
C++实现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的主要思路和关键点,以期对需要这方面技术的朋友有所帮助。
技术分析
要实现RTMPLiveEncoder,需要以下四种关键技术:
- 采集摄像头视频和麦克风音频
- H264编码和AAC编码
- 视频和音频数据封装为可被流媒体服务器识别的可播放流
- RTMP协议实现报文发送
其中,前两项技术在我之前的文章“采集音频和摄像头视频并实时H264编码和AAC编码”中已经介绍过了,这里就不再啰嗦了。
把音视频数据封装为可播放流,这个是一个难点。仔细研究一下,你会发现,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,然后发出去。
线程之间的数据交换,通过一个队列DataBufferQueue来实现。AudioEncoderThread和 VideoEncoderThread把数据指针post到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(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的内容可以基本确定了,更详细的信息,大家可以去翻阅相关文档。
运行效果
RtmpLiveEncoder开始运行

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

C++实现RTMP协议发送H.264编码及AAC编码的音视频(转)的更多相关文章
- C++实现RTMP协议发送H.264编码及AAC编码的音视频
		http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RTMP ... 
- (转)C++实现RTMP协议发送H.264编码及AAC编码的音视频,摄像头直播
		转:http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RT ... 
- 【转】C++实现RTMP协议发送H.264编码及AAC编码的音视频
		RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ... 
- RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播
		RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ... 
- C++实现RTMP协议发送H.264编码及AAC编码的直播软件开发音视频
		RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ... 
- 【转】实现RTP协议的H.264视频传输系统
		1. 引言 随着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性.但人们又面临着另外一种不可避免的尴尬,就是在网络上看到生动 ... 
- 基于RTP协议的H.264传输
		1. 引言 随 着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性.但人们又面临着另外一种不可避免 的尴尬,就是在网络上看 ... 
- MPEG-4与H.264的区别 , 编码 以及 应用
		MPEG4是适用于监控领域的压缩技术 MPEG4于1998年11月公布,原预计1999 年1月投入使用的国际标准MPEG4不仅是针对一定比特率下的视频.音频编码,更加注重多媒体系统的交互性和灵活性.M ... 
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法。。
		[原创] RFC3984是H.264的baseline码流在RTP方式下传输的规范,这里只讨论FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法. 1.单个NAL包单元 12字节 ... 
随机推荐
- 彻底理解PHP的SESSION机制
			http://www.cnblogs.com/acpp/archive/2011/06/10/2077592.html 一.默认机制,用磁盘文件来实现PHP会话.php.ini配置:session.s ... 
- Web前端开发如何利用css样式来控制Html中的h1/h2/h3标签不换行
			H1/H2/H3/H4标题标签常常使用在一个网页中唯一标题.重要栏目.重要标题等情形下. H1在一个网页中最好只使用一次,如对一个网页唯一标题使用.H2.H3.H4标签则可以在一个网页中多次出现, ... 
- 命令精解之DOS批处理
			前言 最近对于批处理技术的探讨比较热,也有不少好的批处理程序发布,但是如果没有一定的相关知识恐怕不容易看懂和理解这些批处理文件,也就更谈不上自己动手编写了,古语云:“授人以鱼,不如授人以渔.”因为网上 ... 
- 基于C#的IBM消息队列操作客户端
			背景: 做XX项目需要把交易的消息推送给YY系统,技术选型MQ 另:选用MQ原因是为了防止YY系统宕机,无法接受收消息 实现 1.安装IBM WebSphere MQ客户端 2.引用amqmdnet. ... 
- Linux常用(持续更新)
			1. scp ./bcec_computernode_check.sh root@10.254.3.1:/tmp 2. # uname -a # cat /proc/version # cat /e ... 
- Codevs 1690 开关灯  USACO
			1690 开关灯 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description YYX家门前的街上有N(2<=N& ... 
- Python之实现一个简易计算器
			自己动手写计算器 一.功能分析 用户输入一个类似这样 3*( 4+ 50 )-(( 100 + 40 )*5/2- 3*2* 2/4+9)*((( 3 + 4)-4)-4) 这样的表达式,假设表达式里 ... 
- 深入理解Python中的生成器
			生成器(generator)概念 生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束. 生成器语法 生成器表达式: 通列表解 ... 
- shell通过ftp实现上传/下载文件
			直接代码,shell文件名为testFtptool.sh: #!/bin/bash ########################################################## ... 
- php学习,一个简单的Calendar(1)
			材料取之深入PHP与JQuery开发,这本书实际上就是讲述一个活动日程表. 此文章适合从其它语言(如java,C++,python等)转到php,没有系统学习php,或者是php初学者,已经对程序有较 ... 
