详细说明flv文件构造--基于《将h.264视频流封装成flv格式文件(一.flv格式)》

11 篇文章 0 订阅

引用了一些原文的内容,但是觉得原文中一些配图不够细心,很多图与内容不匹配,因此在原著的基础上加上了自己理解的一些东西,重新配图,对新手来说,看起来的时候应该比较直观了吧。

其实flv还是挺简单的一个视频格式,下面就来先谈一谈FLV的格式吧。

 

FLV是一个二进制文件,简单来说,其是由一个文件头(FLV header)和很多tag组成(FLV body)。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流,而每个tag又由tag header和tag data组成。

文件头由9bytes组成

 

前3个bytes是文件类型,总是“FLV”,也就是(0x46 0x4C 0x56)。第4btye是版本号,目前一般是0x01。第5byte是流的信息,倒数第一bit是1表示有视频(0x01),倒数第三bit是1表示有音频(0x4)(这部分倒数第几位第几位,指的是以二进制计算的含义,比如这里第五位的0x05,相当于二进制的00000101,也就是倒数1bit和倒数3bit),有视频又有音频就是0x01 | 0x04(0x05),其他都应该是0。最后4bytes表示FLV 头的长度,3+1+1+4 = 9

 

FLV header后面就是FLV body,FLV body由若干个tag 组成。每一个tag第一部分是tag header,tag header长度为11bytes,但是每个tag header前面有4bytes记录着上一个tag的长度,此待会儿再说。(见下图)

tag header的第1个byte为记录着tag的类型,音频(0x8),视频(0x9),脚本(0x12)(新版规范是0x18)第2到4bytes是数据区的长度,也就是tag data的长度(就是从上图的蓝底部分后面第一个02开始到整个metadata部分结束的总长度,);再后面3个bytes是时间戳,单位是毫秒,类型为0x12则时间戳为0,时间戳控制着文件播放的速度,可以根据音视频的帧率类设置;时间戳后面一个byte是扩展时间戳,时间戳不够长的时候用;最后3bytes是streamID,但是总为0,再后面就是数据区了(tag data),也即是h264的裸流,tag header 长度为1+3+3+1+3=11。(对于上图的说明,因为上图中,被蓝颜色选中的长度一共是4+11=15(这标兰的15位的flv file body,在下面还会提到),所以容易误导,其实我们只需要关注上图被选中的蓝色背景部分的从12开头的11位长度的数据即可),而前4位数据,也就是0x12前面的00 00 00 00 就是刚刚说的记录着上一个tag的长度的4bytes,这里因为前面没有tag,所以为0。

发现,pre tag size中的数据长度与video tag或者audio tag中的记录数据长度的内容是相互呼应的,比如下图中,第一个红框里面的30,说明绿底部分内容的数据长度是48,这个48是怎么来的呢?还看绿底这部分内容,除了绿圈17前面的11个长度之外的长度,就是48,然后我们再看紧接着绿底部分内容的那4个byte代表的pre tag size的部分,这部分内容是0x00 00 00 3B,0x3B代表十六进制的59,这个59正是前面所有绿底部分内容的总长度,也就是前面的tag head的11+tag body的48,哈哈,明白了吧。

 

上图是我选了一个比较简单的一帧video tag,让我们看一下上图。两个红框部分不用解释了,分别是数据长度和时间戳,因为这个是第一帧,所以时间戳都是0属于正常,否则就是不正常,相同的时间戳只能看到最后一帧的内容,其他的就被覆盖掉了。红圈是时间戳扩展,两个蓝方框中的内容,我们只需要关注绿色背景的部分,绿色背景部分的数据长一共是48,换算成16进制表示,就是0x30,也就是上图中第一个红框中的0x00 00 30的来源了。

tag data如果是音频数据,第一个byte记录audio信息:

前4bits表示音频格式(已补齐官方文档上全部内容):

·0 -- 未压缩

·1 -- ADPCM

·2 -- MP3

·4 -- Nellymoser 16-kHz mono

·5 -- Nellymoser 8-kHz mono

·6 = Nellymoser

·7 = G.711 A-law logarithmic PCM

·8 = G.711 mu-law logarithmic PCM

·9 = reserved

·10 = AAC

·11 = Speex

·14 = MP3 8-Khz

·15 = Device-specific sound


下面两个bits表示samplerate:

·0 -- 5.5KHz

