前文我们说到如何在基于 libRTMP 库的流媒体直播过程中推送 AAC 、H264 音视频流。本文以上文为基础,阐释如何对 RTMP 包进行解析、重组得到原始的 AAC 音频帧以及 H264 码流。

在继续阅读本文之前,我们首先假设读者已经能够使用 libRTMP 库从 RTMP 直播服务器不断地获取 RTMP 包,如前提不成立,请自行阅读 [抛开flash,自己开发实现C++ RTMP直播流播放器] 一文,实现一个简单的 RtmpDownloader 测试用例。这一部分恕 Bill 不再赘述。

废话颇多,下面让我们一起来看看如何对 RTMP 包进行解析和重组。

根据前文所述,我们在推送音、视频包之前,会首先向服务器推送一个音、视频同步包,该包包含了 AAC 音频帧以及 H264 码流的解码信息。因此当我们首次向服务器请求 RTMP 包之后,服务器会下发给我们对应的音、视频同步包,这将决定我们如何解析并重组音、视频。

RTMP 音频包的解析及 AAC 重组

当我们得到服务器下发的第一个音频包(音频同步包)之后,即可按照前文所述的封包顺序进行逆操作,解析得到我们所需要的 AAC 音频信息,根据这些信息,我们便可重组在推送时被我们去掉的那 7 个(或 9 个)字节:ADTS(Audio Data Transport Stream),请参见维基百科 [ADTS]。一旦 ADTS 构造完毕,直接在其后添加原始 AAC 音频数据即完成了整个 AAC 音频帧的重组。

根据 ADTS 属性的描述,我们不难抽象出一个反映该信息的结构体如下:

接着让我们回顾一下前文提到的音频同步包的结构:

我们只需要从服务器获得的音频同步包中获取 AACDecoderSpecificInfo 以及 AudioSpecificConfig 这 4 个字节,并将其中的内容解析到 RtmpLiveAudioMetadataTy 这个结构中以备使用。示例代码如下:

在获得了 AAC 音频所必要的信息之后,我们便可构造 ADTS 并重组 RTMP 服务器下发来的后续音频包。构造 ADTS 示例代码如下:

至此,ADTS 7个字节便重构完毕,我们只需要在这 7 个字节后面添加上 AAC 的原始数据便可重组一个 AAC 音频帧。针对之后的每一个 RTMP 音频包,都进行上述步骤,不断将重组后的 AAC 音频帧写入文件,使用支持的播放器播放以验证解析正确与否。

RTMP 视频包的解析及 H.264 重组

与重组音频帧类似的,我们首先会从服务器获得视频同步包,首先对视频同步包进行拆包解析,得到本次 H264 码流的 Sps 以及 Pps,并从 Sps 中获取视频的宽高信息以备使用。根据前文提到的视频同步包封包流程,我们进行逆向解析的示例如下:

其中从 Sps 获取视频的宽高信息请读者自行 Google,Bill 不再赘述。解析完视频同步包,我们只需要对接下来的视频包进行分类即可,针对 H264 P 帧,我们直接将原始数据写入文件,针对 I 帧,我们在其前面添加保存好的 Sps 以及 Pps,然后写入原始数据即可。针对之后从 RTMP 服务器接收的每一个视频包,均进行上述重组操作,并将获得的 H264 编码写入文件,使用 Elecard StreamEye Tools 播放即可。

参考博文

[1][抛开flash,自己开发实现C++ RTMP直播流播放器]

[2][使用 libRtmp 进行 H264 与 AAC 直播]

[3][RTMP直播到FMS中的AAC音频直播]

