【MP4】mp4文件详解(一)—— 一文看懂mp4文件格式

【MP4】mp4文件详解(一)—— 一文看懂mp4文件格式本系列系统总结 MP4 文件格式 从格式详解 MP4 分析工具 MP4 开源库解析等几篇文章来进行系统性总结和梳理

大家好,欢迎来到IT知识分享网。

<> 博客简介:Linux、rtos系统,arm、stm32等芯片,嵌入式高级工程师、面试官、架构师,日常技术干货、个人总结、职场经验分享

<> 公众号:嵌入式技术部落

<> 系列专栏:C/C++、Linux、rtos、嵌入式开发、流媒体、数据结构、网络协议、开源库、CMake、Makefile、架构设计模式等



一、前言

本系列系统总结MP4文件格式,从格式详解、MP4分析工具、MP4开源库解析等几篇文章来进行系统性总结和梳理。如有错漏,敬请指出,欢迎随时交流。

二、mp4 文件格式简介

mp4文件格式又被称为MPEG-4 Part 14,出自MPEG-4标准第14部分 。它是一种多媒体格式容器,广泛用于包装视频和音频数据流、海报、字幕等。(顺便一提,目前流行的视频编码格式AVC/H264定义在MPEG-4 Part 10)。

MP4是最常见的封装格式之一,因为其跨平台的特性而得到广泛应用。MP4文件的后缀为.mp4,基本上主流的播放器、浏览器都支持MP4格式。

三、mp4 文件三种组织方式

1. 普通 MP4(General MP4)

组织方式: ftyp-mdat-moov

特点: box的顺序是 ftyp(文件类型)在开头,mdat(媒体数据)紧接其后,最后是 moov(元数据)。 在播放视频时,由于 moov box位于文件尾部,需要在文件完全下载后才能开始播放。

适用场景: 适用于本地存储和播放场景,例如在存储于硬盘或 USB 设备上的视频文件。 不适合流媒体或点播服务,因为需要在传输完所有数据后才能解码播放。



2. 快速 MP4(Faststart MP4)

组织方式: ftyp-moov-mdat

特点: box的顺序是 ftyp(文件类型)在开头,紧接其后的是 moov(元数据),最后才是 mdat(媒体数据)。 这种配置方式允许视频播放器在下载文件的初期就可以访问到 moov box,从而提前开始播放,提供更快的启动时间。

适用场景: 适用于需要更快启动时间的场景,如网络流媒体和点播服务。 可以在视频文件尚未完全下载的情况下就开始播放,提升用户体验。



3. 切片 MP4 或 fMP4(Fragmented MP4)

组织方式: ftyp-moov-moof-mdat

特点: 多个 moof 和 mdat 片段存在于文件中,每个片段包括它自己的元数据和媒体数据。 支持动态打包和传输,适合流媒体传输。 允许在各种网络条件下实现更灵活的文件下载和播放。

适用场景: 主要用于自适应流媒体传输。 适合需要频繁切换码率和分辨率的网络环境,例如移动网络。 提供更加平滑和连续的播放体验,适应不同带宽和播放条件。



联系

四、mp4 文件格式概览

ftyp:File Type Box,描述文件遵从的MP4规范与版本,有且只有一个,一般在文件的开始位置。
moov:Movie Box,媒体数据的metadata信息,有且仅有一个,一般位于ftyp之后,也有的视频moov放在文件末尾。注意,当改变moov位置时,内部一些值需要重新计算。
mdat:Media Data Box,存放实际的媒体数据,可以有多个。

metadata(元数据)是关于数据的数据。换句话说,元数据是描述其他数据的结构化信息。它提供了有关某些数据的信息,这些信息可以包括数据的来源、时间、作者、格式、使用权限等。元数据有助于组织、查找、理解和管理数据。

五、mp4 box解析

box的组成

box由header和body组成。

