在网络的直播与点播场景中,FLV也是一种常见的格式,FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式,其封装格式非常简单,均以FLVTAG的形式存在,并且每一个TAG都是独立存在的,接下来就详细介绍一下FLV标准。

一、FLV 格式标准介绍

FLV包括文件头(File Header)和文件体(File Body)两部分,其中文件体由一系列的Tag组成。FLV文件的结构如下图:



1. 文件头 Header

Header 部分记录了FLV的类型、版本等信息,是FLV的开头。一般差不多占9bytes。具体格式如下:

1. 文件标识(3B):总是为”FLV”, 0x46 0x4c 0x56

2. 版本(1B):目前为0x01

3. 流信息(1B):文件的标志位说明。前5位保留,必须为0;第6位为音频Tag:1表示有音频;第七位保留,为0; 第8位为视频Tag:1表示有视频

4. Header长度(4B):整个Header的长度,一般为9(版本为0x01时);大于9表示下面还有扩展信息。即0x00000009。

下图是使用工具FlvAnalyzer获取到的FLV的Header的详细信息:

 

2. 文件体 FLV Body

文件体由一系列的Tag组成。

其中,每个Tag前面还包含了Previous Tag
Size字段,表示前面一个Tag的大小。Tag的类型可以是视频、音频和Script,每个Tag只能包含以上三种类型的数据中的一种。

下图是使用FlvAnalyzer获取到的Body信息:



3. Tag

每个Tag由也是由两部分组成的:Tag Header和Tag Data。Tag Header里存放的是当前Tag的类型、数据区(Tag
Data)长度等信息,具体如下:

Tag类型(1):0x08:音频;     0x09:视频;      0x12:脚本;     其他:保留

数据区长度(3):数据区的长度

时间戳(3):整数,单位是毫秒。对于脚本型的tag总是0 (CTS)

时间戳扩展(1):将时间戳扩展为4bytes,代表高8位。很少用到

StreamsID(3):总是0

数据区(由数据区长度决定):数据实体

下面是三个Tag类型说明:

*
Audio Tag Data结构(音频类型) :音频Tag Data区域开始的第一个字节包含了音频数据的参数信息,从第二个字节开始为音频流数据。

* video Tag Data结构(视频类型):视频Tag Data开始的第一个字节包含视频数据的参数信息,从第二个字节开始为视频流数据。
*
Script Tag Data结构(脚本类型、帧类型):该类型Tag又被称为MetaData
Tag,存放一些关于FLV视频和音频的元信息,比如:duration、width、height等。通常该类型Tag会作为FLV文件的第一个tag,并且只有一个,跟在File
Header后。

二、FLV 分析工具

在上节的内容中,我们介绍了FLV的格式信息,同时也提到了FlvAnalyzer工具,下面我们就介绍两个工具,帮助大家整理和学习FLV相关知识:

1. FlvAnalyzer

通过FlvAnalyzer可以很清晰的看到FLV文件的基本结构,这样能够结合上面了解的FLV的知识,更清晰的查看FLV的格式及结构。

工具地址:
https://github.com/renhui/Thinking-in-AV/blob/master/多媒体格式/FLV/FlvAnalyzer.exe
<https://github.com/renhui/Thinking-in-AV/blob/master/%E5%A4%9A%E5%AA%92%E4%BD%93%E6%A0%BC%E5%BC%8F/FLV/FlvAnalyzer.exe>

工具使用如图:



左侧树状结构显示flv的信息,可以清楚了解flv文件的结构;

点击左侧节点,右侧显示对应hex与ascii信息,这样就不必打开二进制编辑器了;

通过此工具可以查看audio tag与video tag各个字节(精确到bit)的详细信息,了解每个tag是如何构造的,同时右下角黑色输出框显示某个值的意义;

2. FLV Format Analysis 工具


此工具是雷霄骅整理flvparse的开源代码,制作的flvformatanalysis工具,此工具可以用来帮助学习FLV封装格式结构。此外它还支持分离FLV中的视频流和音频流。

工具地址:
https://github.com/renhui/Thinking-in-AV/blob/master/多媒体格式/FLV/SpecialFFLV.exe
<https://github.com/renhui/Thinking-in-AV/blob/master/%E5%A4%9A%E5%AA%92%E4%BD%93%E6%A0%BC%E5%BC%8F/FLV/SpecialFFLV.exe>

工具使用如图:



三、FLV格式 与 FFmpeg 实战

1. 使用FFmpeg生成带关键索引信息的FLV


