位置

FLV [FLV头] [ScriptTag] [AudioTag1] [【这里】VideoTag1]…… [AudioTagN] [【这里】VideoTagN]


结构

含义
FrameType 4 bit 帧类型
CodecID 4 bit 编码格式
以下个数据只有在codecID = 7 (AVC) 时候才有
AVCPacketType 1 byte (8 bit) AVC 包类型
ComponsitionTime 3 byte (8 bit) 解码时间
数据体 数据体 数据体

帧类型

1 = key frame (for AVC, a seekable frame)
关键帧,可以从此开始播放 ~!

2 = inter frame (for AVC, a non-seekable frame)
非关键帧,不能从此开始播放

3 = disposable inter frame (H.263 only)
H263 的一次性非关键帧

4 = generated key frame (reserved for server use only)
生成的关键帧。实际流并没有这东西。仍然是给服务端预留的。

5 = video info/command frame
信息帧


编码格式

2 = Sorenson H.263
3 = Screen video
4 = On2 VP6
5 = On2 VP6 with alpha channel
6 = Screen video version 2
7 = AVC


AVC包类型

0 = AVC sequence header
CompositionTime 始终为 0 AVCDecoderConfigurationRecord

1 = AVC NALU
包含1个或多个NALU (必须是完整的帧!)

2 = AVC end of sequence (lower level NALU sequence ender is not required or supported)
然而并不是都有。嘛。


CompositionTime

见上 ↑


例子

1
2
3
4
5
6
7
8
09 0000 2b00 0000 0000 0000 // FLV Tag Header
1700 0000 00 // 视频头
~~ // 0001 1001 = frame type = 1 (I帧) codeC = 7 AVC
~~ // Sequence header
~~~~ ~~ // 0 composition Time = 0;
00 01 42c0 1fff e100 1667 42c0 1fda 0140 16e8 4000 //数据区
0003 005d cd65 0003 c60c a801 0005 68ce 3c80 00 //数据区
00 0000 36 // 整个Tag大小 54 应该等于 DataSize + 11 (43 + 11)

CompositionTime = PTS - DTS(FLV timestamp)

=> PTS = CT + DTS

一个实际的例子

No. 帧类型 CT timestamp PTS
1 1 80 2000 2080
2 2 160 2040 2200
3 2 80 2080 2160
4 2 0 2120 2120
5 2 160 2160 2320
6 2 80 2200 2280
7 2 0 2240 2240
8 2 160 2280 2440
9 2 80 2320 2400
10 2 0 2360 2360

播放时候排个序

No. 帧类型 CT timestamp PTS
1 1 80 2000 2080
4 2 0 2120 2120
3 2 80 2080 2160
2 2 160 2040 2200
7 2 0 2240 2240
6 2 80 2200 2280
5 2 160 2160 2320
10 2 0 2360 2360
9 2 80 2320 2400
8 2 160 2280 2440

注意到 每个帧间距为40ms 也就是1秒25帧 FPS=25