FLV结构详解,FLV协议详解(泰山鲁 转载加修正)

FLV结构详解,FLV协议详解(泰山鲁 转载加修正)

FLV这种格式大家一定不会陌生,知道他的文件结构了,才可能读的懂前辈的代码,正好项目碰到了flv文件结构,我这里引用了网上的一些结构,加上自己翻译和改进,整理了这个文章,希望对对家有帮助 

FLV是一个二进制文件,由文件头(FLV header)和很多tag组成。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流(关键字或者文件信息之类)。出自百度-

 

FLV Header

一般比较简单,包括文件类型之类的全局信息

文件类型3bytes总是FLV(0x46(F的ASC码,原注释看着让人头疼) 0x4C 0x56),否则..就不是
版本
1byte一般是0x01,表示FLV version 1
流信息1byte 
倒数第一bit是1表示有视频,倒数第三bit是1表示有音频,其他都应该是0(有些软件如flvtool2可能造成倒数第四bit是1,不过也没发现有什么不对)
header长度
4bytes整个文件头的长度,一般是9(3+1+1+4),有时候后面还有些别的信息,就不是9了
   

 

FLV Body

FLV body就是由很多tag组成的,一个tag包括下列信息:

文件头后紧跟的是文件内容,如下图所示(无耻的剽窃自别人的博客)



由上图可以看出,body部分由一个个Tag组成,每个Tag的下面有一块4bytes的空间用来记录这个tag的⻓度,这个后置用于逆向。当然第一个tag的长度肯定是0了(PreviosTagSize04个字节的0)


Tag 解析

每一个tag也是由两部分组成:tag头和tag数据区。

好了至此FLV格式分析结束,嘿嘿(裤子都脱了你就给看这个)。其实只是想强调下每个tag都是由 头+数据 组成。如下表所示,很明显tag头为11个字节。


tag头

tag头为下表中的前11个字节剩下的为tag数据区(具体分析见2.1.2)


名称

⻓度

介绍

TagTypetag类型)

UI8

8: audio(音频)

9: video(视频)

18: script data(脚本数据)

all others: reserved(其他保留)

DataSizetag数据区大小)

UI24

tag的数据区大小以字节为单位,注意字节序

Timestamp(时间戳)

UI24(原文漏写了)

tag相对于FLV文件第一个tag的时间,以毫秒为单位,当然第一个tag的时间戳肯定为0(很重要

TimestampExtended(时间戳扩展)

UI8

将时间戳扩展至32位,该字节代表高8位(很重要)

StreamID(信息流ID)

UI24

恒为0

Datatag数据区)

If TagType == 8

AUDIODATA

If TagType == 9

VIDEODATA

If TagType == 18

SCRIPTDATAOBJECT

由第一个字节的tag类型决定:

8时代表音频

9时代表视频

18时代表脚本数据




TAG结构图示,整体的就看做一个结构的各成员(又一篇,tag头很重要我这引用了另外一篇方便大家比对tag头和)

previoustagsize4bytes前一个tag的长度,第一个tag就是0
tag类型1byte

三类:

  • 8 -- 音频tag
  • 9 -- 视频tag
  • 18 -- 脚本tag
数据区长度3bytes 
时间戳3bytes单位毫秒,如果是脚本tag就是0
扩展时间戳 
1byte作为时间戳的高位
streamsID3bytes总是0(不知道干啥用)
数据区 

If TagType == 8

AUDIODATA

If TagType == 9

VIDEODATA

If TagType == 18

SCRIPTDATAOBJECT (这个原文一直不明什么东西,后来

查资料才知道是自定义的东西)

 

根据不同的tag类型就有不同的数据区

 先说脚本数据吧,每个脚本数据都是flv的第一包 首当其冲的东西,尽管他是最复杂的

一般来说脚本数据都是第一帧,所以先分析脚本数据吧,这个是FLV文件中最复杂的部分(音频和视频数据比较简单),脚本数据包含了一个FLV文件的信息数据如:分辨率,视频长度,码率,采样率等信息...


脚本数据的数据类型有:

0 = Number type (double型)

1 = Boolean type(bool型)

2 = String type(字符串型)

3 = Object type

