1. flv
1.1. 简介
- 一个 flv 文件,每种类型的tag都属于一个流(或者属于音频,或者属于视频,或者属于信息)
- 一个 flv 文件最多只有一个音频流,一个视频流,不存在多个独立的音视频流在一个文件的情况。(mp4是支持多个音频和视频)
- flv 文件格式使用的是大端序。
1.2. 结构
- 注:下面的数据 type 中
- UI 表示无符号整形,后面跟的数字表示其长度是多少位。比如 UI8,表示无符号整形,长度一个字节。
- UI24 是三个字节。
- UB 表示位域,比如 UB5 表示一个字节的5位。
1.2.1. 整体结构
- 整体结构如下,由Header及Tag组成
- 每个Tag的下面有一块4bytes的空间,用来记录这个tag的长度(不含tagSize占用的4个字节),后置可用于逆向读取处理(TagHeader里会记录Tag的长度,可用于正向读取数据处理)。
- body 包含 Tag0Size+Tag1(Tag1Size)+…+TagN(TagNSize)
- tagSize = 11*8(tagHeaderSize)+tagDataSize(tagHeader里有)
Header |
---|
Tag0Size(没有Tag0所以此处为0) |
Tag1 |
Tag1Size |
Tag2 |
Tag2Size |
… |
… |
TagN(lastTag) |
TagNSize(lastTagSize) |
1.2.2. Header结构
Field | type | Comment |
---|---|---|
签名 | UI | ’F’(0X46) |
签名 | UI8 | ‘L’(0X4C) |
签名 | UI8 | ‘V’(0x56) |
版本 | UI8 | FLV的版本。0x01表示FLV版本是1 |
保留字段 | UB5 | 前五位必须是0 |
是否有音频流 | UB1 | 音频流是否存在标志 |
保留字段 | UB1 | 必须是0 |
是否有视频流 | UB1 | 视频流是否存在标志 |
文件头大小 | UI32 | FLV头的大小(FLV版本为1时固定为9)。文件头到这里的大小(包括这四个字节) |
1.2.3. tag结构
Field | type | Comment |
---|---|---|
TAG类型 | UI8 | 8: audio,9: video,18: script data(描述信息)。 |
数据大小 | UI24 | 数据区的大小,不包括tag头。包头总大小是11个字节。 |
时间戳 | UI24 | 当前帧时戳,单位是毫秒。相对于FLV文件的第一个TAG时戳。第一个tag的时间戳总是0,实际是dts |
时间戳扩展字段 | UI8 | 如果时戳大于0xFFFFFF,将会使用这个字节。这个字节是时戳的高8位,上面的三个字节是低24位。 |
流ID | U24 | 总是0 |
数据区 | UI8[n] | 根据类型区分,包括视频,音频,描述信息 |
1.2.4. 音频数据结构
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;10:AAC;11:Speex;14:MP3 8-Khz;15:Device-specific sound;9,12,13:reserved; |
采样率 | UB2 | 0:5.5-kHz;1:11-kHz;2:22-kHz;3:44-kHz(For AAC: always 3) |
采样大小 | UB1 | 0:snd8Bit;1:snd16Bit。只有未压缩格式有效,压缩格式都按照16bit采样处理 |
声道 | UB1 | 0:单声道;1:立体声,双声道。Nellymoser必须是0,AAC必须是1 |
声音数据 | UI8[N] | 如果是PCM线性数据,存储的时候每个16bit小端存储,有符号。如果音频格式是AAC,则存储的数据是AAC AUDIO DATA (具体格式详见下边),否则为线性数组。 |
AACAUDIODATA
Field | Type | Comment |
---|---|---|
AACPacketType | U8 | 0: AAC sequence header;1: AAC raw |
Data | UI8[n] | AudioSpecificConfig(ISO 14496-3) or Raw AAC frame data |
1.2.5. 视频数据结构
Field | type | Comment |
---|---|---|
帧类型 | UB4 | 1: keyframe (for AVC, a seekable frame)——h264的IDR,关键帧,可重入帧; 2: inter frame (for AVC, a non- seekable frame),h264的普通帧; 3: disposable inter frame (H.263 only);4: generated keyframe (reserved for server use only); 5: video info/command frame(比如标识是否Seek等) |
编码ID | UB4 | 1: JPEG (currently unused); 2: Sorenson H.263;3: Screen video;4: On2 VP6;5: On2 VP6 with alpha channel; 6: Screen video version 2;7: AVC |
视频数据 | UI[N] | 不同的编码,格式不一样,H263VIDEOPACKET/SCREENVIDEOPACKET/VP6FLVVIDEOPACKET/VP6FLVALPHAVIDEOPACKET/SCREENV2VIDEOPACKET/AVCVIDEOPACKET的其中一种结构,具体可以参考标准 |
AVCVIDEOPACKET
Field | type | Comment |
---|---|---|
AVC packet类型 | UI8 | 0:AVC序列头1:AVC NALU单元2:AVC序列结束(低级别avc不需要) |
CTS | SI24 | 如果AVC packet类型是1,则为cts(Composition time offset)偏移,否则为0,通过CTS和tag中的DTS可以得到PTS |
数据 | UI8[n] | 如果AVC packet类型是0,则是解码器配置,sps,pps。如果是1,则是nalu单元(可以是多个) |
1.3. 相关概念
- pts(presentation time stamps),dts(decoder timestamps),cts(CompositionTime)
- pts:显示时间,也就是接收方在显示器显示这帧的时间。单位为1/90000 秒。
- dts:解码时间,也就是rtp包中传输的时间戳,表明解码的顺序。单位单位为1/90000 秒。
- cts偏移:cts = (pts - dts) / 90 。cts的单位是毫秒。
- flv文件中Timestamp和TimestampExtended拼出来的是dts。单位为ms。
- CompositionTime 表示PTS相对于DTS的偏移值, 显示时间(pts) = 解码时间(tag的第5~8字节) + CompositionTime,单位也是ms