标准定义
ISO/IEC 14496-12
MP4整体结构
MP4的Box结构
[Box Header] -> [Box Data]
Box Header定义
| 字段 | 占用(Byte) | 说明 |
|---|---|---|
| size | 4 | 表示整个 box 的大小。size=0说明是最后一个box;size=1时,后面的largesize表示真正的box长度 |
| type | 4 | 4 个 ASCII 值,如果是 “uuid”,则表示此 box 为用户自定义拓展类型 |
| largesize | 8 | size=1 时才有的字段,用于扩展,例如 mdat box 会需要此字段 |
| version | 1 | 版本号 |
| flags | 3 | 标识 |
- version和flags当是full box时存在
以下是一些常见的full box类型
- mvhd (Movie Header Box)
- tkhd (Track Header Box)
- mdhd (Media Header Box)
- hdlr (Handler Reference Box)
- vmhd (Video Media Header Box)
- smhd (Sound Media Header Box)
- dref (Data Reference Box)
- stsd (Sample Description Box)
- stts (Decoding Time to Sample Box)
- stsc (Sample To Chunk Box)
- stsz (Sample Size Box)
- stco / co64 (Chunk Offset Box
MP4需要的基本Box
- [ftyp]
[moov]
[mvhd]
- [tkhd]
[media]
- [mdhd]
- [hdlr]
[minf]
[stbl]
- [stsd]
- [stts]
- [stsc]
- [stsz]
- [stz2]
- [stss]
- [stco]
- [co64]
- [mdat]
ftyp(File Type Box)
ftyp是MP4文件的第一个Box,通过判断该Box来确定文件的类型。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 ftyp box 的总长度,包含这个长度字段本身在内。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "ftyp"。 |
| major_brand | 4 | 文件的主要品牌标识。它指明了文件最好遵循哪种规范进行解析,例如 isom、mp41、avc1 等。 |
| minor_version | 4 | 与 major_brand 相关的版本号。这是一个无符号整数,通常用于指示次要版本,但不应被用来判断文件是否符合某个规范。 |
| compatible_brands | 可变长度 | 一个兼容性品牌列表,每个品牌占 4 字节。它列出了文件所兼容的其他格式或规范,播放器可以通过检查此列表来判断是否能正确解析该文件。 |
moov(Movie Box)
moov 是MP4文件中必须有的一个 Box,但只能存在一个,一般出现在 ftyp 之后或 MP4 文件末尾。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 moov box 的总长度(包含头部)。如果值为 1,则表示实际长度在随后的 8 字节 large-size 中。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "moov"。 |
| mvhd | 可变 | Movie Header Box。包含整个时间轴的全局信息,如创建时间、修改时间、时间刻度、总时长、播放速率、音量以及矩阵变换信息。 |
| trak | 可变 | Track Box。描述单个轨道(如视频轨、音频轨、字幕轨)的信息。一个 MP4 文件通常包含一个或多个 trak。其内部包含 tkhd (轨道头)、mdia (媒体信息) 等。 |
| udta | 可变 | User Data Box。包含用户数据,如元数据标签、版权信息、封面图等(可选)。 |
| pssh | 可变 | Protection System Specific Header Box。如果文件有 DRM 加密,这里会包含相关的密钥系统信息(可选)。 |
mvhd(moov header)
该box是全文件唯一的一个 Box,其对整个媒体文件所包含的媒体数据进行全面的描述。其中包含了媒体的创建和修改时间,默认音量、色域、时长等信息。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 mvhd box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "mvhd"。 |
| version | 1 | box 的版本号,通常为 0 或 1。版本 1 支持 64 位的时间戳和时长。 |
| flags | 3 | 标志位,通常为 0。 |
| creation_time | 4 或 8 | 文件的创建时间。当 version 为 0 时占 4 字节,为 1 时占 8 字节。时间基准是 UTC 1904-01-01。 |
| modification_time | 4 或 8 | 文件的最后修改时间。长度规则同上。 |
| timescale | 4 | 时间刻度,表示 1 秒被划分成多少个时间单元。它是计算时长的基准。 |
| duration | 4 或 8 | 文件的总时长,以 timescale 为单位。当 version 为 0 时占 4 字节,为 1 时占 8 字节。 |
| rate | 4 | 推荐的播放速率,使用 16.16 定点数格式。0x00010000 表示 1.0 倍速正常播放。 |
| volume | 2 | 推荐的播放音量,使用 8.8 定点数格式。0x0100 表示最大音量。 |
| reserved | 10 | 保留字段,通常为 0。 |
| matrix | 36 | 一个 3x3 的变换矩阵,用于定义视频画面的旋转、缩放等图形变换。 |
| pre_defined | 24 | 预定义字段,通常为 0。 |
| next_track_ID | 4 | 下一个轨道(track)将使用的 ID 号,通常为现有最大 track ID 加 1。 |
trak
trak box 是一个 container box,其子 box 包含了该 track 的媒体信息。
一个 mp4 文件可以包含多个 track,track之间是独立的,trak box 用于描述每一路媒体流。一般情况下,一个MP4文件有两个trak,分别对应音频流和视频流。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 trak box 的总长度(包含头部和所有子 box)。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "trak"。 |
| tkhd | 可变 | Track Header Box。轨道头,包含该轨道的基本信息,如轨道ID、创建时间、时长、音量(音频)、宽高(视频)、图层等。 |
| edts | 可变 | Edit Box。编辑列表,用于定义轨道的播放顺序,例如实现剪辑、快进、慢放或跳过某些片段(可选)。 |
| mdia | 可变 | Media Box。媒体信息容器,包含了该轨道媒体数据的详细声明,如媒体类型、时间信息、数据引用和采样表等。 |
| udta | 可变 | User Data Box。用户数据,包含与该轨道相关的元数据,如轨道名称、版权信息等(可选)。 |
tkhd
tkhd 是 trak 容器的核心子 Box,它描述了单个轨道(如视频轨或音频轨)的宏观属性,例如轨道的启用状态、时长、空间位置(宽高)、音量以及图层关系。
tkhd 是一个 FullBox,其内部字段的长度会根据 version 的值(0 或 1)而有所不同,主要体现在时间戳和时长字段上。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 tkhd box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "tkhd"。 |
| version | 1 | box 的版本号,通常为 0 或 1。版本 1 支持 64 位的时间戳和时长。 |
| flags | 3 | 标志位,用于控制轨道的启用和显示状态。常见值为 7 (0x000007),表示轨道启用、用于播放且用于预览。 |
| creation_time | 4 或 8 | 轨道的创建时间。当 version 为 0 时占 4 字节,为 1 时占 8 字节。时间基准是 UTC 1904-01-01。 |
| modification_time | 4 或 8 | 轨道的最后修改时间。长度规则同上。 |
| track_ID | 4 | 轨道的唯一标识符,不能为 0 且不能重复。 |
| reserved | 4 | 保留字段,通常为 0。 |
| duration | 4 或 8 | 轨道的总时长,以 moov 中 mvhd 的时间刻度为单位。当 version 为 0 时占 4 字节,为 1 时占 8 字节。 |
| reserved | 8 | 保留字段,通常为 0。 |
| layer | 2 | 视频轨道的图层顺序。值越小越在上层(越靠近观看者),默认为 0。 |
| alternate_group | 2 | 轨道分组 ID。相同 ID 的轨道属于同一组,播放时通常只选择其中一个(例如不同语言的音轨),默认为 0 表示不分组。 |
| volume | 2 | 轨道音量,使用 8.8 定点数格式。对于音频轨道,0x0100 表示 1.0(最大音量);对于视频轨道,通常为 0。 |
| reserved | 2 | 保留字段,通常为 0。 |
| matrix | 36 | 一个 3x3 的变换矩阵,用于定义视频画面的旋转、缩放等图形变换。 |
| width | 4 | 视频画面的宽度,使用 16.16 定点数格式。 |
| height | 4 | 视频画面的高度,使用 16.16 定点数格式。 |
edts
edts 是 trak 容器的一个可选子 Box,它的主要作用是定义轨道的播放编辑列表,通过调整时间戳来实现剪辑、偏移或重复播放等效果。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 edts box 的总长度(包含头部和所有子 box)。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "edts"。 |
| elst | 可变 | Edit List Box。编辑列表,是 edts 的核心,包含了具体的编辑指令,用于将轨道的媒体时间映射到整个影片的播放时间线上。 |
media
mdia 是 trak(轨道)容器的核心子 Box,它详细描述了该轨道所包含的媒体数据的特性,例如媒体类型(音频/视频)、时间信息、语言以及数据在文件中的具体位置。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 mdia box 的总长度(包含头部和所有子 box)。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "mdia"。 |
| mdhd | 可变 | Media Header Box。媒体头,包含该媒体的创建时间、修改时间、时间刻度(timescale)、时长以及语言信息。 |
| hdlr | 可变 | Handler Reference Box。处理器引用,声明了该轨道的媒体类型(如 vide 表示视频,soun 表示音频)以及用于处理该媒体的组件。 |
| minf | 可变 | Media Information Box。媒体信息容器,包含了描述媒体数据具体属性的信息,如视频头(vmhd)、音频头(smhd)以及最重要的数据索引表(stbl)。 |
mdat(media data box)
mdat 用于存储音视频数据,可从该Box解封装出真实的媒体数据。该Box一般都会存在,但非必须。
mdat的位置比较灵活,可以位于moov之前,也可以位于moov之后,但必须和stbl中的信息保持一致。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 mdat box 的总长度(包含头部和数据)。如果值为 1,则表示实际长度在随后的 8 字节 large-size 中。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "mdat"。 |
| data | 可变 | 媒体数据实体。这里存放的是经过编码的音视频样本(Sample)数据。播放器必须依赖 moov 中的索引信息才能正确解析和播放这部分数据。 |
stbl(Sample Table Box)
stbl 表在 MP4 文件中的位置:moov -> trak -> mdia -> minf -> stbl。
stbl 是 minf (Media Information Box) 的核心子 Box,也是整个 MP4 文件中最复杂、信息量最大的部分。你可以把它理解为媒体数据的“索引目录”或“地图”。它并不包含实际的音视频数据,而是告诉播放器如何从 mdat 中找到每一个样本(Sample),以及何时播放、如何解码。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stbl box 的总长度(包含头部和所有子 box)。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stbl"。 |
| stsd | 可变 | Sample Description Box。样本描述,存储了解码所需的编码格式信息(如 H.264/AVC, AAC)以及初始化参数(如 SPS/PPS)。 |
| stts | 可变 | Time-To-Sample Box。时间映射表,定义了每个样本的播放时长(Duration),用于计算 DTS(解码时间戳)。 |
| stss | 可变 | Sync Sample Box。同步样本表,列出了所有关键帧(I 帧)的序号,用于支持随机访问和快进。 |
| stsc | 可变 | Sample-To-Chunk Box。样本到块映射表,描述了样本是如何分布在数据块(Chunk)中的。 |
| stsz / stz2 | 可变 | Sample Size Box。样本大小表,记录了每个样本的字节大小。 |
| stco / co64 | 可变 | Chunk Offset Box。块偏移表,记录了每个数据块(Chunk)在文件中的起始位置(偏移量)。 |
| ctts | 可变 | Composition Time To Sample Box。显示时间偏移表,用于计算 PTS(显示时间戳),处理 B 帧时的显示顺序与解码顺序不一致的问题(可选)。 |
stsd
stsd 是 stbl (Sample Table Box) 的第一个子 Box,它至关重要,因为它存储了解码媒体数据所需的初始化信息和编码格式定义。没有 stsd,播放器就不知道该用哪种解码器来播放音视频。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stsd box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stsd"。 |
| version | 1 | box 的版本号,通常为 0。 |
| flags | 3 | 标志位,通常为 0。 |
| entry_count | 4 | 样本描述条目的数量。通常为 1,表示该轨道只使用一种编码格式。 |
| Sample Entry | 可变 | 样本条目。具体的编码信息容器。对于 H.264 视频,这里通常是 avc1 box;对于 AAC 音频,则是 mp4a box。它包含了编解码器特定的配置数据(如 SPS/PPS)。 |
stts
stts 是 stbl (Sample Table Box) 的一个核心子 Box,它的作用是定义每个样本(Sample)的播放时长,从而建立起样本序号到解码时间戳(DTS)的映射关系。简单来说,它告诉播放器每一帧应该播放多久。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stts box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stts"。 |
| version | 1 | box 的版本号,通常为 0。 |
| flags | 3 | 标志位,通常为 0。 |
| entry_count | 4 | 时间映射表中的条目数量。 |
| entries | 8 * entry_count | 一个数组,包含 entry_count 个条目。每个条目由 sample_count 和 sample_delta 组成,用于描述一段连续样本的时长信息。 |
entries 数组中每个条目的结构:
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| sample_count | 4 | 连续具有相同时长的样本数量。 |
| sample_delta | 4 | 每个样本的时长,单位是 mdhd box 中定义的 timescale(时间刻度)。 |
stss
stss 是 stbl (Sample Table Box) 的一个子 Box,它的核心作用是标记媒体流中的关键帧(也称为同步样本或 I 帧)。关键帧是可以独立解码的帧,不依赖于其他帧的信息,因此它们是视频快进、快退和随机播放的“锚点”。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stss box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stss"。 |
| version | 1 | box 的版本号,通常为 0。 |
| flags | 3 | 标志位,通常为 0。 |
| entry_count | 4 | 关键帧的数量。 |
| sample_numbers | 4 * entry_count | 一个数组,包含 entry_count 个条目。每个条目是一个 4 字节的整数,代表一个关键帧的样本序号(从 1 开始计数)。 |
ctts
ctts 是 stbl (Sample Table Box) 的一个可选子 Box,它的核心作用是处理视频帧的解码顺序与显示顺序不一致的问题,这在包含 B 帧(双向预测帧)的视频中非常常见。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 ctts box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "ctts"。 |
| version | 1 | box 的版本号。通常为 0,但如果存在负的偏移量(即 PTS < DTS),则必须为 1。 |
| flags | 3 | 标志位,通常为 0。 |
| entry_count | 4 | 时间偏移表中的条目数量。 |
| entries | 8 * entry_count | 一个数组,包含 entry_count 个条目。每个条目由 sample_count 和 sample_offset 组成。 |
entries 数组中每个条目的结构:
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| sample_count | 4 | 连续具有相同显示时间偏移量的样本数量。 |
| sample_offset | 4 | 显示时间偏移量(CTS),单位是 mdhd box 中定义的 timescale(时间刻度)。 |
stsc
stsc 是 stbl (Sample Table Box) 的核心子 Box 之一。它的作用是建立 样本(Sample) 与 数据块(Chunk) 之间的映射关系。
简单来说,stsc 告诉播放器:在某个数据块中,究竟包含了多少个样本(帧)。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stsc box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stsc"。 |
| version | 1 | box 的版本号,通常为 0。 |
| flags | 3 | 标志位,通常为 0。 |
| entry_count | 4 | 映射表中条目的数量(注意:这是规则的数量,不是 Chunk 的总数)。 |
| entries | 12 * entry_count | 一个数组,包含具体的映射规则。 |
entries 数组中每个条目的结构:
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| first_chunk | 4 | 这一组规则的起始 Chunk 索引(从 1 开始计数)。 |
| samples_per_chunk | 4 | 从 first_chunk 开始,每个 Chunk 包含的样本数量。 |
| sample_description_index | 4 | 样本描述的索引,指向 stsd 表中的条目(通常用于区分不同的编码格式,但在单编码流中通常为 1)。 |
stsz
stsz 是 stbl (Sample Table Box) 的核心子 Box 之一。它的核心作用非常直观:记录每一个样本(Sample/帧)的大小(字节数)。
在 MP4 文件中,样本(Sample)的大小通常是不一样的(例如视频中的 I 帧通常比 P 帧大得多)。stsz 提供了一张表,告诉播放器每一帧占用了多少字节,这对于从数据块(Chunk)中准确切割出每一个样本至关重要。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stsz box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stsz"。 |
| version | 1 | box 的版本号,通常为 0。 |
| flags | 3 | 标志位,通常为 0。 |
| sample_size | 4 | 默认样本大小。如果此值不为 0,表示所有样本大小相同,后面就不需要跟大小表;如果此值为 0,表示样本大小不一,必须读取后面的 entry_size 表。 |
| sample_count | 4 | 样本的总数量。这个值必须与 stts 和 stsc 中计算出的总样本数一致。 |
| entry_size | 4 * sample_count | 样本大小表。仅当 sample_size 为 0 时存在。这是一个数组,包含 sample_count 个条目,每个条目记录对应样本的具体字节大小。 |
stco
stco 是 stbl (Sample Table Box) 的核心子 Box 之一。它的核心作用非常明确:记录每一个数据块(Chunk)在 MP4 文件中的物理起始位置(偏移量)。
你可以把它理解为文件中的“物理地址表”。如果说 stsz 告诉我们样本有多大,stsc 告诉我们样本怎么分组,那么 stco 就告诉我们要去哪里(文件的哪个字节位置)读取这些数据。
| 字段名称 | 占用空间(Byte) | 说明 |
|---|---|---|
| box-size | 4 | 整个 stco box 的总长度。 |
| box-type | 4 | box 的类型标识,固定为 ASCII 字符 "stco"。 |
| version | 1 | box 的版本号,通常为 0。 |
| flags | 3 | 标志位,通常为 0。 |
| entry_count | 4 | 偏移表中的条目数量(也就是 Chunk 的总数量)。 |
| chunk_offsets | 4 * entry_count | 偏移量数组。每个条目是一个 4 字节的无符号整数,表示对应 Chunk 距离文件开头的字节数。 |
评论已关闭