音视频 FLV格式解析
前言
本文介绍FLV封装格式,直播场景下拉流比较常见的是http-flv直播流,具有延时低、易传输等特点。
格式概览
总体上看,FLV包括文件头(File Header)和文件体(File Body)两部分,其中文件体由一系列的Tag及Tag Size对组成。
参考雷神图片
用UltraEdit打开FLV文件,如下图
文件头File Header
46 4C 56 01 05 00 00 00 09
头部分由一下几部分组成
Signature(3 Byte)+Version(1 Byte)+Flags(1 Bypte)+DataOffset(4 Byte)
- signature :占3个字节,固定FLV三个字符作为标示。
一般发现前三个字符为FLV时就认为他是flv文件。
图中0x46 0x4C 0x56,代表FLV。 - Version:占1个字节 标示FLV的版本号。这里我们看到是1。
- Flags:占1个字节 内容标示。
第0位和第2位,分别表示 video 与 audio 存在的情况.(1表示存在,0表示不存在)。
截图看到是0x05,也就是00000101,代表既有视频,也有音频。 - DataOffset:
4个字节 表示FLV的header长度。这里可以看到固定是9。
文件体File Body
FLV的body部分是一系列的back-pointers+tag构成的
back-pointers
固定4个字节,表示前一个tag的size。第一个back-pointers数据为0。tag
音视频数据,其中tag内部又分为flv_tag_header + video_header/audio_header+data,详见如下Tag详解部分。
Tag详解
Tag数据结构
Tag分为:
flv_tag_header + video_header/audio_header+data;
其中flv_tag_header占11个字节,video_header5个字节,audio_header2个字节,剩余为H264数据。
flv_tag_header如下:
长度11个字节,type+tag data size+Timestamp+TimestampExtended+stream id+ tag data
type 1个字节。
Tag分三种类型:
scripts0x12
18
audio0x08
8
video0x09
9tag data size 3个字节。
表示tag data的长度。从streamd id 后算起。Timestreamp 3个字节。
时间戳TimestampExtended 1个字节。
时间戳扩展字段stream id 3个字节。
总是0
video_header/audio_header
video_header,长度5个字节
4bit Frame Type,帧类型
4bit CodecID,视频编码类型
8 bit AVCPacketType,是sequence header(0)还是NALU(1)
24 bit CompositionTime,如果为NALU 则为时间间隔,否则为0audio_header,长度为2个字节
4bit 表示音频格式
第5、6bit 表示采样率
第7bit 表示采用的长度
第8bit 表示音频类型
8 bit AVCPacketType,是AAC sequence header(0)还是 AAC raw(1)
data 数据部分
为H264编码后帧数据
脚本Tag,script tag,18,0x12
脚本Tag一般只有一个,是flv的第一个Tag,用于存放flv的信息,比如duration、audiodatarate、creator、width等。
一般来说,该Tag Data结构包含两个AMF包。
AMF(Action Message Format)是Adobe设计的一种通用数据封装格式,在Adobe的很多产品中应用,简单来说,AMF将不同类型的数据用统一的格式来描述。第一个AMF包封装字符串类型数据
第1个字节表示AMF包类型,一般总是0x02,表示字符串,其他值表示意义请查阅文档。
第2-3个字节为UI16类型值,表示字符串的长度,一般总是0x000A(“onMetaData”长度)。
后面字节为字符串数据,一般总为“onMetaData”。第二个AMF包封装一个数组类型,这个数组中包含了音视频信息项的名称和值。
第1个字节表示AMF包类型,一般总是0x08,表示数组。
第2-5个字节为UI32类型值,表示数组元素的个数。
后面即为各数组元素的封装,数组元素为元素名称和值组成的对。表示方法如下:
第1-2个字节表示元素名称的长度,假设为L。
后面跟着为长度为L的字符串。
第L+3个字节表示元素值的类型。
后面跟着为对应值,占用字节数取决于值的类型。
脚本的数据类型。
所有数据都是以数据类型+(数据长度)+数据的格式出现的。
数据类型占1byte,数据长度看数据类型是否存在,后面才是数据。
值 | 类型 | 说明 |
---|---|---|
0 | Number type | 8 Bypte Double |
1 | Boolean type | 1 Bypte bool |
2 | String type | 后面2个字节为长度 |
3 | Object type | |
4 | MovieClip type | |
5 | Null type | |
6 | Undefined type | |
7 | Reference type | |
8 | ECMA array type | 数组,类似Map |
10 | Strict array type | |
11 | Date type | |
12 | Long String type | 后面4个字节为长度 |
视频Tag,FLV Video Tag,9,0x09
根据Tag Header读取VideoData数据后,videoData的部分分为 视频信息Video_Header+AVC_Video_Header+数据
video_header,长度5个字节:
4bit Frame Type,帧类型
4bit CodecID,视频编码类型
8 bit AVCPacketType,是sequence header(0)还是NALU(1)
24 bit CompositionTime,如果为NALU 则为时间间隔,否则为0视频信息,1字节
前4位表示帧类型Frame Type
后4位为编码ID (CodecID)
视频的格式(CodecID)是AVC(H.264)的话,VideoTagHeader会多出4个字节的信息,AVCPacketType和CompositionTime,所以是H264编码的情况下VideoHeader长度是5个字节。
AVCPacketType,1个字节
AVCDecoderConfigurationRecord
包含着是H.264解码相关比较重要的sps和pps信息,再给AVC解码器送数据流之前一定要把sps和pps信息送出,否则的话解码器不能正常解码。
而且在解码器stop之后再次start之前,如seek、快进快退状态切换等,都需要重新送一遍sps和pps的信息。
AVCDecoderConfigurationRecord在FLV文件中一般情况也是出现1次,也就是第一个video tag.CompositionTime,3个字节
sps pps
第一个video 一般存放的是sps和pps。
存储的格式:0x01+sps[1]+sps[2]+sps[3]+0xFF+0xE1+sps size+sps+01+pps size+pps
其中sps size和pps size各占两个字节,所以videoData部分长度是11个字节 + sps.length + pps.length;再加上videoHeader的5个字节。
音频Tag,FLV Audio Tag,8,0x08
根据Tag Header读取AudioData数据后,AudioData的部分分为 音频信息Audio_Header+AACPacketType+数据
audio_header,长度为2个字节
4bit 表示音频格式
第5、6bit 表示采样率
第7bit 表示采用的长度
第8bit 表示音频类型
8 bit AVCPacketType,是AAC sequence header(0)还是 AAC raw(1)音频信息,1字节
- 前4位表示音频格式
- 第5、6位表示采样率
- 第7位表示采用的长度
- 第8位表示音频类型
- 前4位表示音频格式
其中如果音频格式为10,即是AAC格式的,AudioTagHeader中会多出一个字节AACPacketType,这个字段来表示AACAUDIODATA的类型:0 = AAC sequence header,1 = AAC raw。
- AAC sequence header也就是包含了AudioSpecificConfig,AudioSpecificConfig包含着一些更加详细音频的信息,AudioSpecificConfig的定义在ISO14496-3中1.6.2.1 AudioSpecificConfig,这里就不详细贴了。而且在ffmpeg中有对AudioSpecificConfig解析的函数,ff_mpeg4audio_get_config(),可以对比的看一下,理解更深刻。
- AAC raw 这种包含的就是音频ES流了,也就是audio payload.
举个例子
拿个flv文件对照着看一看
FLV Header
46 4C 56 01 05 00 00 00 09
:
表示FLV Header ,音视频都有0x 00 00 00 00
第一个back-pointers(表示前一个tag的size)。他前面没有tag,所以是0。
脚本Tag
12 00 00 B6 00 00 00 00 00 00 00
0x12
表示这是一个scripts tag,00 00 B6
三个字节表示tag data长度为182个字节,Timestreamp、TimestampExtended、stream id 均为0。
下一个back-pointers,表示该整个tag的size,即182 + 11(tag data前面的长度) = 193 = 0xc1,即 00 00 00 c1
,在工具中查找即可。
02 00 0A 6F 6E 4D 65 65 74 61 44 61 74 61
表示第一个AMF包。
02表示类型为string type,后面两个字节00 00A 表示长度是10,值onMetaData。03 00 00 00 08
03表示ObjectType,此处应该一般是08才对,表示数组类型;表示有8个键值对。
接下来就是解析键值对了。解析键值对
0005表示键长度,77 69 64 74 68
表示width,00
表示类型为Number,后面8字节表示值。
0006表示键长度,68 65 69 67 68 74
表示height,00
表示类型为Number,后面8字节表示值。
以此类推解析到最后end marker 00 00 09
,表示解析完毕。
第一个videoTag,一般包含sps和pps
09 00 00 25 00 00 00 00 00 00 00
09表示视频Tag;
00 00 25表示长度为0x25=37;加上头部长度11,为48,下一个back-pointers是00 00 00 30
Timestreamp、TimestampExtended、stream id均为0;
接下来是数据部分tag data。如下图所示:
0x17
,即0b00010111
前4位表示帧类型,1表示为关键帧; 后4位表示编码ID,7表示是AVC。
视频格式是AVC(H.264)类型的话,后面1个字节表示AVCPacketType,再后三个字节表示CompositionTime。00
AVCPacketType为0,表示是AVCDecoderConfigurationRecord。就表示包含着sps和pps了。这个东西要第一个发给解码器,要不然不能正常解码。00 00 00
CompositionTime为0。接下来就是sps和pps的信息了。0x01+sps[1]+sps[2]+sps[3]+0xFF+0xE1+sps size+sps+01+pps size+pps
,对照着二进制看一下
sps[1] =42
sps[2] =80
sps[3] =20
sps size =00 11
,表示sps长度为17,17字节的sps数据读取完;读到01
pps size =00 04
,表示pps长度为4,
读取完后该tag结束。下一个back-pointers。
第一个audioTag,包含AAC sequence header
08 00 00 04 00 00 00 00 00 00 00
08表示音频;
00 00 04表示长度为4;加上头部长度11,为15,下一个back-pointers是00 00 00 0F
接下来是tag data。如下图所示:
AF
,即0b10101111
前4个字节为1010,十进制10,表示音频格式是AAC;10会多一个字节AACPacketType,表示该AACAUDIODATA的类型。
第5、6位为11,十进制3,表示采样率为44kHz;
第7位为1,表示16位采用;
第8位为1,表示stereo;
00
,表示AACPacketType,为0表示该Tag是AAC sequence header。
接下来两个字节表示AudioSpecificConfig,包含更加详细音频的信息。
读取完后该tag结束。下一个back-pointers。
之后的videoTag、videoTag
下一个video
长度为35525的视频数据,时间戳为23。
0x17
后一位AVCPacketType01
,表示NALU数据。三个CompositionTime字节过后,就是NALU数据了。
下一个audio
长度为1538的音频数据,时间戳为36;
0xAF
后一位AACPacketType为01
,表示ACC raw,即音频NALU数据。
总结
至此我们把FLV格式梳理了一遍,就能更好理解FLV部分代码了。
参考:
FLV视频封装格式详解
flv格式详解+实例剖析
将h.264视频流封装成flv格式文件
FLV(AAC/AVC)学习笔记
音视频 FLV格式解析相关推荐
- 音视频学习(四、FLV格式解析)
由于上一节使用到了rtmp推流,然后一直推一直出错,用rtmp推流的数据格式是FLV,所以这一节分析一下FLV的格式,补充补充知识. 4.1 FLV格式解析 4.1.1 FLV总体认识 FLV 是FL ...
- AVI音视频封装格式学习(三)——AVI 数据结构解析
这里介绍AVI会使用到的数据结构,为了避免翻译引入歧义,决定该部分还是使用英文原文,如后续有时间再进行翻译. AVIMAINHEADER structure The AVIMAINHEADER str ...
- 音视频封装格式、编码格式
音视频封装格式.编码格式 概述 常见的AVI.RMVB.MKV.ASF.WMV.MP4.3GP.FLV等文件其实只能算是一种封装标准. 一个完整的视频文件是由音频和视频2部分组成的.H264.Xvid ...
- 音视频封装格式、编码格式知识
常见的AVI.RMVB.MKV.ASF.WMV.MP4.3GP.FLV等文件其实只能算是一种封装标准. 一个完整的视频文件是由音频和视频2部分组成的.H264.Xvid等就是视频编码格式,MP3.AA ...
- AVI音视频封装格式学习(四)——linux系统C语言AVI格式音视频封装应用
拖了很久的AVI音视频封装实例,花了一天时间终于调完了,兼容性不是太好,但作为参考学习使用应该没有问题.RIFF和AVI以及WAV格式,可以参考前面的一些文章.这里详细介绍将一个H264视频流和一个2 ...
- AVI音视频封装格式学习(五)——h265与PCM合成AVI文件
不知道是处于版权收费问题还是什么原因,H265现在也并没有非常广泛的被普及.将h265数据合成AVI的资料现在在网上也基本上没有.使用格式化工厂工具将h265数据封装成AVI格式,发现它在封装的时候其 ...
- ffmpeg4.4项目学习--音视频基本格式
目录 一.引言 二.音视频基本格式学习 ------> 2.1.图像压缩数据格式 ------> 2.2.PCM ------> 2.3.H264 ------> 2.4.AA ...
- AVI音视频封装格式学习(二)——AVI RIFF文件参考
AVI RIFF文件参考 AVI RIFF File Reference 微软AVI文件格式是与捕获,编辑和播放音视频流的应用程序一起使用的RIFF文件规范.通常,AVI文件包含多个不同类型的数据流. ...
- 音视频FLV合成实战
FFmpeg合成流程 示例本程序会⽣成⼀个合成的⾳频和视频流,并将它们编码和封装输出到输出⽂件,输出格式是根据⽂件 扩展名⾃动猜测的. 示例的流程图如下所示. ffmpeg 的 Mux 主要分为 三步 ...
最新文章
- 每天学一点儿shell:Linux三剑客——grep命令
- controller怎么调用controller_SpringMVC五大核心组件及调用过程
- html css 知识回顾2
- microsoft excel正在等待其他某个应用程序_如何删除 Mac 储存空间的其他选项?
- 两个孤寡老人不领证同居在一起合适吗?
- java基础之URLDecoder异常解决方法
- python代码写龙卷风_python - 龙卷风服务器二进制可执行文件
- JavaScript字符统计出现次数
- react实现问卷调查
- 软件开发工具【五】 之 软件开发工具的使用与开发
- 判断有向图中是否存在从vi到vj的路径
- Django介绍,mvc设计模式及mvt设计模式介绍及对比
- 你应该知道的10种软件工具
- 驼峰命名法和下划线命名法互转
- 闪光网-彭亮《可以平凡》
- 齐博php百度编辑器上传图片_齐博CMS整合百度编辑器上传附件的BUG以及解决办法...
- 相机内参和相机外参和标定
- 毕业设计部分作品展示
- Nuke中的各类结点及使用方法
- PanDownload 一款好用的百度网盘下载工具 突破下载网速限制