一、分片相关盒(moof/traf/trun)详细参数说明

分片 MP4(Fragmented MP4,简称 fMP4)是专为流媒体传输设计的格式,核心是将完整视频拆分为多个独立 “分片(Fragment)”,每个分片包含 “元数据(moof)+ 媒体数据(mdat)”,支持 “边下载边播放”(无需等待整个文件下载完成)。以下是分片核心盒子的详细参数、数据结构及流媒体适配逻辑:

1. moof(Movie Fragment Box,电影片段盒)

核心定位:

每个分片的 “迷你元数据容器”,类似完整 MP4 中的moov,但仅存储当前分片的局部元数据,而非全局信息。一个分片对应一个moof盒,与一个mdat盒(该分片的媒体数据)成对出现。

关键参数:
  • 无直接参数,核心作用是承载分片内的子盒mfhdtraf),将分片的元数据组织成结构化单元。
数据结构(简化):
moof
├─ mfhd(分片头盒,必需)
└─ traf(轨道片段盒,至少1个,对应每个轨道的分片)
   ├─ tfhd(轨道片段头盒,必需)
   └─ trun(样本运行盒,可选但常用)
实际作用:
  • 作为分片的 “元数据外壳”,将分片的序号、轨道参数、样本信息封装在一起,方便播放器按分片粒度解析;
  • 与后续的mdat盒绑定,形成 “分片元数据 + 分片数据” 的独立单元,支持下载一个分片就播放一个分片。

2. mfhd(Movie Fragment Header Box,电影片段头盒)

核心定位:

moof的核心子盒,负责标识分片的顺序,确保播放器按正确顺序拼接分片(避免播放错乱,如分片 2 在分片 1 之前播放)。

关键参数:
  • sequence_number(分片序列号):32 位整数,从 1 开始递增(如第 1 个分片序号 = 1,第 2 个 = 2,以此类推)。
数据结构(简化):
字段名 类型 示例值 说明
version u8 0 盒子版本,通常为 0
flags u32 0 标志位,无特殊含义时为 0
sequence_number u32 5 第 5 个分片
实际作用:
  • 播放器下载分片后,通过sequence_number排序(如按 1→2→3→… 的顺序),再拼接播放;
  • 若网络传输中分片丢失(如缺失序号 3),播放器可暂停播放并请求重传,或跳过丢失分片(根据容错策略),保证播放连续性。

3. traf(Track Fragment Box,轨道片段盒)

核心定位:

moof的子盒,对应单个轨道的分片(如视频轨的第 5 个分片、音频轨的第 5 个分片)。一个moof中会有多个traf盒(与轨道数量一致),分别管理不同轨道的分片数据。

关键参数:
  • 无直接参数,核心作用是承载轨道分片的子盒tfhdtrun),将单个轨道分片的元数据组织成单元。
数据结构(简化):

plaintext

traf
├─ tfhd(轨道片段头盒,必需)
├─ trun(样本运行盒,可选但常用)
└─ 其他可选子盒(如tfdt、uuid等,用于时间戳、扩展信息)
实际作用:
  • 隔离不同轨道的分片数据(如视频分片和音频分片分开管理),避免轨道信息混淆;
  • 每个traf仅关联当前轨道的一个分片,播放器可独立解析音 / 视频轨道的分片,再通过时间戳同步播放。

4. tfhd(Track Fragment Header Box,轨道片段头盒)

核心定位:

traf的核心子盒,记录轨道分片的基础配置,包括该分片对应的 “母轨道”(完整轨道)ID、样本默认参数(如大小、偏移量),确保分片与主轨道的参数兼容。

关键参数(核心字段):

字段名 类型 示例值 说明
track_id u32 2 对应主轨道的 ID(如 2 表示该分片属于视频轨,与moovtraktrack_id一致)
default_sample_size u32 15000 分片中样本的默认大小(字节),若trun中未单独指定样本大小,则使用此值
default_sample_duration u32 36 分片中样本的默认持续时长(单位:轨道时间刻度),trun未指定时使用
flags u32 0x000001 标志位,用于标识哪些参数有效(如 0x000001 表示track_id有效)

