MP4 文件是一种基于 ISO/IEC 14496-12 (MPEG-4 Part 12) 定义的多媒体容器格式,也称为 ISO Base Media File Format (ISOBMFF) 。它可以包含音频、视频、字幕等多种流,并使用不同的编码格式压缩存储这些内容。MP4 文件格式使用称为 盒子(box) 或 原子(atom) 的层次结构,每个盒子包含特定类型的信息。
MP4 文件格式结构
MP4 文件是由多个 盒子 (Box)组成的,每个盒子包含不同的信息。这些盒子可以嵌套,每个盒子都有一个 4 字节的标识符(通常是4个ASCII字符,如 ftyp、moov)。盒子的结构大体如下:
            
            
              rust
              
              
            
          
          [box size] [box type] [box data]- box size:盒子的大小,包括所有内容。
- box type:盒子的类型(4 字节字符)。
- box data:盒子的数据内容,依赖于盒子的类型。
常见的 MP4 盒子类型及其作用
以下是 MP4 文件中常见的盒子及其功能:
1. ftyp(File Type Box)
- 这是 MP4 文件的头部盒子,描述文件格式的兼容性和版本。
- 它包含 MP4 文件所使用的品牌(格式类型)以及所支持的兼容品牌。
- 常见的兼容品牌有 isom(ISO Base Media)、mp41(MP4 v1)、mp42(MP4 v2)等。
2. moov(Movie Box)
- 
存放媒体元数据的盒子。所有和媒体信息相关的元数据(视频、音频的时间戳、样本表等)都存储在这个盒子内。 
- 
这个盒子是解析 MP4 文件的关键。 
- 
moov盒子通常由多个子盒子组成:- 
mvhd(Movie Header Box) :包含整个媒体文件的全局信息,比如时间长度和时间单位。
- 
trak(Track Box) :每个trak盒子描述一个媒体轨道(如视频、音频、字幕)。每个trak盒子又包含:- 
tkhd(Track Header Box) :包含该轨道的标头信息,比如轨道ID、宽高、时间等。
- 
mdia(Media Box) :描述该轨道的媒体信息,包括媒体类型、解码时间等。
- 
mdhd(Media Header Box) :该轨道的时间基(timescale)、持续时间(duration)等信息。
- 
minf(Media Information Box) :存储与该轨道的媒体数据相关的信息,具体的解码、合成、播放等。- stbl(Sample Table Box) :包含该轨道的样本表,帮助定位和解析样本数据(如视频帧、音频帧)。
 
 
- 
 
- 
3. mdat(Media Data Box)
- 存储实际的音视频数据。所有媒体数据(例如视频帧、音频帧)都保存在这个盒子中。
- mdat盒子可能会非常大,因为它存储了所有的实际媒体内容(如音频流、视频帧)。
- 它的内容通常与 moov盒子中的元数据相对应。例如,moov中的样本表会指向mdat中的实际数据位置。
4. free 和 skip(Free Space Boxes)
- 这些盒子通常用于占位,它们不存储实际的数据,只是为了方便文件调整大小或进行编辑操作。
5. udta(User Data Box)
- 这是用户定义的数据区,可以包含一些额外的信息,比如版权信息或其他自定义数据。
6. mvex(Movie Extends Box)
- 在分段 MP4 文件中,mvex盒子用来支持片段式播放。
7. moof(Movie Fragment Box)
- 这是用于分段播放的 MP4 文件结构的一部分。与 moov类似,但moof盒子用于描述文件的分段部分。
8. stbl(Sample Table Box)
- 
存储有关如何访问 mdat中的媒体数据的信息,包括:- stts(Time to Sample Box) :存储时间戳信息,用于将解码时间戳 (DTS) 转换为展示时间戳 (PTS)。
- stsc(Sample to Chunk Box) :说明样本如何分块。
- stsz(Sample Size Box) :说明每个样本的大小。
- stco或- co64(Chunk Offset Box) :提供块在- mdat中的偏移量。
 
9. ctts(Composition Time to Sample Box)
- 提供样本的 CTS(Composition Time Stamp,合成时间戳)信息,帮助正确同步视频播放。
- 它将 DTS(解码时间戳)转换为 PTS(展示时间戳),用于处理视频帧的顺序。
10. sidx(Segment Index Box)
- 在分段 MP4 文件中,sidx盒子包含分段信息,用于 DASH(动态自适应流式传输)等技术。
常见时间戳:CTS 和 DTS
在 MP4 文件中,视频和音频流中的每个帧都有两个时间戳:
- DTS(Decoding Time Stamp,解码时间戳) :指示解码器何时应该解码这一帧。DTS 用于处理帧的解码顺序。
- CTS(Composition Time Stamp,合成时间戳) :指示这一帧在时间轴上的实际展示时间。CTS 用于播放顺序。
帧可以按照 DTS 的顺序被解码,但它们按照 CTS 的顺序被展示。这在视频中帧间重排时尤为重要(例如使用 B-帧的场景)。
盒子总括
            
            
              javascript
              
              
            
          
            BASIC_BOXES: [ "mdat", "idat", "free", "skip", "meco", "strk" ],
	FULL_BOXES: [ "hmhd", "nmhd", "iods", "xml ", "bxml", "ipro", "mere" ],
	CONTAINER_BOXES: [
		[ "moov", [ "trak", "pssh" ] ],
		[ "trak" ],
		[ "edts" ],
		[ "mdia" ],
		[ "minf" ],
		[ "dinf" ],
		[ "stbl", [ "sgpd", "sbgp" ] ],
		[ "mvex", [ "trex" ] ],
		[ "moof", [ "traf" ] ],
		[ "traf", [ "trun", "sgpd", "sbgp" ] ],
		[ "vttc" ],
		[ "tref" ],
		[ "iref" ],
		[ "mfra", [ "tfra" ] ],
		[ "meco" ],
		[ "hnti" ],
		[ "hinf" ],
		[ "strk" ],
		[ "strd" ],
		[ "sinf" ],
		[ "rinf" ],
		[ "schi" ],
		[ "trgr" ],
		[ "udta", ["kind"] ],
		[ "iprp", ["ipma"] ],
		[ "ipco" ],
		[ "grpl" ],
		[ "j2kH" ],
		[ "etyp", [ "tyco"] ]
	],如何解析?
- 使用ffmpeg
- js中可以使用MP4box.js解析gpac.github.io/mp4box.js/t... (裂墙推荐这个库 很牛回复问题也很快。js中学习MP4的必备库)
总结
比较棘手,但是需要一点一点吃透,才能是前端音视频入门。