43.FFmpeg学习笔记 - flv格式解析
一、flv文件结构
flv文件由flv header 和flv body组成。
二、flv header
Header 部分记录了FLV的类型、版本、流信息、Header 长度等。一般整个Header占用9个字节,大于9个字节则表示头部信息在这基础之上还存在扩展数据。Header 的头部信息排布如下所示:
三、flv body
Body 是由一个个Tag组成的,每个Tag下面有一块4个字节的空间,用来记录这个Tag 的长度。这个后置的PreviousTagSize用于逆向读取处理,表示的是前面的Tag的大小,对于FLV版本0x01来说,数值等于 11 + Tag的DataSize(tag header总是11个字节)。其结构排布如下:
1.tag
每个Tag 也是由两部分组成的:Tag Header 和 Tag Data。Tag Header 存放了当前Tag的类型,数据长度、时间戳、时间戳扩展、StreamsID等信息,然后再接着数据区Tag Data。
2.tag header
tag header的排布如下:
3.tag data
Tag Data分成 Audio,Video,Script 三种。
1)Audio Tag Data
音频的Tag Data又分为 Audio Tag Header 和 Data 数据区,其排布结构如下图所示:
AudioTagHeader通常占用1个字节,AAC编码则会多出一个AACPacketType的字节,用于表示AAC的序列头还是裸数据。
其中,前4bits表示SoundFormat,其数值对应声音格式,如下:
0 - Linear PCM, platform endian
1 - ADPCM
2 - MP3
3 - LinearPCM,little endian
4 - Nellymoser 16-kHz mono
5 - Nellymoser 8-kHZ mono
6 - Nellymoser
7 - G.711 A-law logarithmic PCM
8 - G.711 U-law logarithmic PCM
9 - reserved
10 - AAC
11 - Speex
14 - MP3 8-kHz
15 - Device-specific sound
第5、6bit 表示SoundRate,数值对应采样率,对于AAC来说,总是3:
0 - 5.5kHz
1 - 11kHz
2 - 22kHz
3 - 44kHz
第7bit 表示采样大小:
0 - snd 8 bit
1 - snd 16 bit
第8bit 表示音频声道数,对于AAC来说,总是1:
0 - sndMono
1 - sndStereo
audio Data数据区,根据SoundFormat的数值来确定,如果SoundFormat = 10,则Data数据区是AAC编码部分,其他声音类型,则根据具体格式进行解析。
针对AAC编码,音频Data数据区的定义如下:
AACPacketType = 0 时,表示AAC序列头,也就是AudioSpecificConfig, AACPacketType = 1 时,表示AAC的裸流,也就是AAC Raw frame data。
AudioSpecificConfig 只出现在第一个Audio Tag中,结构如下:
AudioSpecificConfig() { audioObjectType; 5bitssamplingFrequencyIndex; 4bitsif ( samplingFrequencyIndex == 0xf ) {samplingFrequency; 24bits}channelConfiguration; 4bitssbrPresentFlag = -1;if ( audioObjectType == 5 ) {extensionAudioObjectType = audioObjectType;sbrPresentFlag = 1;extensionSamplingFrequencyIndex; 4bitsif ( extensionSamplingFrequencyIndex == 0xf ) {extensionSamplingFrequency; 24bits}audioObjectType; 5bits} else {extensionAudioObjectType = 0;}if ( audioObjectType == 1 || audioObjectType == 2 ||audioObjectType == 3 || audioObjectType == 4 ||audioObjectType == 6 || audioObjectType == 7 ) {GASpecificConfig();}if ( audioObjectType == 8 ) {CelpSpecificConfig();}if ( audioObjectType == 9 ) {HvxcSpecificConfig();}if ( audioObjectType == 12 ) {TTSSpecificConfig();}if ( audioObjectType == 13 || audioObjectType == 14 ||audioObjectType == 15 || audioObjectType == 16 ) {StructureAudioSpecificConfig();}if ( audioObjectType == 17 || audioObjectType == 19 ||audioObjectType == 20 || audioObjectType == 21 ||audioObjectType == 22 || audioObjectType == 23 ) {GASpecificConfig();}if ( audioObjectType == 24 ) {ErrorResilientCelpSpecificConfig();}if ( audioObjectType == 25 ) {ErrorResilientHvxcSpecificConfig();}if ( audioObjectType == 26 || audioObjectType == 27 ) {ParametricSpecificConfig();}if ( audioObjectType == 17 || audioObjectType == 19 ||audioObjectType == 20 || audioObjectType == 21 ||audioObjectType == 22 || audioObjectType == 23 ||audioObjectType == 24 || audioObjectType == 25 ||audioObjectType == 26 || audioObjectType == 27 ) {epConfig; 2bitsif ( epConfig == 2 || epConfig == 3 ) {ErrorProtectionSpecificConfig();}if ( epConfig == 3 ) {directMapping; 1bitif ( ! directMapping ) {/* tbd */}}}if ( audioObjectType == 28 ) {SSCSpecificConfig();}if ( extensionAudioObjectType != 5 && bits_to_decode() >= 16 ) { syncExtensionType; 11bitsif ( syncExtensionType == 0x2b7 ) {extensionAudioObjectType; 5bitsif ( extensionAudioObjectType == 5 ) {sbrPresentFlag; 1bitif ( sbrPresentFlag == 1 ) {extensionSamplingFrequencyIndex; 4bitsif ( extensionSamplingFrequencyIndex == 0xf ) {extensionSamplingFrequency; 24bits}}}}}
}
AudioSpecificConfig 简化格式如下:
audioObjectType 5bits 编码结构类型,AAC-LC为2
samplingFreguencyIndex 4bits 音频采样率索引值
channelConfiguration 4bits 音频声道数
GASpecificConfigframeLengthFlag 1bits 标志位,用于表明IMDCT窗口长度,为0dependsOnCoreCoder 1bits 标志位,用于表明是否依赖corecoder,为0extensionFlag 1bits 扩展标志位,选择了AAC-LC,这里必须为0
其中,samplingFreguencyIndex 对应关系如下:
0 - 96000
1 - 88200
2 - 64000
3 - 48000
4 - 44100
5 - 32000
6 - 24000
7 - 22050
8 - 16000
9 - 12000
10 - 11025
11 - 8000
12 - 7350
13 - Reserved
14 - Reserved
15 - frequency is written explictly
AAC裸流AAC Raw frame data,即AAC音频原始数据,不包括AAC头数据ADTS。
如果是MP3 编码部分,audio 数据区直接为 MP3 头 + MP3 原始数据。
2)Video Tag Data
Video Tag 由一个字节的Video Tag Header 和 Video数据区部分组成。
Video Tag Header
Video Tag Header通常由一个字节构成,前4bit表示类型,后4bit表示编码器Id。
Video Tag Data
Video数据区部分格式不确定。对于H264/AVC编码部分,Video数据区排布如下:
其中,AVCsequenceheader只有出现在第一个Video Tag,只有一个。为了能够从FLV中获取NALU,必须知道前面的NALU长度所占的字节数,通常是1、2、4个字节,这个内容则必须从AVCDecoderConfigurationRecord中获取,这个遵从标准ISO/IEC 14496-15的5.2.4小节。AVCDecoderConfigurationRecord 的结构如下:
aligned(8) class AVCDecoderConfigurationRecord {unsigned int(8) configurationVersion = 1; //版本号unsigned int(8) AVCProfileIndication; //sps[1],即0x67后面那个字节unsigned int(8) profile_compatibility; //sps[2]unsigned int(8) AVCLevelIndication; //sps[3]bit(6) reserved = '111111'b;unsigned int(2) lengthSizeMinusOne; //NALUnitLength的长度减1,一般为3 bit(3) reserved = '111'b;unsigned int(5) numOfSequenceParameterSets; //sps个数,一般为1for ( i=0; i<numOfSequenceParameterSets; i++ ) {unsigned int(16) sequenceParameterSetLength; //sps的长度 bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;}unsigned int(8) numOfPictureParameterSets; //pps个数,一般为1for ( i=0; i<numOfPictureParameterSets; i++) {unsigned int(16) pictureParameterSetLength; //pps长度 bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;}
}
其中,lengthSizeMinusOne + 1 = NALU长度字段所占字节数。
3)Script Tag Data
当TagType = 0x12时, 这个Tag就是Script tag。Script Tag一般只有一个,是FLV文件的第一个Tag,用于存放FLV文件信息,比如时长、分辨率、音频采样率等。所有的数据都是以数据类型 + (数据长度) + 数据格式出现,数据类型占1个字节,数据长度看数据类型是否存在,后面才是数据。数据排布如下:
其中SCRIPTDATAOBJECTEND和SCRIPTDATAVARIABLEEND为0x000009,用于标记对象和数组类型的结尾。
SCRIPTDATASTRING结构为:
StringLength 2bytes
StringData String
SCRIPTDATALONGSTRING结构为:
StringLength 4bytes
StringData String
ECMA array type结构为:
ECMAArrayLength 4bytes
StringLength 2bytes
StringData String
DataType 1byte
Data 不定长
SCRIPTDATAVARIABLEEND
Object type结构为:
StringLength 2bytes
StringData String
DataType 1byte
DataVale 不定长
SCRIPTDATAOBJECTEND
Strict array type结构为:
ArrayNum 4bytes
DataType byte
DataValue 不定长
如果类型为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标签中包含的是流的信息,一般的信息包括:
43.FFmpeg学习笔记 - flv格式解析相关推荐
- 音视频学习(四、FLV格式解析)
由于上一节使用到了rtmp推流,然后一直推一直出错,用rtmp推流的数据格式是FLV,所以这一节分析一下FLV的格式,补充补充知识. 4.1 FLV格式解析 4.1.1 FLV总体认识 FLV 是FL ...
- 音视频 FLV格式解析
前言 本文介绍FLV封装格式,直播场景下拉流比较常见的是http-flv直播流,具有延时低.易传输等特点. 格式概览 总体上看,FLV包括文件头(File Header)和文件体(File Body) ...
- <四>关于flv格式解析
关于ffmpeg这里插入一个章节-----关于flv格式的解析,因为在ffmpeg推流的过程中,最流行的就是将数据封装成flv格式,通过rtmp传输,所以搞明白flv的格式构成是十分有必要的,我可能会 ...
- FFmpeg学习笔记汇总
第1章 FFmpeg简介 1.1 FFmpeg定义 FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件,作为编解码开发套件,它为开发者提供了丰富的音视频处理的调用接口. FFmpe ...
- Python3 爬虫学习笔记 C08【解析库 Beautiful Soup】
Python3 爬虫学习笔记第八章 -- [解析库 Beautiful Soup] 文章目录 [8.1]关于 Beautiful Soup [8.2]Beautiful Soup 的基本使用 [8.3 ...
- Python3 爬虫学习笔记 C07 【解析库 lxml】
Python3 爬虫学习笔记第七章 -- [解析库 lxml] 文章目录 [7.1]关于 lxml [7.2]使用 XPath [7.3]查找所有节点 [7.4]查找子节点 [7.5]查找父节点 [7 ...
- 安卓学习笔记30:解析XML与JSON
文章目录 零.学习目标 一.解析XML (一)XML概述 (二)解析XML的方法 二.案例演示 - 读取解析XML (一)运行效果 (二)涉及知识点 (三)实现步骤 1.创建安卓应用[ReadPars ...
- CanOpen协议栈学习笔记1-帧格式,SYNC和NMT报文介绍
前面已经记录过can协议,后面开始CanOpen协议栈学习.其实协议栈代码已经看过了,而且已经在开发板上跑过了.这里回过头来,重新看下之前遇到的坑,记录下学习笔记.下面均以标准帧为例 文章目录 1.C ...
- CoAP学习笔记——CoAP格式详解
0 前言 CoAP是受限制的应用协议(Constrained Application Protocol)的代名词.在当前由PC机组成的世界,信息交换是通过TCP和应用层协议HTTP实现的.但是对于小型 ...
最新文章
- Java类加载机制详解【java面试题】
- 电容触摸屏GT911、GT928、GT9147的使用
- Visual Tracking:运行ECO模型的GPU版本
- Android开发中常见的设计模式
- Linux学习笔记-文件压缩与解压缩
- 微信10个实用技巧,值得收藏!
- mysql 不要统计null_浅谈为什么Mysql数据库尽量避免NULL
- 串口发送图片VGA显示
- 常用的限流框架都在这里了!
- 莫烦 Tensorflow
- wps纸张大小设置成A4_pdf两页合并一页a4,只需这招轻松搞定
- WMI服务是什么?Windows 7系统如何禁用WMI服务?
- powershell为所有用户卸载磁贴应用
- 网站建设:网站安全检测工具
- Qt Creator-设置代码的背景色和字体
- 最小值c语言编写自定义函数,C语言笔记55:自定义函数[老九学堂]
- jQuery打字练习小游戏代码带音效
- 从数据架构看生鲜电商的数据价值
- 计算机网络的产生与发展
- NTU-Coursera机器学习:VC Bound和VC维度