【音视频】MP4 文件结构详细解析

文章目录

    • [一、Box 基础结构(核心单元)](#一、Box 基础结构(核心单元))
      • [1. 普通 Box 头](#1. 普通 Box 头)
      • [2. Full Box(Box 的扩展)](#2. Full Box(Box 的扩展))
    • [二、根级核心 Box(必选/关键)](#二、根级核心 Box(必选/关键))
      • [1. ftyp(File Type Box,必选)](#1. ftyp(File Type Box,必选))
      • [2. moov(Movie Box,必选,容器 Box)](#2. moov(Movie Box,必选,容器 Box))
      • [3. mdat(Media Data Box,可选,可多个)](#3. mdat(Media Data Box,可选,可多个))
      • [4. 其他常见根 Box](#4. 其他常见根 Box)
    • 三、关键设计细节与机制
      • [1. 容器 Box vs 叶子 Box](#1. 容器 Box vs 叶子 Box)
      • [2. 时间尺度与时间戳映射](#2. 时间尺度与时间戳映射)
      • [3. 快速启动(Fast Start)](#3. 快速启动(Fast Start))
      • [4. 64 位扩展](#4. 64 位扩展)
    • 四、典型文件结构示例
    • 五、常见问题与解析要点
    • 六、实用工具与命令

MP4(ISO/IEC 14496‑14)基于 ISO 基础媒体文件格式(ISOBMFF,ISO/IEC 14496‑12),整体由Box(或 Atom) 嵌套构成,所有数据均封装在 Box 内,无游离数据。


一、Box 基础结构(核心单元)

每个 Box 遵循统一头格式,字节序为 大端(Big‑Endian),分为普通 Box 与 Full Box(带版本/标志扩展)。

1. 普通 Box 头

字段 字节数 说明
size 4 整个 Box 总字节数(含头);size=1 时用 8 字节 largesize;size=0 表示文件末尾
type 4 4 字符标识(如 ftyp、moov)
largesize 8 可选,size=1 时启用,64 位总长度
body 可变 数据区,可嵌套子 Box(容器 Box)或存储原始数据(叶子 Box)

2. Full Box(Box 的扩展)

在普通 Box 头后增加:

  • version(1 字节):格式版本
  • flags(3 字节):功能标志位
    常见于 mvhd、tkhd 等核心元数据 Box。

二、根级核心 Box(必选/关键)

根层级 Box 按功能分为三类,必须以 ftyp 开头 ,其余顺序可灵活调整(但 moov 前置可实现"快速启动")。

1. ftyp(File Type Box,必选)

  • 作用:标识文件类型与兼容性,是 MP4 的"身份证"

  • 结构:

    复制代码
    size(4)+type(4, 'ftyp')+major_brand(4)+minor_version(4)+compatible_brands(n*4)
  • 示例:major_brand=mp42 表示兼容 MPEG‑4 Part 14;compatible_brands 列出支持的品牌(如 isom、avc1)。

2. moov(Movie Box,必选,容器 Box)

  • 作用:存储媒体元数据(时长、轨道、编码、时间戳映射等),是 MP4 的"索引目录"

  • 典型子 Box 结构:

    复制代码
    moov
    ├─ mvhd(Movie Header Box,必选):全局媒体信息(创建时间、时长、时间尺度)
    ├─ trak(Track Box,至少 1 个):单个轨道(视频/音频/字幕)
    │  ├─ tkhd(Track Header Box):轨道头(ID、时长、分辨率、音量)
    │  ├─ mdia(Media Box):媒体信息容器
    │  │  ├─ mdhd(Media Header Box):媒体时间尺度、时长
    │  │  ├─ hdlr(Handler Reference Box):轨道类型(video/audio)
    │  │  └─ minf(Media Information Box):媒体编码与采样信息
    │  │     ├─ vmhd/smhd(Video/Audio Media Header):音视频专属头
    │  │     ├─ dinf(Data Information Box):数据存储位置
    │  │     └─ stbl(Sample Table Box,核心):采样表(帧索引)
    │  │        ├─ stsd(Sample Description):编码参数(如 H.264 SPS/PPS、AAC 配置)
    │  │        ├─ stts(Time‑to‑Sample):时间戳→采样映射
    │  │        ├─ stsc(Sample‑to‑Chunk):采样→数据块映射
    │  │        ├─ stsz(Sample Sizes):每个采样的字节数
    │  │        └─ stco/co64(Chunk Offsets):数据块在文件中的偏移量
    └─ udta(User Data Box,可选):自定义元数据(标题、作者、封面)
  • 关键:stbl 子 Box 决定如何从 mdat 中定位并解码每一帧数据。

3. mdat(Media Data Box,可选,可多个)

  • 作用:存储原始媒体数据(视频帧、音频帧),是 MP4 的"数据仓库"
  • 结构:size+type('mdat')+媒体字节流
  • 特点:
    • 数据无结构,完全由 moov 中的 stbl 描述
    • 可通过 stco/co64 定位到帧的偏移量与长度
    • 支持"外部引用"(无 mdat,数据来自其他文件)。

4. 其他常见根 Box

  • free/skip:填充/预留空间,不影响播放
  • meta:扩展元数据(如章节、封面)。

三、关键设计细节与机制

1. 容器 Box vs 叶子 Box

  • 容器 Box:可嵌套子 Box(如 moov、trak、mdia),负责组织元数据结构
  • 叶子 Box:直接存储数据(如 mdat、mvhd),无嵌套。

2. 时间尺度与时间戳映射

  • mvhd/mdhd 中的 timescale 定义"1 秒包含的时间单位数"(如 timescale=90000 对应 90kHz)
  • stts 将采样时间戳(单位:timescale)映射为实际播放时间
  • 示例:timescale=90000,采样时间戳 180000 → 播放时间 2 秒。

3. 快速启动(Fast Start)

  • 默认 moov 在 mdat 之后,播放器需读取到文件末尾才能开始播放
  • 将 moov 移到 mdat 之前(如用 ffmpeg -movflags faststart),播放器可立即解析元数据并启动播放,适合网络分发。

4. 64 位扩展

  • 当 Box 长度超过 4GB 时,size=1 并启用 largesize(8 字节)
  • co64 替代 stco 存储 64 位偏移量,支持超大文件。

四、典型文件结构示例

复制代码
[ftyp] → [moov] → [mdat]
或
[ftyp] → [free] → [mdat] → [moov]
  • ftyp:固定开头,标识格式
  • moov:元数据,决定播放逻辑
  • mdat:音视频帧,占文件体积 90%+。

五、常见问题与解析要点

  1. 文件损坏 :moov 丢失或 stbl 错误会导致无法播放,需修复索引
  2. 多音轨/字幕 :通过多个 trak 实现,每个 trak 对应独立的 stbl
  3. H.264/HEVC 编码适配 :stsd 中存储 avcC/hvcC 结构,包含 SPS/PPS/VPS 等编码参数。

六、实用工具与命令

  • 查看 Box 结构:mp4box -info input.mp4 或 ffprobe -show_streams -show_format input.mp4
  • 快速启动优化:ffmpeg -i input.mp4 -c copy -movflags faststart output.mp4
  • 提取 Box:dd if=input.mp4 of=moov.box skip=$offset count=$size(需先解析 moov 偏移与长度)。
相关推荐
All for pursuit.7 小时前
【回溯-7】494.目标和
数据结构·c++·算法·leetcode
白杨尚青7 小时前
C++入门篇(十三):vector(上)——动态数组:构造、空间增长与迭代器失效
开发语言·c++·笔记·算法·stl
企业数字化笔记8 小时前
视频像素分割怎么选?HSV 阈值、传统掩膜、语义分割和实例分割的效果与代价
opencv·音视频
youdexiang8 小时前
AI 生成会议纪要好用吗?多款 APP 功能分析
java·人工智能·音视频
(Charon)9 小时前
【C++面试】RAII到底是什么:从资源管理理解C++对象生命周期
c++·算法·面试
AI创界者9 小时前
【开源实战】MiniMax-H3 本地离线高自由度 ComfyUI 工作流搭建指南(含规则松绑与提示词映射)
人工智能·aigc·音视频
无名猿9 小时前
成员初始化列表与初始化顺序陷阱:按声明顺序,不是书写顺序
c++·现代c++·语法基础
91刘仁德9 小时前
传输层协议深度拆解:端口寻址、UDP 报文与 TCP 可靠性机制全解析
linux·网络·c++·网络协议·tcp/ip·udp·c
hai3152475439 小时前
文本矩阵化拆解与视频矩阵化构建
线性代数·矩阵·音视频
Liuchang09119 小时前
洛谷 P2670 [NOIP 2015 普及组] 扫雷游戏
c++·算法·游戏