flv的组成
FLV是一个二进制文件,简单来说,其是由一个文件头(FLV header)和很多tag组成(FLV body)。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流,而每个tag又由tag header和tag data组成。
1 flv header
文件头由9bytes组成
前3个bytes是文件类型,总是“FLV”,也就是(0x46 0x4C 0x56)。第4btye是版本号,目前一般是0x01。第5byte是流的信息,倒数第一bit是1表示有视频(0x01),倒数第三bit是1表示有音频(0x4),有视频又有音频就是0x01 | 0x04(0x05),其他都应该是0。最后4bytes表示FLV 头的长度,3+1+1+4 = 9。
2 FLV body,FLV body由若干个tag 组成。
tag header:
FLV body由若干个tag 组成。每一个tag第一部分是tag header,tag header长度为11bytes,但是每个tag header前面有4bytes记录着上一个tag的长度,此待会儿再说。tag header的第1个byte为记录着tag的类型,音频(0x8),视频(0x9),脚本(0x12);第2到4bytes是数据区的长度,也就是tag data的长度;再后面3个bytes是时间戳,单位是毫秒,类型为0x12则时间戳为0,时间戳控制着文件播放的速度,可以根据音视频的帧率类设置;时间戳后面一个byte是扩展时间戳,时间戳不够长的时候用;最后3bytes是streamID,但是总为0,再后面就是数据区了(tag data),tag header 长度为1+3+3+1+3=11。
previoustagsize |
4bytes |
前一个tag的长度,第一个tag就是0 |
tag类型 |
1byte |
三类: 8 -- 音频tag 9 -- 视频tag 18 -- 脚本tag |
数据区长度 |
3bytes |
|
时间戳 |
3bytes |
单位毫秒,如果是脚本tag就是0 |
扩展时间戳 |
1byte |
作为时间戳的高位 |
streamsID |
3bytes |
总是0(不知道干啥用) |
数据区 |
|
|
0x12前面的00 00 00 00 就是刚刚说的记录着上一个tag的长度的4bytes,这里因为前面没有tag,所以为0。
之前说每个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 date:
如果tag data是脚本数据(0x12),Script Tag Data,该类型Tag又通常被称为Metadata(元数据) Tag,会放一些关于FLV视频和音频的参数信息,如duration、width、height等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。一般来说,该Tag Data结构包含两个AMF包。
接下来就是Metadata的具体数据,由两个AMF包组成。
Metadata元素个数暂定为12个 = 音频5个 + 视频5个 + 2个(duration和filesize)。 后面还可能会加入其它元素,因此会返回来修改此值。metadata元素的顺序不固定,此处采用ffmpeg中的顺序。
第二个AMF包中各数组元素封装形式为:前两个字节是元素名称的长度;后面跟着长度为L的字符串;第L+3个字节表示元素值的类型;后面跟着是对应值,占用的字节数取决于值的类型。
以下的(tag->key,tag->value)不一定在所有flv文件中出现,依据不同版本有所不同。
如果tag data是(0x08)音频
Audio tag 数据区
audio信息 |
1byte |
前四位bits表示音频格式: 0 -- 未压缩 1 -- ADPCM 2 -- MP3 5 -- Nellymoser 8kHz momo 6 -- Nellymoser 下面两位bits表示samplerate: 0 -- 5.5kHz 1 -- 11kHz 2 -- 22kHz 3 -- 44kHz 下面一位bit表示每个采样的长度: 0 -- snd8Bit 1 -- snd16Bit 下面一位bit表示类型: 0 -- sndMomo 1 -- sndStereo |
audio数据区 |
不定 |
|
如果tag data是(0x09)视频
video信息 |
1byte |
前四位bits表示类型: 1 -- keyframe 2 -- inner frame 3 -- disposable inner frame (H.263 only) 4 -- generated keyframe 后四位bits表示编码器id: 2 -- Seronson H.263 3 -- Screen video 4 -- On2 VP6 5 -- On2 VP6 without channel 6 -- Screen video version 2 7 -- AVC (h.264) |
video数据区 |
不定 |
|
到此为止已经介绍完flv文件格式,flv格式还是比较简单的,header部分很简洁,body部分都是由一个个tag组成,tag的话也就三种,脚本tag一般只有一个。最后用一个简单的图来概括flv文件格式,以结束本文档。
其他:
flv解析代码
https://blog.csdn.net/leixiaohua1020/article/details/50535082