1.MP4文件Box节点树
下图展示了 MP4 文件的整体骨架,即MP4文件Box节点树 ,其中每个盒子(Box)都是树上的一个节点。moov 无疑是这棵树的"大脑"和核心目录,它并不直接存储音视频数据,而是包含了如何找到和解读这些数据的所有元信息(Metadata)。

Box有两种,一种是叶子Box,一种是容器Box。
2.Box节点结构
每个Box都由Header和Body(Data) 两部分组成。

上面是我画的,实际上别人画的更好:

图片来自:https://www.jianshu.com/p/529c3729f357
Box Header:包含两个核心字段:
- size (4字节):表示整个Box(包含Header自身)的总字节数。
- type (4字节):由4个ASCII字符组成的标识符,如ftyp、moov,用于区分Box类型。
Box Body:存放该Box的实际数据,其结构完全取决于type。有些Box的Body内会继续嵌套其他Box,这类Box被称为容器Box(Container Box),例如moov就是最典型的容器Box。
此外,还有一种特殊的FullBox,它在标准Box的Header基础上扩展了version(1字节)和flags(3字节)字段,用于提供更详细的版本和控制信息
3.核心节点详解与缩写还原
在 MP4 的节点树中,有些盒子名称是缩写。了解它们的全称能更好地理解其职能。
| 节点缩写 | 节点全称 | 核心职能与解读 |
|---|---|---|
ftyp |
File Type Box(文件类型盒子) | 它是文件的"身份证",位于整个节点树的根目录下的第一个子节点。它声明了文件的兼容性标准,播放器首先读取它来判断是否能支持播放该文件。通常为24字节。 |
moov |
Movie Box(影片盒子) | 它是整个文件的"总索引"或"大脑",是一个容器节点 。它包含了影片的全局信息以及所有轨道(Track)的元数据,但不包含实际的媒体数据。 |
mvhd |
Movie Header Box(影片头盒子) | 作为 moov 节点的第一个子节点,它存储了全局信息,如整个影片的创建时间、时间刻度(timescale)、时长等。 |
trak |
Track Box(轨道盒子) | 每个 trak 节点代表一条独立的媒体轨道(如视频轨、音频轨)。它是一个容器节点,内部有更细致的结构来描述这条轨道的所有信息。 |
tkhd |
Track Header Box(轨道头盒子) | 位于 trak 节点内,描述单个轨道的头信息,如轨道的唯一ID、时长、视频宽度高度、音量等。 |
mdia |
Media Box(媒体盒子) | 位于 trak 节点内,是一个容器节点,包含了该轨道媒体信息的详细定义。 |
mdhd |
Media Header Box(媒体头盒子) | 位于 mdia 节点内,包含该轨道媒体的头信息,如轨道的语言、时间刻度、时长等。 |
hdlr |
Handler Reference Box(处理器参考盒子) | 位于 mdia 节点内,声明了该轨道媒体的类型 ,例如是视频轨(vide)、音频轨(soun)还是提示轨(hint)。 |
minf |
Media Information Box(媒体信息盒子) | 位于 mdia 节点内,是一个容器节点,包含了如何解释媒体数据的信息。 |
stbl |
Sample Table Box(样本表盒子) | 位于 minf 节点内,是最重要的索引节点。它像一个详细的"目录",将时间戳映射到具体的媒体数据在文件中的存储位置。视频能否快速随机拖动(seek),关键就在于解析这个盒子。 |
stsd |
Sample Description Box(样本描述盒子) | 位于 stbl 节点内,描述了媒体的编码格式(如 H.264, AAC)和解码所需的配置参数(如视频的宽高、编码等级)。 |
stts |
Time-to-Sample Box(时间戳-样本映射盒子) | 位于 stbl 节点内,建立了样本序号与时间戳(解码顺序)的映射关系。 |
stss |
Sync Sample Box(同步样本盒子) | 位于 stbl 节点内,记录了所有关键帧(I帧)的列表。这是实现视频拖动功能的关键索引。 |
stsc |
Sample-to-Chunk Box(样本-块映射盒子) | 位于 stbl 节点内,定义了样本是如何分块(Chunk)存储的。 |
stco/co64 |
Chunk Offset Box(块偏移盒子) | 位于 stbl 节点内,记录了每个数据块(Chunk)在文件中的起始字节位置 。stco 用于32位偏移,co64 用于64位偏移(大文件)。 |
mdat |
Media Data Box(媒体数据盒子) | 它是节点树中最庞大的"数据仓库" ,直接位于根节点下。它存储了实际的、经过编码压缩的音视频帧数据(Sample) 。它本身只是一个数据容器,需要依赖 moov 中的索引才能被正确解读。 |
最起码要记住两个Box:
MP4文件中的moov(Movie Box)和mdat(Media Data Box)确实扮演着这样的角色:moov是记录所有元数据的"说明书",而mdat是存储实际媒体数据的"仓库"。下面这个表格能更清晰地展示它们的核心分工。
| 特性对比 | moov (Movie Box,元数据容器) |
mdat (Media Data Box,媒体数据容器) |
|---|---|---|
| 核心功能 | 存储媒体的描述性信息(元数据),相当于"说明书" | 存储编码后的音视频数据本身,是媒体的"数据仓库" |
| 主要内容 | 时长、时间尺度、轨道信息、样本(帧)的索引、大小、时间戳、关键帧位置等 | H.264视频帧、AAC音频帧等连续的、编码后的二进制数据块 |
| 必要性 | 必需。没有它,播放器无法理解mdat中的数据。 |
通常必需(除非数据在外部文件)。没有它就没有实际的媒体内容。 |
| 结构关系 | 是顶级容器Box,内嵌复杂的子Box结构(如mvhd, trak, stbl等)来组织元数据。 |
是顶级容器Box,结构相对简单,主要包含连续的媒体数据流。 |
4.MP4文件内的节点和数据是怎么写进去的
先生成独立的Box节点文件,然后最后遍历节点树,也就是把二维的树编码成一维的文件流,生成文件流就是把各个Box文件拼接进最终的MP4文件中,完成。
5.用工具查看MP4视频文件信息
离线工具:mp4info
在线工具:mp4box.js
大家慢慢分析吧!