数据结构(简化,基于flags标识有效参数):

plaintext

tfhd
├─ version: 0
├─ flags: 0x000007(表示track_id、default_sample_size、default_sample_duration均有效)
├─ track_id: 2(对应视频轨)
├─ default_sample_size: 15000(默认样本大小15KB)
└─ default_sample_duration: 36(默认样本持续36个时间单位,若轨道时间刻度=1000,则为36ms)
实际作用:
  • 通过track_id关联主轨道(如视频轨),确保分片数据能正确 “拼接” 到主轨道的播放流中;
  • 提供样本默认参数(大小、时长),减少trun盒的重复数据(若分片中所有样本参数一致,trun无需逐个记录),节省分片元数据体积。

5. trun(Track Run Box,样本运行盒)

核心定位:

traf的核心子盒,记录分片中每个样本的具体信息(如大小、时间偏移、是否为关键帧),是支持 “边下载边播放” 的关键 —— 无需依赖全局stbl盒,仅通过trun就能解析分片中的样本,实现即时播放。

关键参数(核心字段,基于flags标识是否存在):

字段名 类型 示例值 说明
sample_count u32 8 分片中的样本数量(如该分片包含 8 个视频帧)
data_offset i32 120 样本数据在mdat中的偏移量(相对于trun盒的起始位置,正数表示在trun之后)
sample_size(数组) u32[] [14800, 15200, ...] 每个样本的大小(字节),若tfhd指定默认值且此处未填,则用默认值
sample_duration(数组) u32[] [36, 36, ...] 每个样本的持续时长(时间单位),同理可使用tfhd默认值
sample_flags(数组) u32[] [0x000001, 0x000000, ...] 样本标志位(如 0x000001 表示该样本是关键帧)

数据结构(简化,包含 8 个样本):

plaintext

trun
├─ version: 0
├─ flags: 0x00001F(表示sample_count、data_offset、sample_size、sample_duration、sample_flags均有效)
├─ sample_count: 8(8个样本)
├─ data_offset: 120(样本数据在mdat中,位于trun盒之后120字节处)
├─ sample_size: [14800, 15200, 14500, 15100, 14900, 15300, 14700, 15000](每个样本大小)
├─ sample_duration: [36, 36, 36, 36, 36, 36, 36, 36](每个样本持续36ms)
└─ sample_flags: [0x000001, 0x000000, 0x000000, 0x000000, 0x000001, 0x000000, 0x000000, 0x000000](第1、5个是关键帧)

实际作用(流媒体核心逻辑):

  • 无需全局stbl:传统 MP4 需先读取完整moov(包含stbl)才能定位样本,而 fMP4 的trun直接记录分片中样本的大小、位置、时间,下载完moof(含trun)后即可解析mdat中的样本,实现 “下载一个分片播一个分片”;
  • 关键帧标记:通过sample_flags标记关键帧,播放器可在分片内快速定位关键帧,即使分片下载中断,也能从最近的关键帧恢复播放;
  • 灵活适配网络:若网络带宽不足,可动态调整分片大小(如减少每个分片的样本数量),降低单次下载的数据量,减少卡顿。

分片盒子协同逻辑总结(边下边播实现流程)

  1. 分片下载:播放器从服务器请求视频分片(按sequence_number顺序,如先下载序号 1,再下载序号 2);
  2. 分片解析:下载完moof后,通过mfhd确认分片序号(如序号 1),通过traftfhd找到对应的轨道(如视频轨track_id=2);
  3. 样本定位:通过trun获取分片中样本的数量、大小、时间偏移,结合data_offset定位到mdat中的样本数据(如第 1 个样本起始于mdat的 120 字节处,大小 14800 字节);
  4. 解码播放:解码器使用stsd(来自主moov的全局编码参数)解析样本,结合trunsample_duration控制播放时间,实现边下载边播放;
  5. 分片拼接:播放完分片 1 后,继续下载分片 2,重复步骤 2-4,通过sequence_number确保顺序拼接,通过时间戳(sample_duration累加)确保音视频同步。