header:包含了整个box的长度size和类型type。

  • size:整个box长度,占4个字节(32位)。
    当size==0时,代表这是文件中最后一个Box,通常包含在mdat box中;
    当size==1时,意味着box长度需要更多bits来描述,在后面会定义一个64bits的largesize描述box的长度 (一般只有装载媒体数据的mdat box会用到largesize);

  • type:box类型,包括 “预定义类型”、“自定义扩展类型”,占4个字节(32位)。
    预定义类型:比如ftyp、moov、mdat等预定义好的类型;
    自定义扩展类型:当type是uuid时,代表box中的数据是用户自定义扩展类型,size (或largesize)随后的16字节,为自定义类型的值 (extended_type);

  • 在部分box header中,还存在version、flags字段,这样的box叫做Full Box。相比Box,FullBox 多了 version、flags 字段。version:当前box的版本,为扩展做准备,占1个字节;flags:标志位,占24位,含义由具体的box自己定义。

body:是box的实际数据,可以是纯数据也可以是更多的子box。

  • body根据类型有不同的意义和格式。
  • 当box body中嵌套其他box时,这样的box叫做container box。

ftyp (File Type Box)

File Type Box,一般在文件的开始位置,描述文件的版本、兼容协议等。

“ftyp” body依次包括1个32位的major brand(4个字符),1个32位的minor version(整数)和1个以32位(4个字符)为单位元素的数组compatible brands。这些都是用来指示文件应用级别的信息。

“ftyp” 结构如下表

字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

major brand 4 推荐兼容性的版本
minor version 4 最低兼容性的版本
compatible brands[] 4 所有的兼容性的版本

mdat (Media Data Box)

存放具体的媒体数据。音视频数据的编解码信息都在其它box中保存,解析的时候先读取其它box的信息获取编解码信息以及音视频数据在mdat中的位置,然后再读取mdat获取音视频数据。

mdat的位置比较灵活,可以位于moov之前,也可以位于moov之后,但必须和stbl中的信息保持一致。

free (Free Space Box)

free box 是可选的,如果存在,则通常出现在moov与mdat之间。

free中的数据通常为全0,其作用相当于占位符,其内容是无关紧要的,可以被忽略。该box被删除后,不会对播放产生任何影响。

在实时拍摄视频,moov数据增多时,将free分配给moov使用。因为设备录制视频时并不能预先知道视频数据大小,如果moov在mdat之前,随着拍摄mdat的数据会增加,moov数据也会增多,如果没有free预留的空间,则要不停的向后移动mdat数据以腾出moov空间。

moov (Movie Box)

Movie Box包含了mp4文件媒体数据的metadata信息,“moov”是一个container box,具体内容信息由子box诠释。Movie Box,包含本文件中所有媒体数据的宏观描述信息以及每路媒体轨道的具体信息。”moov”⼀般位于放在⽂件末尾,但如果为了⽀持http边下载边播放则需要将moov提前。注意,当改变moov位置时,内部⼀些值需要重新计算。

一般情况下(限于篇幅,本文只讲解常见的MP4文件结构),“moov”中会包含1个”mvhd”和若干个”trak”。其中”mvhd”为Movie Header Box,记录mp4文件的整体信息,比如创建时间、文件时长等,一般作为“moov”的第一个子box出现(对于其他container box来说,header box都应作为首个子box出现)。“trak”为Track Box,是一个container box,一个mp4可以包含一个或多个轨道(比如视频轨道、音频轨道),轨道相关的信息就在trak里。

mvhd (Movie Header Box)

Movie Header Box,记录整个mp4媒体文件的描述信息,如创建时间、修改时间、时间度量标尺、可播放时长等。

“mvhd”结构如下表。

字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
creation_time 4 创建时间(相对于UTC时间1904-01-01零点的秒数)
modification_time 4 修改时间
timescale 4 表示时间粒度,如果是1000,表示1秒被分成1000个粒度,用于下面的duration计算
duration 4 媒体文件的总时长,该值需要除以timescale,转换成真正的秒数。例如:timescale = 1000, duration = 5000 ,则媒体文件的总时长为5秒
rate 4 推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式,该值为1.0(0x00010000)表示正常前向播放
volume 2 与rate类似,[8,8]格式,前8位表示整数,后8位表示浮点数,0x0100 = 1.0,最大音量播放
reserved 8 保留位
matrix 36 视频变换矩阵
pre-defined 24
next_track_id 4 下一个track使用的id号,当在mp4中需要新插入一个track时,这个track的id

udta (User Data Box)

用户自定义数据。

trak (Track Box)

“trak”是一个container box,其子box包含了该track (轨道) 的媒体数据引用和描述 (hint track除外)。

