上一篇介绍了MP4文件格式,这一篇来学习一下FLV的封装格式。
FLV格式是Adobe公司开发的,该格式的文件由于结构简单,数据片之间包含前后联系,因此特别适合流媒体传输。
0x01 FLV文件结构
FLV文件是由于FLV文件头和FLV文件体组成,FLV文件体由若干级联的FLV标签组成,每个FLV标签都先传递一个PreviousTagSize来保存前一个FLV标签的大小。视频头信息、音频流数据、视频流数据都封装在不同类型的FLV标签中,并且在同一个FLV文件中保存或传输。
0x02 FLV文件头
FLV文件头前三个字节保存了F、L、V的ASCII码。第四个字节表示FLV的版本。第五个字节中的第8位表示是否存在视频tag,第6位表示是否存在音频tag。
0x03 FLV标签
1.tag头部信息
FLV标签是由FLV标签头部信息(FLV Tag Header)和FLV标签载荷数据(FLV Tag Playload)组成。其中,FLV标签包含当前标签的类型、大小、时间戳等信息,FLV标签载荷数据保存了一个完整的音频、视频、或参数数据类型的标签。主要包含脚本标签,音频标签、视频标签。
| 1byte | reserved 2bit 保留位 |
|---|---|
| filter 1bit 预处理标识 0 :无预处理 1:需要加密等预处理 | |
| tagType 5bit 8表示音频 9表示视频 18表示参数数据 | |
| 3byte | data size 表示载荷数据大小 |
| 3byte | timeStamp 当前标签的时间戳 |
| 1byte | 时间戳扩展,可作为高位字节与timestamp构成一个32为有符号整型值 |
| 3byte | streamID 始终为0 |
2.脚本标签 Script Tag
当tagType是18时表示保存了一个脚本标签。脚本标签以不同类型的键值对保存了若干媒体文件的参数数据。scriptTagBody实际上是一个十分复杂的键值对结构,key和name都可以用通用数据类型ScriptDataValue来表示。**
**
| 字段 | 类型 | 含义 |
|---|---|---|
| Name | Script Data Value(String) | 参数名称 |
| Value | Script Data Value(ECMA Array) | 参数值 |
Script Data Value
script Data Value 可以包含12种数据类型。他是由两部分组成,Type和Data,Type表示数据的类型,Data保存实际的数据。
| 类型索引 | 类型 |
|---|---|
| 0 | 双精度浮点 |
| 1 | 布尔值 |
| 2 | 字符串 |
| 3 | 对象结构 |
| 7 | 16位无符号整数 |
| 8 | ECMA数组 |
| 10 | 有序数组 |
| 11 | 日期 |
| 12 | 长数组 |
字符串
字符串包换两部分,StringLength 和StringData。
| 字段 | 类型 | 含义 |
|---|---|---|
| StringLength | uI16 | 长度 |
| StringData | 字符串 | 数据 |
对象类型
对象结构用于保存若干匿名的属性。一个对象结构主要包含两部分,ObjectProperties 和 List Teminator。List Teminator包含固定的3 Byte,分别是0、0、9。
| 字段 | 类型 | 含义 |
|---|---|---|
| ObjectProperties | ScriptDataObjectProperty[] | 对象的属性列表 |
| List Teminator | ScriptDataObjectEnd | 属性列表终止符 |
ObjectProperties是一种复合类型,用来保存某种属性的键值对。由PropertyName和PropertyData组成。
| 字段 | 类型 | 含义 |
|---|---|---|
| PropertyName | ScriptDataString | 属性名称 |
| PropertyData | ScriptDataValue | 属性值 |
ECMA数组类型
ECMA数组保存了ECMA格式的数组。每个ECMA数组保存了若干个对象的属性。
| 字段 | 类型 | 含义 |
|---|---|---|
| ECMAArrayLength | UI32 | 数组长度 |
| Variable | ScriptDataObjectProperty[] | 变量的键值对 |
| List Teminator | ScriptDataObjectEnd | 属性列表终止符 |
onMetaData结构
在一个典型的FLV文件中,第一个Tag结构通常为一个Script Tag,其中包含一个onMetaData结构。onMetaData结构在整个文件的封装中起到记录媒体数据的基本信息的作用。
| 字段 | 类型 | 含义 |
|---|---|---|
| audiocodecid | Number | 音频解码器索引 |
| audiodatarate | Number | 音频流比特率 |
| audiodelay | Number | 音频流解码器延迟 |
| audiosamplerate | Number | 音频采样率 |
| audiosamplesize | Number | 音频包大小 |
| canseektoend | Boolean | 能否寻找到结尾 即最后一个视频帧是否为关键帧 |
| creationdate | String | 创建时间 |
| duration | Number | 媒体总时长 |
| filesize | Number | 媒体文件大小 |
| framerate | Number | 视频帧率 |
| height | Number | 视频高度 |
| stereo | Boolean | 音频流是否是立体声 |
| videocodecid | Number | 视频刘解码器索引 |
| videodatarate | Number | 视频流比特率 |
| width | Number | 视频帧宽度 |
0x03.视频标签 Flv video Tag*
当tagType是9时表示保存了一个视频标签。视频标签由视频标签头和视频标签体组成,视频标签头中保存了视频流相关的MetaData数据。通过视频标签头中的时间戳和compositonTime,可以确定当前视频帧显示的时间戳。
| 字段 | 类型 | 含义 |
|---|---|---|
| FrameType | UB[4] | 当前标签中保存的视频帧帧的类型 |
| CodecID | UB[4] | 视频流编码格式索引 |
| AVCPacketType | UI8 | 当前视频包数据的类型 |
| CompositionTime | SI24 | 当前视频包的显示时间戳偏移量 |
帧类型FrameType
| 帧类型值 | 含义 |
|---|---|
| 1 | H.264/AVC的关键帧,可作为随机接入点 |
| 2 | H.264/AVC的非关键帧 |
| 3 | 可丢弃的非关键帧(仅用于H。263) |
| 4 | 后生成的关键帧 保留 通常不用 |
| 5 | 视频信息或命令帧 |
编码格式索引CodecID
视频解码器根据索引来进行解码
| 索引 | 编码标准 |
|---|---|
| 2 | sorenson H.263 |
| 3 | screen video |
| 4 | on2 vp6 |
| 5 | 带alpha通道的on2 vp6 |
| 6 | screen video version 2 |
| 7 | h.264/avc |
包类型AVPacketType
| 索引 | 含义 |
|---|---|
| 1 | AVC编码视频头结构,包括SPS、PPS和附加信息 |
| 2 | AVC NALU数据包 |
| 3 | 表示码流结构 |
由此可以确定视频标签体的不同格式的视频码流包。如果codecID为7,FLV标签中保存的为H.264格式的视频码流包。
0x04.音频标签 Flv audio Tag
当tagType是8时表示保存了一个音频标签。音频标签由音频标签头和音频标签体组成。
音频标签头
| 字段 | 类型 | 含义 |
|---|---|---|
| SoundFormat | UB[4] | 音频编码格式 |
| SoundRate | UB[2] | 音频采样频率 |
| SoundSize | UB[1] | 每个音频采样点的数据大小 |
| SoundType | UB[1] | 音频类型,0表示单声道,1表示立体声 |
| AACPacketType | UI18 | AAV数据包类型 |
音频编码格式SoundFormat
| 索引 | 含义 |
|---|---|
| 2 | MP3 |
| 10 | AAC |
| 11 | speex |
音频采样率soundRate
| 索引 | 含义 |
|---|---|
| 0 | 采样频率5.5kHz |
| 1 | 采样频率11kHz |
| 2 | 采样频率22kHz |
| 3 | 采样频率44kHz |
采样点数据大小soundSize
| 索引 | 含义 |
|---|---|
| 0 | 每个采样点占8bit |
| 1 | 每个采样点占10bit |
数据类型AACPacketType
| 索引 | 含义 |
|---|---|
| 0 | 表示AAC数据头 |
| 1 | 表示AAC数据包 |
0x05.End
看到这里,flv文件格式基本就了解的差不多了。后面计划介绍一下iOS平台音视频开发相关的类库AVFoundation以及实战文章。后续还会更新FFmpeg以及opengles的文章,关注我不迷路。