分片 MP4 与传统 MP4 的核心差异

对比维度 传统 MP4(非分片) 分片 MP4(fMP4)
元数据位置 moov(全局元数据)+ stbl(全局样本索引) moov(基础参数)+ 每个分片moof(局部元数据)
播放条件 需下载完整moov才能开始播放 下载第一个分片的moof即可播放
适用场景 本地播放、小文件传输 流媒体(如直播、在线视频)
网络适应性 差(文件大时下载慢,易卡顿) 好(分片下载,动态适配带宽)

二、主moov扩展盒与分片时间戳同步详细说明

在分片 MP4(fMP4)中,主moov盒里的mvex/trex盒与分片的moof/traf/trun盒并非独立工作 ——mvex/trex负责提供分片的全局默认配置,而moof内的盒子基于这些默认值补充局部差异,两者配合实现分片的高效解析与播放。同时,分片的时间戳同步依赖tfdt盒(轨道片段解码时间盒)与全局时间基准的对齐,确保多个分片、多轨道的播放连续性。

(一)、主moov扩展盒(mvex/trex)与分片盒子的联动

mvex(Movie Extends Box)和trex(Track Extends Box)是主moov中为分片 MP4 预留的 “全局配置中心”,作用是定义所有分片的基础默认参数,避免每个moof/traf重复存储相同信息(如轨道 ID、编码描述索引),减少分片元数据体积。

1. mvex(Movie Extends Box,电影扩展盒)

核心定位:

moov的子盒,是分片 MP4 的 “扩展开关”—— 仅当 MP4 为分片格式时,mvex才存在,其核心作用是承载trex(每个轨道对应一个trex),统一管理所有轨道的分片默认配置。

数据结构(简化):

plaintext

mvex(主moov的子盒)
└─ trex(Track Extends Box,每个轨道1个)
   ├─ track_id: 1(对应音频轨)
   ├─ default_sample_description_index: 1
   ├─ default_sample_duration: 32
   ├─ default_sample_size: 12000
   └─ default_sample_flags: 0x000000
└─ trex(对应视频轨)
   ├─ track_id: 2
   ├─ default_sample_description_index: 1
   ├─ default_sample_duration: 36
   ├─ default_sample_size: 15000
   └─ default_sample_flags: 0x000001
实际作用:
  • 作为trex的 “容器”,将所有轨道的分片默认参数集中存储在主moov中,播放器只需读取一次mvex,就能获取所有轨道的分片基础配置;
  • 告诉播放器 “该 MP4 是分片格式”,需按分片逻辑解析(而非传统 MP4 的全局stbl索引)。

2. trex(Track Extends Box,跟踪扩展盒)

核心定位:

mvex的子盒,每个轨道对应一个trex(如音频轨 1 个、视频轨 1 个),存储该轨道所有分片的 “默认参数模板”。当分片的tfhd/trun未指定某参数时,自动使用trex的默认值,减少重复数据。