【基于libRTMP的流媒体直播之 AAC、H264 解析】的更多相关文章

  1. (转)基于libRTMP的流媒体直播之 AAC、H264 推送

    参考: 1,基于libRTMP的流媒体直播之 AAC.H264 推送 http://billhoo.blog.51cto.com/2337751/1557646

  2. 基于libRTMP的流媒体直播之 AAC、H264 推送

    这段时间在捣腾基于 RTMP 协议的流媒体直播框架,其间参考了众多博主的文章,剩下一些细节问题自行琢磨也算摸索出个门道,现将自己认为比较恼人的 AAC 音频帧的推送和解析.H264 码流的推送和解析以 ...

  3. 【基于libRTMP的流媒体直播之 AAC、H264 推送】

    这段时间在捣腾基于 RTMP 协议的流媒体直播框架,其间参考了众多博主的文章,剩下一些细节问题自行琢磨也算摸索出个门道,现将自己认为比较恼人的 AAC 音频帧的推送和解析.H264 码流的推送和解析以 ...

  4. 最简单的基于librtmp的示例:发布(FLV通过RTMP发布)

    ===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...

  5. 基于Darwin实现的分布式流媒体直播服务器系统

    各位EasyDarwin开源项目的爱好者,您好,这篇博客的年限有点老了,目前EasyDarwin已经采用全新的云平台架构,详细可以参考博客:http://blog.csdn.net/xiejiashu ...

  6. day122:MoFang:OSSRS流媒体直播服务器&基于APICloud的acLive直播推流模块实现RTMP直播推流

    目录 1.docker安装OSSRS流媒体直播服务器 2.基于APICloud的acLive直播推流模块实现RTMP直播推流 3.直播流管理 1.docker安装OSSRS流媒体直播服务器 1.OSS ...

  7. 最简单的基于Flash的流媒体示例:RTMP推送和接收(ActionScript)

    ===================================================== Flash流媒体文章列表: 最简单的基于Flash的流媒体示例:RTMP推送和接收(Acti ...

  8. 最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)

    ===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...

  9. 最简单的基于librtmp的示例:接收(RTMP保存为FLV)

    ===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...

随机推荐

  1. Windows的Java_HOME环境变更配置

    Windows的Java_HOME环境变更配置 一般会配置三个环境变更: 1.系统变量 变量名JAVA_HOME  变量值=安装目录,如:C:\Program Files (x86)\Java\jdk ...

  2. SpringBoot配置Bean的两种方式--注解以及配置文件

    一.注解方式 编写实体类: package com.example.bean; import org.springframework.boot.context.properties.Configura ...

  3. Java多线程干货系列—(四)volatile关键字

    原文地址:http://tengj.top/2016/05/06/threadvolatile4/ <h1 id="前言"><a href="#前言&q ...

  4. django学习之- 数据缓存

    5种配置:开发调试 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎内存CA ...

  5. 实现浏览器兼容的innerText

    今天学习到了FF不支持innerText,而IE.chrome.Safari.opera均支持innerText. 为了各个浏览器能兼容innerText,必须对js做一次封装. 为啥能实现兼容呢?原 ...

  6. POJ 3281 [网络流dinic算法模板]

    题意: 农场主有f种食物,d种饮料,n头牛. 接下来的n行每行第一个数代表第i头牛喜欢吃的食物数量,和第i头牛喜欢喝的饮料数目. 接下来分别是喜欢的食物和饮料的编号. 求解:农场主最多能保证几头牛同时 ...

  7. BCD工具类(8421)

    目录 1.BCD介绍 (1)BCD码(Binary-Coded Decimal)亦称二进码十进数.用4位二进制数来表示1位十进制数中的0~9这10个数码.用二进制编码的十进制代码. (2)BCD码可分 ...

  8. 如何扩展ArcGIS中的元数据编辑器

    http://www.esrichina-bj.cn/old../library/arcnews16/Metadata.htm http://www.esrichina-bj.cn/old../lib ...

  9. MySQL 资源大全

    干货!MySQL 资源大全 提交 我的留言 加载中 已留言 shlomi-noach 发起维护的 MySQL 资源列表,内容覆盖:分析工具.备份.性能测试.配置.部署.GUI 等. 伯乐在线已在 Gi ...

  10. HDU 1017 A Mathematical Curiosity【看懂题意+穷举法】

    //2014.10.17    01:19 //题意: //先输入一个数N,然后分块输入,每块输入每次2个数,n,m,直到n,m同一时候为零时  //结束,当a和b满足题目要求时那么这对a和b就是一组 ...