FLV文件格式分析

参考地址:

https://zhuanlan.zhihu.com/p/83346973

https://www.cnblogs.com/leisure_chn/p/10662941.html

https://blog.csdn.net/abe_liu/article/details/107445565     (video解析)

https://www.cnblogs.com/chgaowei/p/5445597.html   (FLV文件格式官方规范详解)

前言

flv 是 flash video 的缩写,是 Adobe Flash payler 支持的一种流媒体播放格式。flv 是一种层级格式,除了一个 flv header 外,剩下全是由 一个个 tag 组成。tag 是由 tag 头和 tag 数据组成。tag 类型分为音频、视频、脚本,一共三种类型。每一种数据类型又有自己的 tag 头。

FLV 文件头格式

FLV 文件有 9 个字节的文件头,文件以 3 字节签名 0x46、0x4C、0x 56 开始,分别是 ‘F’、’L’、’V’ 三个字母的 ascii 编码。版本号是 1。文件头中还有 flag 标记,表面是否有音频、视频 tag。

字段类型说明
Signature UI8 'F' (0x46)
Signature UI8 'L' (0x4C)
Signature UI8 'V' (0x56)
Version UI8

类型标识。 前5个bit是类型标志预留字段,必须是0; 第6个bit音频类型标志(TypeFlagsAudio); 第7个bit是类型标志预留字段,必须是0; 第8个bit视频类型标志(TypeFlagsVideo)。(0x05,也就是 00000101,表示既有音频也有视频。0x01 只有视频)

FLV 版本。例如,0x01 表示 FLV 版本 1

TypeFlags UI8 b[0] 是否存在视频流
b[2] 是否存在音频流
其他字段保留,值为0
DataOffset UI32 FLV Header 长度(字节)

下来以音频、视频为例,分析一下 FLV 格式的 header、tag。

音频 tag 格式

如上图,除了 9 字节的公共文件头外,body 部分就是一个个 tag 组成的。每一个 tag 都有 15 字节的 tag 头。字段说明如下:

  • PreviousTagSize,是 4 字节长度,表面之前的 Tag 的长度,包含了 tag 头和 tag 数据。第一个 tag ,此值是 0。
  • TagType,是 1 字节长度。音频:8, 视频:9
  • DataSize , 是 3 字节长。flv tag 的数据长度,其实如图里 audio tag 头及其数据长度。
  • Timestamp,是 3 字节长。时间戳,貌似 flv 播放需要。
  • TimestampExtended, 是对 Timestamp 长度的扩展,当时间长度 3 字节不能表示的时候,启用扩展字段。
  • StreamID ,3 字节长,都填 0
字段字节数描述
TagType 1 0x12 : Scipt 0x09 :视频 0x08:音频
DataSize 3 数据长度
TimeStamp 3 相对于第一帧的时间戳,单位为毫秒,第一帧总为0
TimeStampExtender 1 时间戳的补充字段
StreamID 3 0

flv tag 的 body 部分其实就是音频的 tag 部分了,图中每一个字段都有简单说明。具体每一个参数都有很多取值,取值的详细说明参考 [1] 中标明的 flv 规范音频 tag 部分。

对于 AACPacketType = 0 的情况,音频数据是 AudioSpecificConfig 格式,此格式在 ISO/IEC 14496-3 2009 中第一,可惜下载不到此文档。

如果是 AACPacketType = 1 的情况,那么后续数据都是 AAC 格式了(data里面的数据不包含Acc 的头7个字节)。

音频数据

Field
type
Comment
音频格式
UB4
0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
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
 
7, 8, 14, and 15:内部保留使用。
flv是不支持g711a的,如果要用,可能要用线性音频。
采样率
UB2
For AAC: always 3   (AAC总是3)
0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz
采样大小
UB1
0 = snd8Bit
1 = snd16Bit
声道
UB1
0=单声道
1=立体声,双声道。AAC永远是1
声音数据
UI8[N]
如果是PCM线性数据,存储的时候每个16bit小端存储,有符号。
如果音频格式是AAC,则存储的数据是AAC AUDIO DATA,否则为线性数组。

视频 tag 格式

视频 tag 格式和音频格式 flv 文件头、flv tag 头都相同。

这里需要说明一下的是,当 flv 包含的是 h264 的时候,CodecID 值是 7。在 H264 视频流开始的第一个 NALU 数据,需要发送 SPS、PPS 类型的数据。此时,AVCPacketType 会填 0,SPS/PPS 是包含在 AVCDecoderConfigurationRecord 结构中。

视频Tag Data 是由 FrameType 和CodecID 以及VideoData 或者AVCVIDEOPACKET构成,AVCVIDEOPACKET只存在第一个video tag 中。

1、AVCVIDEOPACKET 解析

字段字节描述
AVCPACKETType 1 0:AVC sequence header 1:AVC NALU 2:AVC end of sequence
Composition Offset 3 合成时间。 AVCPacketType==1,表示 合成时间(单位毫秒); 否则为0
VideoData 2 如果AVCPacketType=0数据部分为AVCDecoderConfigurationRecord; 如果AVCPacketType=1,数据部分为1个或多个NALU; 如果AVCPacketType==2,数据部分为空

关键的AVCDecoderConfigurationRecord 数据构成

字段字节描述
版本 1 0x01版本号为1
编码规格 3 sps[1]+sps[2]+sps[3]
NALU 的长度 1 0xff
SPS个数 1 0xE1
SPS长度 2 整个sps长度
SPS的内容 n 整个sps
PPS个数 1 0x01
PPS长度 2 整个pps长度
PPS内容 n 整个pps内容

 

2、普通Video Data 解析

讲完第一个特殊的VideoData, 其他所有的VideoData 都是由AVPACKETTYPE + CompsitionTime offset + Data(去除startCode 的有效图像数据)构成。

 

posted @ 2020-12-27 16:34  远洪  阅读(1348)  评论(0)    收藏  举报