4 = MovieClip type

5 = Null type

6 = Undefined type

7 = Reference type

8 = ECMA array type

10 = Strict array type

11 = Date type(时间类型)

12 = Long string type(长字符串)


所有的数据可由公式来表达,  公式 =  数据类型 + 数据长度(根据类型决定) + 数据  三部分组成


注意:公式中可以确定长度的数据长度就会省略(bool , double),有些类型确定的类型就省略(下面介绍)看来真是抠门到家了,为了弄清这点我拿了一个16禁止编辑器(非常推荐QtCreator或者Vc 编辑器,可以直接打开)一个字节一个字节对比才得出这点。

连官方文档都没有细说,如果本人理解有误请在留言中指出!!!

 

举个例子最能说明这个类型,看这个例子什么都明白了 

     泰山鲁不生产矿泉水,哥们也只是大自然的搬运工,下面转自网上一篇flv包头分析

                  

下面贴出FLV文件的一部分,包括FLV头和一个脚本数据




46 4c 56 01 05 00 00 00 09(FLV文件头)

00 00 00 00 (第一帧数据的长度)

12 00 04 f0 00 00 00 00 00 00 00(tag头,可以知道类型为18脚本数据,长度为 0x 00 04 f0 = 1264字节)

02 00 0a 6f 6e 4d 65 74 61 44 61 74 61(类型为字符串,长度00 0a = 10个内容为onMetaData)

08 00 00 00 0b (为ecma array类型,项数为不靠谱的11)