一个MP4文件可以包含多个track (比如视频轨道、音频轨道),且至少有一个track,这些track之间彼此独立,有自己的时间和空间信息,track (轨道) 的相关的信息就在trak里。

“trak”必须包含一个”tkhd”和一个”mdia”,此外还有很多可选的box(略)。其中”tkhd”为track header box。“mdia”为media box,该box是一个包含一些track媒体数据信息box的container box。 我们只分析必的”tkhd”,“mdia”,至于其他例如”edts”有兴趣的同学可以自行了解。

tkhd (Track Header Box)

Track Header Box,包含关于媒体流的头信息。

“tkhd”结构如下表。

字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

version 1 box版本,0或1,一般为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 8/4 创建时间(相对于UTC时间1904-01-01零点的秒数),当version=0时字节数是4
modification_time 8/4 修改时间,当version=0时字节数是4
track_id 4 id号,不能重复且不能为0
reserved 4 保留位
duration 8/4 track的时间长度,单位采用的是mvhd box下的timescale,,当version=0时字节数是4
reserved 8 保留位
layer 2 视频层,默认为0,值小的在上层
alternate_group 2 track分组信息,默认为0表示该track不与其他任何track相关
volume 2 [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;视频track为0[0000]
reserved 2 保留位
matrix 36 视频变换矩阵
width 4 视频的宽;音频track为0
height 4 视频的高【16.16】的格式存储;音频track为0

edts(edit Box)

不是所有的 MP4文件有这个 Box,子Box为elst(Edit List Box),它的作用是使某个track的时间戳产生偏移。

mdia (Media Box)

“mdia”也是个container box,其子box的结构和种类还是比较复杂的。先来看一个“mdia”的实例结构树图。

在这里插入图片描述

在代表一流音频或视频流的track中,除tkhd外,主要的媒体配置信息在mdia中保存。描述了这条音视频轨/流(trak)的媒体数据样本的主要信息,对播放器来说是一个很重要的box。

mdhd (Media Header Box)

Media Header Box,存放视频流创建时间,⻓度等信息。

“mdhd”结构如下表。

字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
creation_time 4 创建时间(相对于UTC时间1904-01-01零点的秒数)
modification_time 4 修改时间
timescale 4 同前表
duration 4 track的时间长度
language 2 媒体语言码。最高位为0,后面15位为3个字符(见ISO 639-2/T标准中定义)
pre-defined 2
hdlr (Handler Reference Box)

Handler Reference Box,解释了媒体的播放过程信息,包含了 track 的类型信息,主要是有字段handler_type区分。

“hdlr”结构如下表。

字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
handler_type 4 在media box中,该值为4个字符:
“vide”— video track
“soun”— audio track
“hint”— hint track


reserved 12
name 不定 track type name,以‘\0’结尾的字符串
minf (Media Information Box)

minf box 顾名思义,是专门用来描述当前track下媒体数据的box,它是一个container box,其内容由其子box来表达。

vmhd (Video Media Header Box)
字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
graphicsmode 4 视频合成模式,为0时拷贝原始图像,否则与opcolor进行合成
opcolor 2×3 {red,green,blue}
smhd (Sound Media Header Box)
字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
balance 2 立体声平衡,[8.8] 格式值,一般为0,-1.0表示全部左声道,1.0表示全部右声道
reserved 2
hmhd (Hint Media Header Box)
nmhd (Null Media Header Box)

非视音频媒体使用该box,略。

dinf (Data Information Box)

“dinf”用于存储关于数据引用的信息,具体来说,它包含了一个或多个描述如何访问该媒体数据的具体信息。dinf对于运行时获取和解析数据位置信息是至关重要的。dinf是一个container box。dinf 一般包含一个dref,即data reference box。dref下会包含一个或多个url或urn,这些box组成一个表,用来定位track数据。

一个track的媒体数据可以被分成若干段,每一段都可以根据url或urn指向的地址来获取数据,sample描述中会用这些片段的序号将这些片段组成一个完整的track,一般情况下,当数据被完全包含在文件中时,url或urn中的定位字符串是空的。

“dref”的字节结构如下表。

字段 字节数 意义
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 box版本,0或1,一般为0。(以下字节数均按version=0)
entry count 4 “url”或”urn”表的元素个数
“url”或”urn”列表 不定

“url”或“urn”都是box,“url”的内容为字符串(location string),“urn”的内容为一对字符串(name string and location string)。当“url”或“urn”的box flag为1时,字符串均为空。

stbl (Sample Table Box)

“stbl”是一个container box,其子box包括:sample description box(stsd)、time to sample box(stts)、sample size box(stsz或stz2)、sample to chunk box(stsc)、chunk offset box(stco或co64)、composition time to sample box(ctts)、sync sample box(stss)等。

下面是这几个box概要的介绍:

  • stsd:sample description box,样本的描述信息,存储了编码类型和初始化解码器需要的信息,并与具体编解码器类型有关。给出视频、音频的编码、宽高、音量等信息,以及每个sample中包含多少个frame。
  • stco/co64:chunk offset box,chunk在文件中的偏移;
  • stsc:sample to chunk box,sample-chunk映射表,每个chunk中包含几个sample;
  • stsz/stz2:sample size box,每个sample的size(单位是字节);
  • stts:time to sample box,存储了该 track 每个 sample 到 dts 的时间映射关系。
  • stss:sync sample box,针对视频,关键帧的序号;
  • ctts:composition time to sample box,sample的CTS与DTS的时间差的压缩表;
stsd (Sample Description Box)

Sample Description Box,存储了编码类型和初始化解码器需要的信息,视频的编码类型、宽高、长度,音频的声道、采样等信息都会出现在这个box中。

stsd的内容和track的类型有关,也就是和hdlr的handler_type参数有关。

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 取 0 或 1,一般取 0
entry_count 4 entry 个数
开始循环
AudioSampleEntry() 不定大小 子 box,当 handler_type=‘soun’ 时才有
VisualSampleEntry() 不定大小 子 box,当 handler_type=‘vide’ 时才有
HintSampleEntry() 不定大小 子 box,当 handler_type=‘hint’ 时才有
MetadataSampleEntry() 不定大小 子 box,当 handler_type=‘meta’ 时才有
结束循环

version字段后会有一个entry count字段,根据entry的个数,每个entry会有type信息,如“vide”、“sund”等,根据type不同sample description会提供不同的信息,例如对于video track,会有“VisualSampleEntry”类型信息,对于audio track会有“AudioSampleEntry”类型信息。

video track的stsd body内容(不同的编码方式,stsd的子box的名称会有不同,但是box中的字段都是相同的):

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”。预定义类型:比如ftyp、moov、mdat等预定义好的类型;自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)
data_reference_index 2 当MP4文件的数据部分,可以被分割成多个片段,每一段对应一个索引,并分别通过URL地址来获取,此时,data_reference_index 指向对应的片段(比较少用到)
width 2 视频的宽,单位是像素
height 2 视频的高,单位是像素
horizresolution 4 水平方向的分辨率(像素/英寸),默认是0x00(72dpi)
vertresolution 4 垂直方向的分辨率(像素/英寸),默认是0x00(72dpi)
frame_count 2 一个sample中包含多少个frame,对video track来说,默认是1
compressorname 32 仅供参考的名字,通常用于展示,占32个字节,比如 AVC Coding。第一个字节,表示这个名字实际要占用N个字节的长度。第2到第N+1个字节,存储这个名字。第N+2到32个字节为填充字节。compressorname 可以设置为0
depth 2 位图的深度信息,比如 0x0018(24),表示不带alpha通道的图片
字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”。预定义类型:比如ftyp、moov、mdat等预定义好的类型;自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)
data_reference_index 2 当MP4文件的数据部分,可以被分割成多个片段,每一段对应一个索引,并分别通过URL地址来获取,此时,data_reference_index 指向对应的片段(比较少用到)
channel_count 声道数,取值为1或2
samplesize 采样位宽,一般为8bit或16bit
samplerate 采样率
stts (Time To Sample Box)

