FLV文件格式详解


具体格式可以参看 flv spec。

FLV文件格式详解_第1张图片

下面主要介绍上图中的Tag里面的字段,每个Tag由两部分组成:Tag Header和Tag Data。

1. Tag Header

名称 长度 介绍
Tag类型 1 bytes 8:音频
9:视频
18:meta
其他:保留
数据区长度 3 bytes 在数据区的长度
时间戳 3 bytes 整数,单位是毫秒。对于脚本型的tag总是0
时间戳扩展 1 bytes 将时间戳扩展为4bytes,代表高8位。很少用到
StreamsID 3 bytes 总是0
数据区(data) 由数据区长度决定 数据实体

2. Tag Data

Tag的数据区根据Tag类型的不同可以分为三种:音频数据、视频数据和meta数据。

2.1 音频数据

第一个字节是音频信息,格式如下:
名称 长度 介绍
音频格式 4 bits 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
采样率 2 bits 0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz
对于AAC总是3
采样的长度 1 bit 0 = snd8Bit
1 = snd16Bit
压缩过的音频都是16bit
音频类型 1 bit 0 = sndMono
1 = sndStereo
对于AAC总是1
音频数据         8 bit [n]  
     

如果是AAC格式的情况下,音频数据的格式如下:

FLV文件格式详解_第2张图片

2.2 视频数据

第一个字节是视频信息,格式如下:
名称 长度 介绍
帧类型 4 bits 1: keyframe (for AVC, a seekable frame)
2: inter frame (for AVC, a non-seekable frame)
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frame
编码ID 4 bits 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

如果帧类型是5,那么这个tag data的内容不是视频数据,data里面是8bits数据,意义如下:
  • 0, Start of client-side seeking video frame sequence 
  • 1,End of client-side seeking video frame sequence 
如果是AVC格式的话,tag data后面的数据格式如下:

FLV文件格式详解_第3张图片

2.3 脚本数据

脚本Tag一般只有一个,是flv的第一个Tag,用于存放flv的信息,比如duration、audiodatarate、creator、width等。

首先介绍下脚本的数据类型。所有数据都是以数据类型+(数据长度)+数据的格式出现的,数据类型占1byte,数据长度看数据类型是否存在,后面才是数据。

格式如下:

FLV文件格式详解_第4张图片

FLV文件格式详解_第5张图片

如果类型为String,后面的2bytes为字符串的长度(Long String是4bytes),再后面才是字符串数据;如果是Number类型,后面的8bytes为Double类型的数据;Boolean类型,后面1byte为Bool类型。

知道了这些后再来看看flv中的脚本,一般开头是0x02,表示String类型,后面的2bytes为字符串长度,一般是0x000a(“onMetaData”的长度),再后面就是字符串“onMetaData”。好像flv格式的文件都有onMetaData标记,在运行ActionScript的时候会用到它。后面跟的是0x08,表示ECMA Array类型,这个和Map比较相似,一个键跟着一个值。键都是String类型的,所以开头的0x02被省略了,直接跟着的是字符串的长度,然后是字符串,再是值的类型,也就是上面介绍的那些了。

onMetaData标签中包含的是流的信息,一般的信息包括:

  • duration: a DOUBLE indicating the total duration of the file in seconds
  • width: a DOUBLE indicating the width of the video in pixels
  • height: a DOUBLE indicating the height of the video in pixels
  • videodatarate: a DOUBLE indicating the video bit rate in kilobits per second 
  • framerate: a DOUBLE indicating the number of frames per second
  • videocodecid: a DOUBLE indicating the video codec ID used in the file (see “Video tags” on page 8 for available CodecID values)
  • audiosamplerate: a DOUBLE indicating the frequency at which the audio stream is replayed
  • audiosamplesize: a DOUBLE indicating the resolution of a single audio sample
  • stereo: a BOOL indicating whether the data is stereo
  • audiocodecid: a DOUBLE indicating the audio codec ID used in the file (see “Audio tags” on page 6 for available SoundFormat values)
  • filesize: a DOUBLE indicating the total size of the file in bytes 

2.4 keyframes索引信息

官方的文档中并没有对 keyframes index 做描述,但是,flv 的这种结构每个 tag 又不像 TS 有同步头,如果没有 keyframes index 的话,需要按顺序读取每一个tag, seek 及快进快退的效果会非常差。后来在做 flv 文件合成的时候,发现网上有的 flv 文件将 keyframes 信息隐藏在 Script Tag 中。

keyframes 几乎是一个非官方的标准, 也就是民间标准。两个常用的操作 metadata 的工具是 flvtool2 和 FLVMDI,都是把 keyframes 作为一个默认的元信息项目。在 FLVMDI 的主页上有描述:

keyframes: (Object) This object is added only if you specify the /k switch. 'keyframes' is known to FLVMDI and if /k switch is not specified, 'keyframes' object will be deleted. 'keyframes' object has 2 arrays: 'filepositions' and 'times'. Both arrays have the same number of elements, which is equal to the number of key frames in the FLV. Values in times array are in 'seconds'. Each correspond to the timestamp of the n'th key frame. Values in filepositions array are in 'bytes'. Each correspond to the fileposition of the nth key frame video tag (which starts with byte tag type 9).

也就是说 keyframes 中包含着 2 个内容 “filepositions” 和 “times”分别指的是关键帧的文件位置和关键帧的 PTS。通过 keyframes 可以建立起自己的 Index,然后在 seek 和快进快退的操作中,快速有效地跳转到你想要找的关键帧位置进行处理。

3. FLV分析工具

  • flvmeta.com/
  • yamdi:将flv转成带索引的flv,yamdi -i i.flv -o o.flv
  • flvlib: pip install flvlib, 查看索引信息:debug-flv --metadata file.flv
  • flvcheck:adobe.com/products/adob

你可能感兴趣的:(多媒体)