在网络视频点播文件为FLV格式文件时,人们经常用工具先对FLV文件进行一次转换,主要是将FLV文件中的关键帧建立一个索引,并将索引写到Metadata头中,这个步骤用FFmpeg同样也可以实现,使用参数
add_keyframe_index即可:
ffmpeg -i 好汉歌.mp4 -c copy -f flv -flvflags add_keyframe_index out.flv 
生成FLV包含了关键帧索引信息,这些关键帧索引信息并不是FLV的标准字段,但是由于其被广泛使用,已经成为常用的字段,所以FFmpeg也同样支持了这个功能。

2. 使用ffprobe查看FLV关键帧索引相关信息

除了在第二节介绍的两个工具,我们也可以使用ffprobe来解析FLV文件,并且还能将关键帧索引的相关信息打印出来,命令如下:
ffprobe -v trace -i out.flv
输出如下:
[NULL @ 0x7fc669002a00] Opening 'out.flv' for reading [file @ 0x7fc667f00480]
Setting default whitelist'file,crypto' Probing flv score:100 size:2048 Probing
mp3 score:1 size:2048 [flv @ 0x7fc669002a00] Format flv probed with size=2048
and score=100 [flv @ 0x7fc669002a00] Before avformat_find_stream_info() pos: 13
bytes read:32768 seeks:0 nb_streams:0 [flv @ 0x7fc669002a00] type:18, size:1184,
last:-1, dts:0 pos:21 [flv @ 0x7fc669002a00] keyframe stream hasn't been created
[flv @0x7fc669002a00] type:9, size:45, last:-1, dts:0 pos:1220 [flv @
0x7fc669002a00] keyframe filepositions = 1296 times = 0 [flv @ 0x7fc669002a00]
keyframe filepositions =159283 times = 3000 [flv @ 0x7fc669002a00] keyframe
filepositions =258004 times = 4000 [flv @ 0x7fc669002a00] keyframe
filepositions =272776 times = 4000 [flv @ 0x7fc669002a00] keyframe
filepositions =405340 times = 6000 [flv @ 0x7fc669002a00] keyframe
filepositions =1215104 times = 16000 [flv @ 0x7fc669002a00] keyframe
filepositions =2529035 times = 26000 [flv @ 0x7fc669002a00] keyframe
filepositions =3198814 times = 36000 [flv @ 0x7fc669002a00] keyframe
filepositions =3623757 times = 41000 [flv @ 0x7fc669002a00] keyframe
filepositions =4882191 times = 51000 [flv @ 0x7fc669002a00] keyframe
filepositions =5951597 times = 61000 [flv @ 0x7fc669002a00] keyframe
filepositions =6256906 times = 63000 [flv @ 0x7fc669002a00] keyframe
filepositions =7235927 times = 73000 [flv @ 0x7fc669002a00] keyframe
filepositions =8175324 times = 83000 [flv @ 0x7fc669002a00] keyframe
filepositions =9203399 times = 93000 [flv @ 0x7fc669002a00] keyframe
filepositions =9936528 times = 103000 [flv @ 0x7fc669002a00] keyframe
filepositions =11056393 times = 113000 [flv @ 0x7fc669002a00] keyframe
filepositions =12183978 times = 123000 [flv @ 0x7fc669002a00] keyframe
filepositions =13014068 times = 133000 [flv @ 0x7fc669002a00] keyframe
filepositions =13610750 times = 143000 [flv @ 0x7fc669002a00] keyframe
filepositions =14628601 times = 153000 [flv @ 0x7fc669002a00] keyframe
filepositions =15873046 times = 163000 [flv @ 0x7fc669002a00] keyframe
filepositions =17112198 times = 173000 [flv @ 0x7fc669002a00] keyframe
filepositions =18301365 times = 182000 [flv @ 0x7fc669002a00] keyframe
filepositions =18604436 times = 186000 [flv @ 0x7fc669002a00] 0 17 0 [flv @
0x7fc669002a00] type:8, size:9, last:-1, dts:0 pos:1280 [flv @ 0x7fc669002a00] 1
AF0 [flv @ 0x7fc669002a00] type:9, size:2117, last:-1, dts:0 pos:1304 [flv @
0x7fc669002a00] 0 17 0 [NULL @ 0x7fc668809e00] nal_unit_type: 7, nal_ref_idc: 3
[NULL @0x7fc668809e00] nal_unit_type: 8, nal_ref_idc: 3 [NULL @ 0x7fc668809e00]
user data:"x264 - core 142 r2 dd79a61 - H.264/MPEG-4 AVC codec - Copyleft
2003-2014 - http://www.videolan.org/x264.html - options: cabac=1 ref=8
deblock=1:-1:-1 analyse=0x1:0x131 me=umh subme=9 psy=1 psy_rd=1.00:0.15
mixed_ref=1 me_range=24 chroma_me=1 trellis=2 8x8dct=0 cqm=0 deadzone=21,11
fast_pskip=0 chroma_qp_offset=-3 threads=24 lookahead_threads=2
sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 stitchable=1
constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1
open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0
rc_lookahead=60 rc=2pass mbtree=1 bitrate=680 ratetol=1.0 qcomp=0.60 qpmin=0
qpmax=69 qpstep=4 cplxblur=20.0 qblur=0.5 ip_ratio=1.40 aq=1:1.00" [h264 @
0x7fc668809e00] nal_unit_type: 7, nal_ref_idc: 3 [h264 @ 0x7fc668809e00]
nal_unit_type:8, nal_ref_idc: 3 [h264 @ 0x7fc668809e00] nal_unit_type: 6,
nal_ref_idc:0 [h264 @ 0x7fc668809e00] nal_unit_type: 5, nal_ref_idc: 3 [h264 @
0x7fc668809e00] user data:"x264 - core 142 r2 dd79a61 - H.264/MPEG-4 AVC codec
- Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=1
ref=8 deblock=1:-1:-1 analyse=0x1:0x131 me=umh subme=9 psy=1 psy_rd=1.00:0.15
mixed_ref=1 me_range=24 chroma_me=1 trellis=2 8x8dct=0 cqm=0 deadzone=21,11
fast_pskip=0 chroma_qp_offset=-3 threads=24 lookahead_threads=2
sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 stitchable=1
constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1
open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0
rc_lookahead=60 rc=2pass mbtree=1 bitrate=680 ratetol=1.0 qcomp=0.60 qpmin=0
qpmax=69 qpstep=4 cplxblur=20.0 qblur=0.5 ip_ratio=1.40 aq=1:1.00" [h264 @
0x7fc668809e00] Reinit context to 576x432, pix_fmt: yuv420p [h264 @
0x7fc668809e00] no picture [flv @ 0x7fc669002a00] type:9, size:1653, last:-1,
dts:40 pos:3436 [flv @ 0x7fc669002a00] 0 27 0
(省略......) [flv @ 0x7fc669002a00] 1 AF 0 [flv @ 0x7fc669002a00] type:9, size:88
,last:-1, dts:1600 pos:31870 [flv @ 0x7fc669002a00] 0 27 0 [flv @ 0x7fc669002a00
] Allinfo found [flv @ 0x7fc669002a00] stream 0: start_time: 0.080 duration: -
9223372036854776.000 [flv @ 0x7fc669002a00] stream 1: start_time: 0.080
duration: -9223372036854776.000 [flv @ 0x7fc669002a00] format: start_time: 0.080
duration:189.440 bitrate=787 kb/s [flv @ 0x7fc669002a00] After
avformat_find_stream_info() pos:31965 bytes read:32768 seeks:0 frames:74 Input #
0, flv, from 'out.flv': Metadata: major_brand : isom minor_version : 512
compatible_brands: isomiso2avc1mp41 artist : yinyuetai.com album : Yinyuetaidate
:04/01/15 15:51:32 comment : Yinyuetai-1TR1026 encoder : Lavf57.83.100
hasVideo :true hasKeyframes : true hasAudio : true hasMetadata : true
canSeekToEnd :true datasize : 18639072 videosize : 16303552 audiosize : 2335015
lasttimestamp :189 lastkeyframetimestamp: 187 lastkeyframelocation: 18603951
Duration:00:03:09.44, start: 0.080000, bitrate: 787 kb/s Stream #0:0, 41, 1/1000
: Video: h264 (Main),1 reference frame, yuv420p(progressive, left), 576x432, 0/1
,684 kb/s, 25 fps, 25 tbr, 1k tbn, 50 tbc Stream #0:1, 33, 1/1000: Audio: aac
(HE-AAC),44100 Hz, stereo, fltp, 95 kb/s [h264 @ 0x7fc668824400] nal_unit_type:
7, nal_ref_idc: 3 [h264 @ 0x7fc668824400] nal_unit_type: 8, nal_ref_idc: 3
[AVIOContext @0x7fc667f005c0] Statistics: 32768 bytes read, 0 seeks
从以上内容可以看到,输出信息包含了keyframe关键帧存储在文件中的偏移位置及时间戳。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信