“stts”记录着该sample到下一个sample的DTS间隔,存储了sample的duration,包含了DTS到sample number的映射表,主要用来推导每个帧的时长,描述了sample时序的映射方法,我们通过它可 以找到任何时间的sample。

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 取 0 或 1,一般取 0
entry_count 4 条目个数
开始循环
sample_count 4 单个entry中,具有相同时长(duration 或 sample_delta)的连续sample的个数
sample_delta 4 单个 sample 的播放时长,单位为 timescale,也可以说是相邻两个sample之间dts的差值
结束循环
stss (Sync Sample Box)
字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 取 0 或 1,一般取 0
entry_count 4 条目个数
开始循环
sample_number 4 sample 计数,从 1 开始
结束循环
ctts(Composition Time to Sample Box)
字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

version 1 取 0 或 1,一般取 0
flags 3
sample_counts 4 单个entry中,具有相同差值(pts-dts)的连续sample的个数
sample_offsets 4 从解码(dts)到渲染(pts)之间的差值
stsc (Sample To Chunk Box)

stsc中用一个表描述sample与chunk映射表,每个chunk中包含几个sample,查看这张表就可以找到包含指定sample的chunk,从而找到这个sample。

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3
version 1 取 0 或 1,一般取 0
entry_count 4 表项个数
first_chunk 4 当前表项中,对应的第一个chunk的序号
samples_per_chunk 4 同一个entry中每个chunk包含的sample数
sample_description_index 4 chunk使用的stsd的序号,即不同chunk可以使用不同编解码信息