关键参数(与tfhd参数对应,形成 “默认 - 覆盖” 关系):
参数名 类型 示例值(视频轨) 说明
track_id u32 2 对应主轨道的 ID(与moovtraktrack_id一致,关联轨道)
default_sample_description_index u32 1 默认样本编码描述索引(关联stsd中的编码参数,如 H.264 的avc1
default_sample_duration u32 36 样本默认持续时长(单位:轨道时间刻度,如 36=36ms,与trunsample_duration对应)
default_sample_size u32 15000 样本默认大小(字节,与trunsample_size对应)
default_sample_flags u32 0x000001 样本默认标志位(如 0x000001 = 关键帧,与trunsample_flags对应)
与分片盒子的联动逻辑(以视频轨为例):
  • 默认参数继承:若某分片的tfhd未指定default_sample_size,则自动使用trex15000字节;若trun未单独指定某样本的sample_duration,则使用trex36时间单位;
  • 局部参数覆盖:若分片的trun中某样本大小为16000字节(不同于默认的15000),则以trun的局部值为准,实现 “默认统一 + 局部灵活” 的配置;
  • 作用:减少每个moof/traf的参数存储量(如无需重复记录track_id、编码索引),尤其对大量小分片的直播场景,能显著降低元数据传输成本。

(二)、分片时间戳同步实现(tfdt盒与全局时间对齐)

分片 MP4 的时间同步核心是让每个分片的样本时间戳与全局时间轴对齐—— 传统 MP4 通过stts累加计算全局时间,而分片 MP4 通过tfdt(Track Fragment Decode Time Box)提供分片的 “时间基准点”,再结合trunsample_duration计算每个样本的全局时间。

1. tfdt(Track Fragment Decode Time Box,轨道片段解码时间盒)

核心定位:

traf的可选子盒(但分片同步必需),为当前轨道分片提供起始解码时间(全局时间轴上的位置),是分片时间与全局时间对齐的 “锚点”。

关键参数:
  • base_media_decode_time(基础媒体解码时间):64 位整数,表示该分片的第一个样本在全局时间轴上的起始解码时间(单位:轨道时间刻度)。
数据结构(简化):
字段名 类型 示例值(视频轨分片 5) 说明
version u8 1 版本 1 支持 64 位时间戳,版本 0 支持 32 位(推荐版本 1,避免时间溢出)
flags u32 0 标志位,无特殊含义时为 0
base_media_decode_time u64 18000 该分片第一个样本的全局起始解码时间(轨道时间刻度,若刻度 = 1000,则为 18 秒)
核心作用:
  • 解决分片 “时间孤岛” 问题:每个分片的trun仅记录样本的 “相对时间”(如分片内第 1 个样本持续 36ms,第 2 个也持续 36ms),而tfdtbase_media_decode_time告诉播放器 “该分片的时间起点在全局时间轴的哪里”;
  • 示例:若视频轨时间刻度 = 1000(1 单位 = 1ms),分片 5 的base_media_decode_time=18000(18 秒),则:
    • 分片 5 第 1 个样本解码时间 = 18000ms(18 秒);
    • 第 2 个样本解码时间 = 18000+36=18036ms(18.036 秒);
    • 以此类推,确保分片 5 的时间与前 4 个分片的时间轴无缝衔接。

2. 时间戳同步完整流程(以视频轨为例)

步骤 1:获取全局时间基准(主moovmvhd
  • mvhdtimescale(全局时间刻度)=1000(1 单位 = 1ms),duration=480000(总时长 480 秒 = 8 分钟);
  • 轨道的mdhd(媒体头盒)的timescale=1000(与全局刻度一致,确保时间单位统一)。
步骤 2:解析分片tfdt的时间基准
  • 分片 5 的tfdtbase_media_decode_time=18000(轨道时间刻度 = 1000→18 秒);
  • 该值是分片 5 所有样本的 “时间起点”,由服务器生成时确保与前一分片(分片 4)的最后一个样本时间衔接(如分片 4 最后一个样本时间 = 17999ms,分片 5 起点 = 18000ms,无间隙)。
步骤 3:计算分片中每个样本的全局时间
  • trunsample_count=8,每个样本sample_duration=36(36ms);
  • 样本 1 全局解码时间 = 18000ms(18 秒);
  • 样本 2 全局解码时间 = 18000+36=18036ms(18.036 秒);
  • ...
  • 样本 8 全局解码时间 = 18000+36×7=18252ms(18.252 秒)。
步骤 4:视频与音频轨道的时间同步
  • 音频轨分片 5 的tfdtbase_media_decode_time=18000(与视频轨一致);
  • 音频样本sample_duration=32(32ms,对应 44100Hz 采样率的音频段);
  • 音频样本 1 全局解码时间 = 18000ms,与视频样本 1 的时间一致,实现音视频同步播放。

3. 时间戳同步的关键保障

  • 时间刻度统一:主moovmvhd、轨道的mdhdtfdt/trun的时间单位需一致(如均为 1000,即 ms),若不一致需进行转换(如轨道刻度 = 90000,全局刻度 = 1000,则 1 轨道单位 = 1/90 秒≈11.11ms);
  • base_media_decode_time连续:服务器生成分片时,需确保下一个分片的base_media_decode_time= 前一个分片最后一个样本的全局时间 + 1,避免时间间隙或重叠;
  • 音视频tfdt对齐:同一序号的音视频分片(如音频分片 5、视频分片 5)的base_media_decode_time需相同,确保同一时间点播放对应的音频和视频样本。

(三)、完整分片 MP4 的盒子层级与协同逻辑(补充mvex/tfdt后)

plaintext

MP4 文件(分片格式)
├─ ftyp(文件类型盒,必需)
├─ moov(主电影盒,必需)
│  ├─ mvhd(全局头盒,必需)
│  ├─ mvex(电影扩展盒,必需)
│  │  ├─ trex(音频轨扩展盒,必需)
│  │  └─ trex(视频轨扩展盒,必需)
│  └─ trak(音频轨/视频轨盒,必需)
│     ├─ tkhd(轨道头盒)
│     ├─ mdia(媒体盒)
│     │  ├─ mdhd(媒体头盒)
│     │  ├─ hdlr(处理者盒)
│     │  └─ minf(媒体信息盒)
│     │     └─ stbl(样本表盒,仅存编码参数stsd,无全局样本索引)
│     │        └─ stsd(编码描述盒,avc1/mp4a,必需)
├─ moof(分片1元数据盒,必需)
│  ├─ mfhd(分片头盒,sequence_number=1)
│  ├─ traf(音频轨分片1盒)
│  │  ├─ tfhd(轨道片段头盒,track_id=1)
│  │  ├─ tfdt(解码时间盒,base_media_decode_time=0)
│  │  └─ trun(样本运行盒,8个音频样本)
│  └─ traf(视频轨分片1盒)
│     ├─ tfhd(轨道片段头盒,track_id=2)
│     ├─ tfdt(解码时间盒,base_media_decode_time=0)
│     └─ trun(样本运行盒,8个视频样本)
├─ mdat(分片1媒体数据盒,存储分片1的音视频样本)
├─ moof(分片2元数据盒,sequence_number=2)
│  ├─ mfhd(sequence_number=2)
│  ├─ traf(音频轨分片2盒,tfdt=256ms)
│  └─ traf(视频轨分片2盒,tfdt=288ms)
├─ mdat(分片2媒体数据盒)
└─ ...(更多分片moof+mdat)

协同逻辑总结:

  1. 初始化:播放器读取ftyp确认是分片 MP4,读取moovmvhd获取全局时间刻度,读取mvextrex获取各轨道的分片默认参数,读取stsd获取编码参数;
  2. 分片解析:下载分片 1 的moof,通过mfhd确认序号 1,通过traftfhd关联轨道(如track_id=2对应视频轨),通过tfdt获取分片 1 的时间起点(0ms);
  3. 样本播放:通过trun获取样本大小、时长,结合mdat定位样本数据,解码器用stsd参数解码,按tfdt+sample_duration计算的全局时间播放;
  4. 分片衔接:下载分片 2,通过mfhd序号 2 确认顺序,通过tfdtbase_media_decode_time=288ms(分片 1 最后一个样本时间 = 287ms)实现无缝衔接,重复步骤 3-4 直至播放结束。

总结

  • mvex/trex是分片 MP4 的 “全局配置模板”,通过提供默认参数减少分片元数据冗余,与tfhd/trun形成 “默认 - 覆盖” 的高效配置模式;
  • tfdt是分片时间同步的 “锚点”,通过base_media_decode_time将分片的局部时间映射到全局时间轴,确保分片间、音视频轨道间的时间对齐;
  • 整个分片系统围绕 “边下载边播放” 设计,从参数配置到时间同步,每一步都为降低延迟、提升网络适应性服务,这也是 fMP4 成为流媒体主流格式的核心原因。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