MP4文件格式分析及分割实现(附源码)
2017-11-16 15:34
776 查看
MP4文件格式分析及分割实现(附源码)
MP4文件格式分析
MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在“ISO/IEC 14496-14”标准文件中定义的,属于MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base mediafile format)”标准中所定义的媒体格式的一种实现,后者定义了一种通用的媒体文件结构标准。MP4是一种描述较为全面的容器格式,被认为可以在其中嵌入任何形式的数据,各种编码的视频、音频等都不在话下,不过我们常见的大部分的MP4文件存放的AVC(H.264)或MPEG-4(Part 2)编码的视频和AAC编码的音频。MP4格式的官方文件后缀名是“.mp4”,还有其他的以mp4为基础进行的扩展或者是缩水版本的格式,包括:M4V,3GP,F4V等。
一个mp4文件有可能包含非常多的box(全部大约70多个),在很大程度上增加了解析的复杂性。如果要全部解析必要性不是很大。大部分mp4文件没有那么多的box类型,下图就是一个简化了的,常见的mp4文件结构:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170719135846005-1746376481.png)
下图是节点box详细说明:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170714145046728-232725374.png)
下面我们将对以上主要box的解析进行详细说明:
1.
一级box
一级box主要包含ftyp、moov、free、mdat等等。
1.1
ftyp box
结构:/******************************************************************************************** ** File Type Box (ftyp) ** -------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** major_brand | 4 | ** minor_version | 4 | 版本号 ** compatible_brands | 4 * N | 本文件遵从的多种协议(ismo, iso2, mp41) ********************************************************************************************/
运行结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170714150537728-569984141.png)
1.2 moov
box
结构:/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ********************************************************************************************/
1.3 free box
结构:
/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ********************************************************************************************/
1.4 mdat box
结构:
/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** | 后面全是真实数据 ********************************************************************************************/
运行结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170714151314165-1184118153.png)
2. 二级box
本节所说的二级box皆为moov的子box,主要包含mvhd、trak、udat等等。
2.1 mvhd box
结构:/************************************************************************************************************ ** mvhd ** -------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** version | 1 | box版本,0或1,一般为0(以下字节数均按version = 0) ** flags | 3 | ** creation time | 4 | 创建时间(相对于UTC时间1904 - 01 - 01零点的秒数) ** modification time | 4 | 修改时间 ** time scale | 4 | 文件媒体在1秒时间内的刻度值,可以理解为1秒长度的时间单元数 ** duration | 4 | 该track的时间长度,用duration和time scale值可以计算track时长 ** rate | 4 | 推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式.该值为1.0 (0x00010000) ** volume | 2 | 与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量 ** reserved | 10 | 保留位 ** matrix | 36 | 视频变换矩阵 ** pre-defined | 24 | ** next track id | 4 | 下一个track使用的id号 ************************************************************************************************************/
运行结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170718204331411-215399662.png)
2.2 trak box
结构:
/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ********************************************************************************************/
2.3 udat box
结构:
/************************************************************************************************************ ** udat ** -------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** | 用户自定义数据解析 ************************************************************************************************************/
运行结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170718213538490-607273759.png)
3. 三级box
本节所说的三级box皆为trak的子box,主要包含tkhd、mdia等。
3.1 tkhd box
结构:/************************************************************************************************************ ** tkhd ** ------------------------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 ------------------------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** version | 1 | box版本,0或1,一般为0。(以下字节数均按version = 0) ** flags | 3 | 按位或操作结果值,预定义如下; 0x000001 track_enabled,否则该track不被播放; 0x000002 track_in_movie,表示该track在播放中被引用; 0x000004 track_in_preview,表示该track在预览时被引用。 一般该值为7,如果一个媒体所有track均未设置track_in_movie和track_in_preview,将被理解为所有track均设置了这两项; 对于hint track,该值为0; ** creation_time | 4 | 创建时间(相对于UTC时间1904 - 01 - 01零点的秒数) ** modification_time | 4 | 修改时间 ** track_id | 4 | id号 不能重复且不能为0 ** reserved | 4 | 保留位 ** duration | 4 | track的时间长度 ** reserved | 8 | 保留位 ** layer | 2 | 视频层,默认为0,值小的在上层 ** alternate_group | 2 | track分组信息,默认为0表示该track未与其他track有群组关系 ** volume | 2 | [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;否则为0 ** reserved | 2 | 保留位 ** matrix | 36 | 视频变换矩阵 ** width | 4 | 宽 ** height | 4 | 高,均为[16.16] 格式值 与sample描述中的实际画面大小比值,用于播放时的展示宽高 ************************************************************************************************************/
运行结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170719142936615-1906247260.png)
3.2 mdia box
结构:
/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ********************************************************************************************/
4. 四级box
本节所说的四级box皆为mdia的子box,主要包含mdhd、hdlr、minf等。
4.1 mdhd box
结构:/************************************************************************************************************ ** tkhd ** ------------------------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 ------------------------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** version | 1 | box版本0或1 一般为0 (以下字节数均按version=0) ** flags | 3 | ** creation_time | 4 | 创建时间(相对于UTC时间1904 - 01 - 01零点的秒数) ** modification_time | 4 | 修改时间 ** time_scale | 4 | ** duration | 4 | track的时间长度 ** language | 2 | 媒体语言码,最高位为0 后面15位为3个字符[见ISO 639-2/T标准中定义] ** pre-defined | 2 | 保留位 ************************************************************************************************************/
结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170719144742411-1841800357.png)
4.2 hdlr box
结构:/************************************************************************************************************ ** hdlr ** ------------------------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 ------------------------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** version | 1 | box版本0或1 一般为0 (以下字节数均按version=0) ** flags | 3 | ** pre-defined | 4 | ** handler type | 4 | 在media box中,该值为4个字符 "vide"— video track "soun"— audio track "hint"— hint track ** reserved | 12 | ** name | 不定 | track type name,以‘\0’结尾的字符串 ************************************************************************************************************/
结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170719150233271-721045400.png)
4.3 minf box
结构:/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ********************************************************************************************/
5. 五级box
本节所说的五级box皆为minf的子box,主要包含header
box(vmhd/smhd/hmld/nmld)、stbl等。
5.1 header box
本处的headerbox会根据前面的handler type数值选择哪个box。 "vide"—vmhd 视频
"soun"— smhd 音频
"hint"—hmhd 忽略
vmhd结构:
/************************************************************************************************************ ** vmhd ** ------------------------------------------------------------------------------------------------------------- ** 字段名称 | 长度(bytes) | 有关描述 ------------------------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ** version | 1 | box版本0或1 一般为0 (以下字节数均按version=0) ** flags | 3 | ** graphics_mode | 4 | 视频合成模式,为0时拷贝原始图像,否则与opcolor进行合成 ** opcolor | 2 ×3 | {red,green,blue} ************************************************************************************************************/
结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170719151858755-561329904.png)
5.2 stbl box
结构:/******************************************************************************************** ** 字段名称 | 长度(bytes) | 有关描述 -------------------------------------------------------------------------------------------- ** boxsize | 4 | box的长度 ** boxtype | 4 | box的类型 ********************************************************************************************/
6. 六级box
本节所说的六级box皆为stbl的子box,主要包含stsd、stts、stsz、stsc、stss、stco等,这些也是mp4文件设计的精髓所在,主要控制chunk、sample、mdat之间的映射关系。
6.1 stsd box
stsd: Sample Description Box,解析stsd可获得coding类型、视频宽高、音频samplesize、channelcount这些和解码器有关信息。![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170720191759911-1780775432.png)
6.2 stts box
stts: Decoding Time to Sample Box,时间戳和Sample映射表![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170720192010396-1449570870.png)
上图是一个video trak,说明该视频包含87帧数据,每帧包含512个采样。
总共512*87=44544个采样,和我们前面mdhd box的Duration完全一致。
Duration / TimeScale = 44544 / 12288 = 3.625秒 正是我们的视频播放长度。
12288 / 512 = 24 p/s (帧率)。
6.3 stsz box
stsz, stz2: Sample Size Boxes,每个Sample大小的表![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170720195659474-1927436027.png)
一共87帧 每帧的字节大小。
6.4 stsc box
stsc: Sample to chunk 的映射表。![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170720201645990-191548870.png)
前面说了一共87帧数据,放在83个chunk中。1~82个chunk每个里面放1帧,第83个chunk放了5帧。
6.5 stss box
stss: 关键帧索引表。![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170720202131755-1503601782.png)
第1、13、25、37、49、61、73、85.... 这些帧都是关键帧。
每12帧就有一个关键帧, 前面我们计算得知fps是24。由此可知该视频关键帧间隔为0.5秒。
6.6 stco box
'stco','co64': Chunk位置偏移表![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170720202507849-399968312.png)
一共83个chunk,记录在mdat真实数据中的字节偏移量。
下图为第三方MP4文件解析结果:
![](http://images2015.cnblogs.com/blog/693621/201707/693621-20170714165054915-515273568.png)
MP4文件格式解析源码:https://github.com/kingsunc/AVFileParse
搞清楚stbl的映射关系后 我们就可以进行MP4文件的分割实现(也就是所谓的点播拖动)。
MP4分割实现源码:https://github.com/kingsunc/AVFileParse/tree/master/Mp4_Segment
相关文章推荐
- MP4文件格式分析及分割实现(附源码)
- 第二人生的源码分析(六十二)类Easy实现多协议文件传送
- 位图文件(BMP)格式分析以及程序实现
- mp4(H264容器)的详细文件格式分析
- Wireshark的Pcap文件格式分析及解析源码(转)
- 传奇源码分析-客户端(传奇2文件格式分析)
- 第二人生的源码分析(六十二)类Easy实现多协议文件传送
- Wireshark的Pcap文件格式分析及解析源码【转】
- 怎么分割ape文件(cue格式分析)_XLosslessDecoder
- mp4(H264容器)的详细文件格式分析
- 怎么分割ape文件(cue格式分析)_XLosslessDecoder
- MP4文件格式的解析,以及MP4文件的分割算法
- 位图文件(BMP)格式分析以及程序实现
- MP4文件格式的解析,以及MP4文件的分割算法
- mp4(H264容器)的详细文件格式分析 转自:http://blog.csdn.net/szu030606/article/details/5943279
- 传奇源码分析-客户端(WindHorn简述和传奇文件格式分析)
- 传奇源码分析-客户端(传奇2和3 文件格式分析比较)
- 第二人生的源码分析(六十二)类Easy实现多协议文件传送
- 位图文件(BMP)格式分析以及程序实现
- 传奇源码分析-客户端(WindHorn简述和传奇文件格式分析)