00 0f 6d 65 74 61 64 61 74 61 63 72 65 61 74 6f 72(key:string类型,类型字节省略, 长度为00 0f ,数据为metadatacreator

02 00 21 6d 6f 64 69 66 69 65 64 20 62 79 20 79 6f 75 6b 75 2e 63 6f 6d 20 69 6e 20 32 30 31 31 31 32 30 32(value:类型为02字符串,长度为00 21,数据为modified by youku.com in 20111202(00 21后面的33个字节)


00 0c 68 61 73 4b 65 79 66 72 61 6d 65 73(key:string类型,长度00 0c,数据hasKeyframes)

01 01(value:类型为01 bool类型,数值为01)


00 08 68 61 73 56 69 64 65 6f 01 01 00 08 68 61 73 41 75 64 69 6f 01 01 00 0b 68 61 73 4d 65 74 61 64 61 74 61 01 01 00 05 77 69 64 74 68 00 40 91 c0 00 00 00 00 00 00 06 68 65 69 67 68 74 00 40 83 10 00 00 00 00 00 00 09 66 72 61 6d 65 72 61 74 65 00 40 37 f9 dc b5 11 22 87 00 0f 61 75 64 69 6f 73 61 6d 70 6c 65 72 61 74 65 00 40 d5 88 80 00 00 00 00 00 08 64 75 72 61 74 69 6f 6e 00 40 67 7b 56 b2 db d1 94 00 09 6b 65 79 66 72 61 6d 65 73


03(object类型)

00 0d 66 69 6c 65 70 6f 73 69 74 69 6f 6e 73(key:类型为string类型(省略)长度00 0d,值:filepositions)

0a 00 00 00 37 (value:类型为Strict array,数组的项数为00 00 00 37 = 55项)

00 40 94 30 00 00 00 00 00 (类型00为double类型,所以长度省略,接下来的8个字节代表值 1292.000000)

00 40 95 a8 00 00 00 00 00(类型00为double类型,所以长度省略,接下来的8个字节代表值 1386.000000)

00 40 f9 63 30 00 00 00 00 00 41 10 83 1c 00 00 00 00 00 41 1c 18 38 00 00 00 00 00 41 21 83 9e 00 00 00 00 00 41 29 29 8e 00 00 00 00 00 41 34 d7 04 00 00 00 00 00 41 3b 19 dd 00 00 00 00 00 41 3d 71 aa 00 00 00 00 00 41 3e ef 0b 00 00 00 00 00 41 47 78 7f 00 00 00 00 00 41 4e f8 c0 80 00 00 00 00 41 51 cf 99 80 00 00 00 00 41 55 70 e2 c0 00 00 00 00 41 58 fb fa 80 00 00 00 00 41 5c 9f ea 80 00 00 00 00 41 5d b7 d8 00 00 00 00 00 41 5e b8 b9 80 00 00 00 00 41 60 5e e9 80 00 00 00 00 41 60 d6 48 40 00 00 00 00 41 61 29 4d c0 00 00 00 00 41 61 86 44 60 00 00 00 00 41 62 0e 49 00 00 00 00 00 41 62 6f b6 60 00 00 00 00 41 62 e1 c3 00 00 00 00 00 41 63 68 59 40 00 00 00 00 41 64 1a 54 a0 00 00 00 00 41 64 d0 c9 60 00 00 00 00 41 66 0a 50 a0 00 00 00 00 41 66 98 d6 20 00 00 00 00 41 66 c1 67 e0 00 00 00 00 41 66 cd 8e 20 00 00 00 00 41 66 e4 b3 c0 00 00 00 00 41 67 3e 92 80 00 00 00 00 41 68 1a ed 00 00 00 00 00 41 69 25 f9 00 00 00 00 00 41 69 9a 09 e0 00 00 00 00 41 69 e7 0d 40 00 00 00 00 41 6a 02 ef 20 00 00 00 00 41 6a 9b 54 20 00 00 00 00 41 6c 4c db 40 00 00 00 00 41 6d 08 bf 20 00 00 00 00 41 6e 39 83 20 00 00 00 00 41 70 83 14 f0 00 00 00 00 41 71 04 77 e0 00 00 00 00 41 71 c3 82 60 00 00 00 00 41 72 77 6a 40 00 00 00 00 41 72 c5 e1 40 00 00 00 00 41 73 6a 92 30 00 00 00 00 41 73 eb cf 20 00 00 00 00 41 74 25 d7 70 00 00 00 00 41 74 52 66 00 00 00 00 00 41 74 97 38 50 00 00 00 00 41 75 41 a2 40 00 00 00 00 05 74 69 6d 65 73 0a 00 00 00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 14 05 1e b8 51 eb 85 00 40 23 84 fd f3 b6 45 a1 00 40 2f 88 10 62 4d d2 f1 00 40 33 3a 40 2b b0 cf 87 00 40 36 c5 d2 f1 a9 fb e7 00 40 3c c7 5c 28 f5 c2 8f 00 40 41 64 72 b0 20 c4 9b 00 40 42 84 bc 6a 7e f9 db 00 40 43 c5 0e 56 04 18 93 00 40 46 c5 d2 f1 a9 fb e7 00 40 49 c6 97 8d 4f df 3b 00 40 4c c2 05 76 19 f0 fb 00 40 4e 4d 15 29 a4 85 cd 00 40 50 81 8d fe a2 79 83 00 40 52 01 f0 4c 75 6b 2d 00 40 53 3a 40 2b b0 cf 87 00 40 54 62 8b f2 58 bf 25 00 40 55 e2 ee 40 2b b0 cf 00 40 56 bb 25 8b f2 58 bf 00 40 57 1b 3e 1f 67 15 29 00 40 57 ee 1e b8 51 eb 85 00 40 58 73 96 2f c9 62 fc 00 40 58 f1 0b 9a f7 20 15 00 40 59 7e 85 1e b8 51 eb 00 40 5a 59 67 c3 ec e2 a5 00 40 5b 51 a7 40 da 74 0d 00 40 5c 5c 96 2f c9 62 fc 00 40 5d bf 9b a5 e3 53 f7 00 40 5e 47 be 76 c8 b4 39 00 40 5e 62 6f f5 13 cc 1d 00 40 5e 6a 72 01 5d 86 7c 00 40 5e 7a 76 19 f0 fb 38 00 40 5e bf dd 2f 1a 9f be 00 40 5f 2f f9 db 22 d0 e5 00 40 5f 9d 6b 2d bd 19 42 00 40 5f e0 26 e9 78 d4 fd 00 40 60 04 18 93 74 bc 6a 00 40 60 0a c4 f3 07 82 63 00 40 60 36 d0 36 9d 03 69 00 40 60 c8 4a c0 83 12 6e 00 40 61 0f 07 82 63 ab 59 00 40 61 68 73 b6 45 a1 ca 00 40 62 28 a4 dd 2f 1a 9f 00 40 62 97 6b dc 80 57 61 00 40 63 2b 91 bf d4 4f 30 00 40 63 eb c2 e6 bd c8 05 00 40 64 59 34 39 58 10 62 00 40 65 19 65 60 41 89 37 00 40 65 8d 83 12 6e 97 8d 00 40 65 ae e0 f0 4c 75 6b 00 40 65 d2 ea 27 98 3c 13 00 40 66 1c 52 42 e6 bd c8 00 40 66 bb 25 8b f2 58 bf 

00 00 09 (object的结尾)

00 00 09(ecma array的结尾)


有兴趣的同学可以自行分析,看到这么复杂的脚本“数据区”是不是晕蛋了呢,如果没有的话恭喜你厉害,本菜可是分析了将近10分钟才得出这些结论的(反正吹牛又不用缴税,擦劳资的两个不眠夜啊)。接下来毁三观:

必须用的数据只在tag头中,必须用的数据只在tag头中,必须用的数据只在tag头中....

所以如果晕菜的话没关系,在实际应用中(比如视频合并)本菜的亲身经历告诉你其实这么复杂的脚本数据其实99%都没有卵用。




Audio tag 数据区

audio信息1byte

前四位bits表示音频格式:

  • 0 -- 未压缩
  • 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

下面两位bits表示samplerate:

  • 0 -- 5.5kHz
  • 1 -- 11kHz
  • 2 -- 22kHz
  • 3 -- 44kHz

下面一位bit表示每个采样的长度:

  • 0 -- snd8Bit
  • 1 -- snd16Bit

下面一位bit表示类型:

  • 0 -- sndMomo
  • 1 -- sndStereo
audio数据区
不定

 

 

if SoundFormat == 10

    AACAUDIODATA

else

    Sound data—varies by format

 

 

 

AACAUDIODATA

AACPacketType1byte

 

0: AAC sequence header

1: AAC raw

 

AACAUDIODATA数据区
不定

 

 

iif AACPacketType == 0

     AudioSpecificConfig

else if AACPacketType == 1

    Raw AAC frame data

 

 

 

 

2.1.2.2.1 音频数据

名称

⻓度

介绍

SoundFormat(音频格式)

UB[4] 4bit)

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 logarithmicPCM

9 = reserved

10 = AAC

11 = Speex

14 = MP3 8-Khz

15 = Device-specific sound

SoundRate (音频波特率)


UB[2]

0 = 5.5-kHz

1 = 11-kHz

2 = 22-kHz

3 = 44-kHz

SoundSize(采样长度)

UB[1]

0 = snd8Bit

1 = snd16Bit

SoundType(音频类型)

UB[1]

0 = sndMono

1 = sndStereo

ACC来说总是1

音频数据


 

 

 

video tag 数据区

video信息1byte

前四位bits表示类型:

  • 1 -- keyframe
  • 2 -- inner frame
  • 3 -- disposable inner frame (H.263 only)
  • 4: generated keyframe (reserved for server use only)
  • 5: video info/command frame 

后四位bits表示编码器id:

  • 1: JPEG (currently unused)
  • 2 -- Seronson H.263
  • 3 -- Screen video
  • 4 -- On2 VP6
  • 5 -- On2 VP6 without channel
  • 6 -- Screen video version 2
  • 7: AVC 
video数据区
不定

 

 

If CodecID == 2 

H263VIDEOPACKET

If CodecID == 3 

SCREENVIDEOPACKET

If CodecID == 4 

VP6FLVVIDEOPACKET

If CodecID == 5 

VP6FLVALPHAVIDEOPACKET

If CodecID == 6 

SCREENV2VIDEOPACKET

if CodecID == 7

AVCVIDEOPACKET

 


视频数据,类型信息如下表中的第一个字节

名称

⻓度

介绍

FrameType(帧类型)

UB[4] 4bit)

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 logarithmicPCM

