这段时间,工作上的需要,在RTMP上做了flv流到标准h264、AAC的转换,服务器是开源项目CRTMPSERVER,客户端flex编写,视频编码h264,音频编码AAC,现将一些协议相关的东西记录如下。

一、分析FLV数据

我们先拿一个flv文件来简单分析一下flv数据的格式

flv标准文档下载地址http://www.cnblogs.com/chef/archive/2012/07/18/2597003.html

flv文件分析器flvprase下载地址http://www.cnblogs.com/chef/archive/2012/07/18/2596930.html

本文重点不在于此,这块就跳过了。相信大家对照flv标准文档都能看懂flv数据格式,而且我也强烈建议想学习这块知识的朋友先把这步的工作完成。

二、分析RTMP上行的h264视频流

在server上将上行视频存成二进制文件(注意,一定要用二进制形式保存数据)如下图(图片所显示的二进制数据每行有16列数据,即从0至f,如显示不完全,请单独打开图片查看)

我使用的工具是notepad++(并安装二进制查看插件)

如果你有做第一步的工作,不难看出rtmp中flv视频流就是一个接着一个的Video tag——即FLV tag中去除头信息, 只保留video tag内容。

我们对照flv标准文档来逐个分析

17:1-keyframe  7-avc

00:AVC sequence header -- AVC packet type

00 00 00:composition time,AVC时,全0,无意义

因为AVC packet type=AVC sequence header,接下来就是AVCDecoderConfigurationRecord的内容

configurationVersion = 01

AVCProfileIndication = 42

profile_compatibility = 00

AVCLevelIndication = 1f

lengthSizeMinusOne = ff -- FLV中NALU包长数据所使用的字节数,(lengthSizeMinusOne & 3)+1,实际测试时发现总为ff,计算结果为4,下文还会提到这个数据

numOfSequenceParameterSets = E1 -- SPS 的个数,numOfSequenceParameterSets & 0x1F,实际测试时发现总为E1,计算结果为1

sequenceParameterSetLength = 00 31 -- SPS 的长度,2个字节,计算结果49

sequenceParameterSetNALUnits = 67 42 80 1f 96 54 05 01 ed 80 a8 40 00 00 03 00 40 00 00 07 b8 00 00 20 00 00 03 01 00 01 fc 63 8c 00 00 10 00                     00 03 00 80 00 fe 31 c3 b4 24 4d 40 -- SPS,为刚才计算的49个字节, SPS中包含了视频长、宽的信息

numOfPictureParameterSets = 01 -- PPS 的个数,实际测试时发现总为E1,计算结果为1

pictureParameterSetLength = 00 04 -- PPS 的长度

pictureParameterSetNALUnits = 68 ce 35 20 -- PPS

接下来又是新的一包videotag数据了

17:1-keyframe  7-avc

01:AVC NALU

00 00 00:composition time,AVC时,全0,无意义

因为AVCPacket type = AVC NALU,接下来就是一个或多个NALU

每个NALU包前面都有(lengthSizeMinusOne & 3)+1个字节的NAL包长度描述(前文提到的,还记得吗),前面计算结果为4个字节

00 00 00 02 :2 -- NALU length

09 10:NAL包

这里插入一点NALU的小知识,每个NALU第一个字节的前5位标明的是该NAL包的类型,即NAL nal_unit_type

#define NALU_TYPE_SLICE 1
#define NALU_TYPE_DPA 2
#define NALU_TYPE_DPB 3
#define NALU_TYPE_DPC 4
#define NALU_TYPE_IDR 5
#define NALU_TYPE_SEI 6
#define NALU_TYPE_SPS 7
#define NALU_TYPE_PPS 8
#define NALU_TYPE_AUD 9  //访问分隔符
#define NALU_TYPE_EOSEQ 10
#define NALU_TYPE_EOSTREAM 11
#define NALU_TYPE_FILL 12

09&0x1f=9,访问单元分隔符

前面我们解析的sps头字节为67,67&0x1f = 7,pps头字节为68,68&0x1f=8,正好能对应上。

00 00 00 29:说明接下来的NAL包长度为41

06 00 11 80 00 af c8 00 00 03 00 00 03 00 00 af c8 00 00 03 00 00 40 01 0c 00 00 03 00 00 03 00 90 80 08 00 00 03 00 08 80:06&0x1f=6 -- SEI

00 00 3c d0:接下来的NAL包长度

65 88 80……:65&0x1f=5 -- I帧数据

这包video tag分析到此结束了,下面会紧接着来一些该I帧对应的P帧数据, 见下图

看00003d80那行,前面的内容一直到53 4f 7f都是上一个video tag的内容,即前面说的65 88 80那个I帧的数据拉,27开始是新的一个video tag

27:2-inter frame即P帧,7-codecid=AVC

01:AVCPacket type = AVC NALU

00 00 00:composition time,AVC时,全0,无意义

00 00 00 02 09 30:跟上面分析的一样拉,2个字节的nal包,访问单元分隔符

00 00 00 11:17字节的NAL包

06 01 0c 00 00 80 00 00 90 80 18 00 00 03 00 08 80:06&0x1f=6-SEI

00 00 46 85: NAL包数据长度

41 9a 02……: 41&0x1f=1,P帧数据

三、转换

大致总结下flv h264流,按顺序依次是

1、一个video tag,包含的信息:SPS,PPS,访问单元分隔符,SEI,I帧包

2、一个或多个video tag,包含的信息:访问单元分隔符,SEI,P帧包可为多个

循环1、2