序号1的chunk,包含6个sample。序号2的chunk,包含1个sample。序号3~6的chunk,每个chunk包含2个sample。序号7的chunk,包含1个sample。

以上所有chunk中的sample,对应的sample description的序号都是1,也就是用第一个stsd。

stsz/stz2 (Sample Size Box)

“stsz” 定义了每个sample的大小,包含了媒体中全部sample的数目和一张给出每个sample大小的表。这个box相对来说体积是比较大的。

有两种不同的box类型:stsz、stz2

stsz结构如下:

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3 无实际意义(官方文档也没有介绍)
version 1 当前box版本,为扩展做准备,取 0 或 1,一般取 0
sample_size 4 默认的sample大小(单位是byte),通常为0。如果sample_size不为0,那么,所有的sample都是同样的大小。如果sample_size为0,那么,sample的大小可能不一样
sample_count 4 当前track里面的sample数目。如果 sample_size==0,那么,sample_count 等于下面entry_size(sample_sizes)中的数据个数
entry_size (sample_sizes) 4 单个sample的大小 (如果sample_size==0的话)

stz2的结构如下:

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3 无实际意义(官方文档也没有介绍)
version 1 当前box版本,为扩展做准备,取 0 或 1,一般取 0
field_size 1 entry表中,每个entry_size占据的位数(bit),可选的值为4、8、16。4比较特殊,当field_size等于4时,一个字节上包含两个entry,高4位为entry[i],低4位为entry[i+1]
sample_count 4 等于下面entry_size中的数据个数
entry_size 4 单个sample的大小
stco/co64 (Chunk Offset Box)

“stco”定义了每个chunk在媒体流中的偏移量(offsets)。这个位置是在整个文件中的,而不是在任何box中的,这样做就可以直接在文件中找到媒体数据,而不用解析box。需要注意的是一旦前面的box有了任何改变,这张表都要重新建立,因为位置信息已经改变了。

针对小文件、大文件,有两种不同的box类型,分别是stco (32位)、co64 (64位),它们的结构是一样的,只是字段长度不同。

在构建mp4文件的时候,需要特别注意 moov 所处的位置,它对于chunk_offsets 的值是有影响的。有一些MP4文件的 moov 在文件末尾,为了优化首帧速度,需要将 moov 移到文件前面,此时,需要对 chunk_offsets 进行改写。

结构如下:

字段 字节数 描述
size 4 包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
type 4 box类型,包括 “预定义类型”、“自定义扩展类型”
预定义类型:比如ftyp、moov、mdat等预定义好的类型;
自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

flags 3 无实际意义(官方文档也没有介绍)
version 1 当前box版本,为扩展做准备,取 0 或 1,一般取 0
chunk_offsets 4 在文件本身中的 offset,而不是某个box内部的偏移

六、写在最后

关于MP4文件格式详解总结完毕,如有问题,也欢迎随时交流。该系列下一篇文章,将分享几个MP4分析工具,欢迎关注交流。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/113469.html

(0)
上一篇 2025-12-14 11:33
下一篇 2025-12-14 12:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信