9= reserved

10= AAC

11= Speex

14= MP3 8-Khz

15= Device-specific sound1:keyframe (for AVC, a seekable

frame)

2:inter frame (for AVC, a non-

seekableframe)

3:disposable inter frame(H.263

only)

4:generated keyframe (reservedfor

serveruse only)

5:video info/command frame

CodecID(编码类型)


UB[4]

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

VideoData(视频数据)

IfCodecID == 2

orUI8

H263VIDEOPACKET

IfCodecID == 3

SCREENVIDEOPACKET

IfCodecID == 4

VP6FLVVIDEOPACKET

IfCodecID == 5

VP6FLVALPHAVIDEOPACKET

IfCodecID == 6

SCREENV2VIDEOPACKET

ifCodecID == 7

AVCVIDEOPACKET



类型信息如下表中的第一个字节

名称

⻓度

介绍

FrameType(帧类型)

UB[4] 4bit)

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 logarithmicPCM

9= reserved

10= AAC

11= Speex

14= MP3 8-Khz

15= Device-specific sound1:keyframe (for AVC, a seekable

frame)

2:inter frame (for AVC, a non-

seekableframe)

3:disposable inter frame(H.263

only)

4:generated keyframe (reservedfor

serveruse only)

5:video info/command frame

CodecID(编码类型)