这里需要说明下,做转换这一步时,我们只需要从videotag中获取到所有的、一个一个的NAL包就可以了,至于它是I帧、P帧及其他类型,实际上我们并不需要关心,这里只是为了更好的分析数据。

h264的NALU和NALU之间是由00 00 01(也可以是00 00 00 01)分隔开的,我们组成h264之后的格式为

1、00 00 00 01 SPS 00 00 00 01 PPS 00 00 00 01 访问单元分隔符 00 00 00 01 SEI 00 00 00 01 I帧 00 00 00 01 P帧 00 00 00 01 P帧……(P帧数量不定)

循环1

其中的访问单元分隔符和SEI不是必须的,将h264以二进制的形式写入文件,使用Elecard StreamEye就可以播放了,下载地址

http://www.cnblogs.com/chef/archive/2012/07/18/2597008.html

(转)RTMP中FLV流到标准h264、aac的转换的更多相关文章

  1. h264 封装 RTMP中FLV数据的解析 rtmp协议简单解析以及用其发送h264的flv文件

    一个完整的多媒体文件是由音频和视频2部分组成的.H264.Xvid等就是视频编码格式,MP3.AAC等就是音频编码格式.字幕文件只是其中附带部分. 把视频编码和音频编码打包成一个完整的多媒体文件,可以 ...

  2. rtmp直播拉流客户端EasyRTMPClient设计过程中时间戳问题汇总

    EasyRTMPClient 简介 EasyRTMPClient是EasyDarwin流媒体团队开发.提供的一套非常稳定.易用.支持重连接的RTMPClient工具,以SDK形式提供,接口调用非常简单 ...

  3. 视频技术详解:RTMP H5 直播流技术解析

    本文聚焦 RTMP 协议的最精华的内容,接进行实际操作 Buffer 的练习和协议的学习. RTMP 是什么 RTMP 全称即是 Real-Time Messaging Protocol.顾名思义就是 ...

  4. nginx+ffmpeg搭建rtmp转播rtsp流的flash服务器

    本文概要: nginx是非常优秀的开源服务器,用它来做hls或者rtmp流媒体服务器是非常不错的选择.本文介绍了一种简易方法快速搭建rtmp流媒体服务器,也叫rtsp转播,数据源不是读取文件,而是采用 ...

  5. 谈一谈Java8的函数式编程(二) --Java8中的流

    流与集合    众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...

  6. Java中IO流的总结

    有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...

  7. java-IO流-字节流-概述及分类、FileInputStream、FileOutputStream、available()方法、定义小数组、BufferedInputStream、BufferedOutputStream、flush和close方法的区别、流的标准处理异常代码

    1.IO流概述及其分类 * 1.概念      * IO流用来处理设备之间的数据传输      * Java对数据的操作是通过流的方式      * Java用于操作流的类都在IO包中      *  ...

  8. Java中IO流中的装饰设计模式(BufferReader的原理)

    本文粗略的介绍下JavaIO的整体框架,重在解释BufferReader/BufferWriter的演变过程和原理(对应的设计模式) 一.JavaIO的简介 流按操作数据分为两种:字节流与字符流. 流 ...

  9. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

随机推荐

  1. oracle相关命令收集-张

    orcle相关命令收集 1,用管理员登陆 /as sysdba:2, 更改用户密码 alter user name identified by password: alter user exptest ...

  2. python基础(9)--递归、二叉算法、多维数组、正则表达式

    1.递归 在函数内部,可以调其他函数,如果一个函数在内部调用它本身,这个函数就是递归函数.递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于裂解 递归算法解决问题的特点: 1)递归是 ...

  3. python基础(6)---set、collections介绍

    1.set(集合) set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key. 集合和我们数学中集合的概念是一样的,也有交集.并集.差集. ...

  4. [实战]MVC5+EF6+MySql企业网盘实战(10)——新建文件夹

    写在前面 上篇文章更新了编辑了文件名的操作,本片文章将实现新建文件夹的功能. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战 ...

  5. spring boot 使用不同的profile来加载不同的配置文件

    在开发过程之中,经常需要在开发和测试环境中进行互相切换,当切换的同时需要加载相应的配置文件,因此要经常 性的对配置文件进行相应的修改,长此以往感到十分痛苦.如果能针对开发和测试环境分别建两个不同的配置 ...

  6. 易普优APS 5.0高级计划排程系统助力工业4.0智能工厂建设

    (一)智能工厂建设核心 <中国制造2025>明确提出要推进制造过程智能化,智能工厂是实现智能制造的重要载体.作为智能工厂,在生产过程应实现自动化.透明化.可视化.精益化的同时,产品检测.质 ...

  7. 简单的oracle sql语句练习

    简单的oracle sql语句练习 求每个部门的平均薪水 select deptno,avg(sal) from emp group by deptno 每个部门同一个职位的最大工资 select d ...

  8. 【ASP.NET】编写自己的Web服务器

    自己写一个简单的Web服务器,对加深理解Http协议有很好的帮助,下面就看一下一个基于TcpListener的Web服务器: class Program { static void Main(stri ...

  9. ZOJ 3954 Seven-Segment Display

    二分图匹配. 先检查每个数字$1$的个数是否满足条件,不满足直接就是无解.剩下的情况可以建立二分图,如果现在的某一列可以对应于原图的某一列,那么建边.如果二分图的最大匹配是$7$,则有解,否则误解. ...

  10. Wordpress,你好!

    [caption id="" align="alignleft" width="1024"] 耳机[/caption] 想了想,还是没有删掉 ...