多媒体文件格式(二):FLV 格式
在网络的直播与点播场景中,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
工具使用如图:

左侧树状结构显示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
工具使用如图:

三、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: size:
Probing mp3 score: size:
[flv @ 0x7fc669002a00] Format flv probed with size= and score=
[flv @ 0x7fc669002a00] Before avformat_find_stream_info() pos: bytes read: seeks: nb_streams:
[flv @ 0x7fc669002a00] type:, size:, last:-, dts: pos:
[flv @ 0x7fc669002a00] keyframe stream hasn't been created
[flv @ 0x7fc669002a00] type:, size:, last:-, dts: pos:
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00] keyframe filepositions = times =
[flv @ 0x7fc669002a00]
[flv @ 0x7fc669002a00] type:, size:, last:-, dts: pos:
[flv @ 0x7fc669002a00] AF
[flv @ 0x7fc669002a00] type:, size:, last:-, dts: pos:
[flv @ 0x7fc669002a00]
[NULL @ 0x7fc668809e00] nal_unit_type: , nal_ref_idc:
[NULL @ 0x7fc668809e00] nal_unit_type: , nal_ref_idc:
[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: , nal_ref_idc:
[h264 @ 0x7fc668809e00] nal_unit_type: , nal_ref_idc:
[h264 @ 0x7fc668809e00] nal_unit_type: , nal_ref_idc:
[h264 @ 0x7fc668809e00] nal_unit_type: , nal_ref_idc:
[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:, size:, last:-, dts: pos:
[flv @ 0x7fc669002a00] 0
(省略......)
[flv @ 0x7fc669002a00] AF
[flv @ 0x7fc669002a00] type:, size:, last:-, dts: pos:
[flv @ 0x7fc669002a00]
[flv @ 0x7fc669002a00] All info found
[flv @ 0x7fc669002a00] stream : start_time: 0.080 duration: -9223372036854776.000
[flv @ 0x7fc669002a00] stream : start_time: 0.080 duration: -9223372036854776.000
[flv @ 0x7fc669002a00] format: start_time: 0.080 duration: 189.440 bitrate= kb/s
[flv @ 0x7fc669002a00] After avformat_find_stream_info() pos: bytes read: seeks: frames:
Input #, flv, from 'out.flv':
Metadata:
major_brand : isom
minor_version :
compatible_brands: isomiso2avc1mp41
artist : yinyuetai.com
album : Yinyuetai
date : // ::
comment : Yinyuetai-1TR1026
encoder : Lavf57.83.100
hasVideo : true
hasKeyframes : true
hasAudio : true
hasMetadata : true
canSeekToEnd : true
datasize :
videosize :
audiosize :
lasttimestamp :
lastkeyframetimestamp:
lastkeyframelocation:
Duration: ::09.44, start: 0.080000, bitrate: kb/s
Stream #:, , /: Video: h264 (Main), reference frame, yuv420p(progressive, left), 576x432, /, kb/s, fps, tbr, 1k tbn, tbc
Stream #:, , /: Audio: aac (HE-AAC), Hz, stereo, fltp, kb/s
[h264 @ 0x7fc668824400] nal_unit_type: , nal_ref_idc:
[h264 @ 0x7fc668824400] nal_unit_type: , nal_ref_idc:
[AVIOContext @ 0x7fc667f005c0] Statistics: bytes read, seeks
从以上内容可以看到,输出信息包含了keyframe关键帧存储在文件中的偏移位置及时间戳。
多媒体文件格式(二):FLV 格式的更多相关文章
- 多媒体文件格式之FLV
[时间:2016-07] [状态:Open] FLV是一个相对简单的多媒体格式,仅支持单节目,也就是说每个FLV只能至多一个音频.至多一个视频.FLV(Flash Video)是Adobe的一个免费开 ...
- 多媒体文件格式(一):MP4 格式
在互联网常见的格式中,跨平台最好的应该就属MP4文件了.因为MP4文件既可以在PC平台的Flashplayer中播放,又可以在移动平台的Android.iOS等平台中进行播放,而且使用系统默认的播放器 ...
- rtmp直播推流(一)--flv格式解析与封装
flv文件格式分析,可参看RTMP中FLV流到标准h264.aac的转换,该文章写的很清晰. flv封装格式解析,可参看视音频数据处理入门:FLV封装格式解析,文章图文并貌,很直观. flv文件封装, ...
- 通过RTMP play分析FLV格式详解
最近做了一个rtmp中转服务程序,通过实践,熟悉rtmp play和push中各类格式,这里总结一下. 程序github地址: https://github.com/runner365/rtmp_re ...
- 用java程序调用ffmpeg执行视频文件格式转换flv
用java小例题说明更直观:(可以直接编译运行)环境我在windows平台下测试的...需要在e:/下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4 ...
- FLV格式详解
Overview Flash Video(简称FLV),是一种流行的网络格式.目前国内外大部分视频分享网站都是采用的这种格式. File Structure 从整个文件上开看,FLV是由The FLV ...
- 如何下载网页上的视频 并且 flv 格式转化成 MP4
链接:http://www.jb51.net/softjc/222135.html https://jingyan.baidu.com/article/25648fc162f2899190fd0042 ...
- c/c++常用代码---doc,ppt,xls文件格式转PDF格式[转]
[转]doc,ppt,xls文件格式转PDF格式 http://blog.csdn.net/lee353086/article/details/7920355 确实好用. 需要注意的是#import文 ...
- 前端页面播放 rtmp 流与 flv 格式视频文件
技术 :angular/cli , html5 , typescript , scss ,es 6 ... 项目类型:直播视频与视频回放 使用到 插件 : videojs + ckplayer 遇到的 ...
随机推荐
- js &运算符什么意思,什么用处
“&&”连接两个表达式,当两侧表达式都为真时,返回TRUE.有一个为假则返回FALSE. 也就是说,符号前面的如果为true,就会执行符号后面的语句,如果符号前面的为false,那么后 ...
- idea cpu 卡慢 占用100%
1.修改idea配置文件D:\ideaIU-2017.2\bin\idea.exe.vmoptions 如: -server -Xms800m -Xmx800m -XX:MaxPermSize=512 ...
- Flink写入kafka时,只写入kafka的部分Partitioner,无法写所有的Partitioner问题
1. 写在前面 在利用flink实时计算的时候,往往会从kafka读取数据写入数据到kafka,但会发现当kafka多个Partitioner时,特别在P量级数据为了kafka的性能kafka的节点有 ...
- Flink on yarn的配置及执行
1. 写在前面 Flink被誉为第四代大数据计算引擎组件,即可以用作基于离线分布式计算,也可以应用于实时计算.Flink可以自己搭建集群模式已提供为庞大数据的计算.但在实际应用中.都是计算hdfs上的 ...
- [转]7行Python代码的人脸识别
https://blog.csdn.net/wireless_com/article/details/64120516 随着去年alphago 的震撼表现,AI 再次成为科技公司的宠儿.AI涉及的领域 ...
- MVC中ztree异步加载
var setting = { async: { enable: true, url: "*****/LoadChild", autoParam: ["id"] ...
- Monkey如何使用
1.Monkey是Google提供的一个命令行工具,可以运行在模拟器或者实际设备中.它向系统发送伪随机的用户事件(如按键.手势.触摸屏等输入),对软件进行稳定性与压力测试. Monkey是什么:Mon ...
- css居中,margin_and_position
首先父元素肯定是要相对定位的,其次我们上下左右居中的元素的css如下: width: 50px; height: 50px; margin: auto; position: absolute; lef ...
- Linux文件的扩展名--2019-04-25
1.压缩的和归档的文件 .bz2:使用bzip2压缩的文件 .gz:使用gzip压缩的文件 .tar:使用tar压缩的文件 .tbz:使用tar和bzip压缩的文件 .tgz:使用tar和gzip压缩 ...
- D3---01基础的柱状图制作(转)
---文章转自 http://d3.decembercafe.org/index.html ,Created by 十二月咖啡馆. 一个完整的柱形图包含三部分:矩形.文字.坐标轴. 首先要布置一个大 ...