UB[4]

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

VideoData(视频数据)

IfCodecID == 2

orUI8

H263VIDEOPACKET

IfCodecID == 3

SCREENVIDEOPACKET

IfCodecID == 4

VP6FLVVIDEOPACKET

IfCodecID == 5

VP6FLVALPHAVIDEOPACKET

IfCodecID == 6

SCREENV2VIDEOPACKET

ifCodecID == 7

AVCVIDEOPACKET



类型信息如下表中的第一个字节

名称

⻓度

介绍

FrameType(帧类型)

UB[4] 4bit)

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 logarithmicPCM

9= reserved

10= AAC

11= Speex

14= MP3 8-Khz

15= Device-specific sound1:keyframe (for AVC, a seekable

frame)

2:inter frame (for AVC, a non-

seekableframe)

3:disposable inter frame(H.263

only)

4:generated keyframe (reservedfor

serveruse only)

5:video info/command frame

CodecID(编码类型)


UB[4]

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

VideoData(视频数据)

IfCodecID == 2

orUI8

H263VIDEOPACKET

IfCodecID == 3

SCREENVIDEOPACKET

IfCodecID == 4

VP6FLVVIDEOPACKET

IfCodecID == 5

VP6FLVALPHAVIDEOPACKET

IfCodecID == 6

SCREENV2VIDEOPACKET

ifCodecID == 7

AVCVIDEOPACKET



 

H263VIDEOPACKET

H263VIDEOPACKET数据结构:

PictureStartCode UB[17]  和H.263 5.1.1相似
    0000 0000 0000 0000 1

Version  UB[5]  视频格式版本
    Flash Player 6 supports 0 and 1
TemporalReference UB[8]  察看 H.263 5.1.2

PictureSize UB[3]  图像尺寸:
    000: custom, 1 byte
    001: custom, 2 bytes
    010: CIF (352x288)
    011: QCIF (176x144)
    100: SQCIF (128x96)
    101: 320x240
    110: 160x120
    111: 保留

CustomWidth   If PictureSize = 000 UB[8]
    If PictureSize = 001 UB[16]
    否则不存在
    注意:UB[16]不一样UI16,这里不是字节交换的
    单位是像素

CustomHeight   If PictureSize = 000 UB[8]

 

AVCVIDEOPACKET

 

AVCPacketType1byte

 

 

0: AVC sequence header

1: AVC NALU

2: AVC end of sequence (lower level NALU 

sequence ender is not required or supported)

 

CompositionTime
3byte

 

 

if AVCPacketType == 1

Composition time offset 

else

0

 

 

 

Data不定

 

 

if AVCPacketType == 0

AVCDecoderConfigurationRecord

else if AVCPacketType == 1

One or more NALUs (can be individual

slices per FLV packets; that is, full frames

are not strictly required)

else if AVCPacketType == 2

Empty

 

 

 

script tag 数据区

来两张图片

 

 

学习的过程是漫长和痛苦的,学会了你就感觉神仙一样,一切神秘的flv,aac avc和复杂的音视频数据都是个屎

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值