·1 -- 11kHz

·2 -- 22kHz

·3 -- 44kHz

下面1bit表示采样长度:

·0 -- snd8Bit

·1 -- snd16Bit

下面1bit表示类型:

·0 -- sndMomo

·1 -- sndStereo

之后是数据。

如果是视频数据,第一个byte记录video信息:

前4bits表示类型:

·1 -- keyframe

·2 -- inner frame

·3 -- disposable inner frame (h.263 only)

·4 -- generated keyframe

后4bits表示解码器ID:

·1 -- JPEG (currently unused)

·2 -- seronson h.263

·3 -- screen video

·4 -- On2 VP6

·5 -- On2 VP6 with alpha channel

·6 -- Screen video version 2

·7 -- AVC (h.264)

之后是数据。

 对于上图的橘红圈17,特别说明一下,这个是前4bit中的“1”和后4bit中的“7”的集合体,如上所说,tag head的第一位是09,说明是个视频,所以第12位的17就需要按照视频的规则来翻译,根据上面说的,前4位是类型,1代表“keyframe(关键帧)”,7代表“AVC (h.264)”(解码器ID)。

那么再来个例子,如下图


使用ffplay播放的时候,可以看到video是vp6类型,对应图上的第十二位的14中的4可知,这个4代表解码器id中的On2 VP6

 

如果是AAC和AVC的音视频,则在放入数据前有一个音频和视频的配置信息需要写入前两个tag,等会再说。之前说每个tag前面会有一个记录上个tag长度的4个bytes(previous tag size),整个的flv文件其实是:FLV header + previous tag size0 + tag1 + previous tag size1 + tag2 + previous tag size2 + ... +tagN + previous tag sizeN。第一个previous tag size因为前面没有tag,所以为0,其他的总是记录着前面一个tag 长度(tag data size + tag header size)(换言之,现有tag data具体内容,后有pre tag size说明)

 

 

如果tag data是脚本数据,Script Tag Data,该类型Tag又通常被称为Metadata(元数据) Tag,会放一些关于FLV视频和音频的参数信息,如duration、width、height等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。一般来说,该Tag Data结构包含两个AMF包。AMF(Action Message Format)是Adobe设计的一种通用数据封装格式,在Adobe的很多产品中应用,简单来说,AMF将不同类型的数据用统一的格式来描述。第一个 AMF包封装字符串类型数据,用来装入一个“onMetaData”标志,这个标志与Adobe的一些API调用有,在此不细述。第二个AMF包封装一个数组类型,这个数组中包含了音视频信息项的名称和值。具体说明如下,大家可以参照图片上的数据进行理解

第一个AMF包:

 第1个字节表示AMF包类型,一般总是0x02(这个02的来源见下图),表示字符串,其他值表示意义请查阅文档。

  第2-3个字节为UI16类型值,表示字符串的长度,一般总是0x000A(“onMetaData”长度)。

  后面字节为字符串数据,一般总为“onMetaData”。


(图中内容是由ue打开,我们只需关注绿色背景部分,第一个红框中的

0x02,就是metadata的起始标志,其实我们只需要稍微仔细关注一下0x02前面的内容, 就很方便看出,0x46 4c 56到0x09这9位,就是flv的 header部分,后面的15位,就是我们前面说的那flv的file body部分)。而由0x6F 6E开头到0x61结尾的这些没有被红框选中的绿色背景部分,就是翻译后的onMeteData内容。

第二个AMF包:

 第1个字节表示AMF包类型,一般总是0x08,表示数组。

 第2-5个字节为UI32类型值,表示数组元素的个数。

 后面即为各数组元素的封装,数组元素为元素名称和值组成的对。表示方法如下:

   第1-2个字节表示元素名称的长度,假设为L。

   后面跟着为长度为L的字符串。

   第L+3个字节表示元素值的类型。

  后面跟着为对应值,占用字节数取决于值的类型

 结尾的标记使用ue打开来看的话,可能可能不好找,可以协同使用flvParse来一起看,比如下面两图

当前图片需要与下图结合来看


上图中的红框圈起来的就是pre tag size0的内容了。


推荐一下原文地址和原文中的一个链接,还是不错的

http://blog.csdn.net/yeyumin89/article/details/7932368

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

感谢你看到了这里, 依然推荐一个flv的查看工具 flvParse,全国各大csdn有下载,欢迎百度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值