liyuanhong

参考地址:

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 的有效图像数据)构成。

 

分类:

技术点:

相关文章: