on
MP4 解析
概念
wiki mp4 是 MPEG-4 Part 14 的简称。更确切的描述是 mp4 是一种多媒体文件格式,该文件格式的详细定义位于 MPEG-4 Part 14,而具体音视频等具体内容仍散落于 MPEG-4 的其他 Part 中。
MPEG
MPEG(Moving Picture Experts Group),一个专家组, 官网地址 - mpeg。该组织自己的描述是“MPEG 是 ISO/IEC 的一个工作组,负责音视频的解压缩相关的标准制定”。所有关于该工作组的协议标准在 mpeg standards。
所以不止有 MPEG-4,还有 MPEG-1、MPEG-2、MPEG-DASH、MP3、AAC 等(具体相关个格式后续文章会逐步补充),简述如下图表:
标准 | 视频编码 | 音频编码 | 主要用途 | 压缩效率 |
---|---|---|---|---|
MPEG-1 | 基本压缩 | MP3 | VCD,早期多媒体 | 低 |
MPEG-2 | 标清/高清 | Dolby Digital, AAC | DVD、数字电视 | 中等 |
MPEG-4 Part 2 | DivX, Xvid | AAC | 互联网视频,移动设备 | 中等 |
H.264/AVC | 高效视频压缩 | AAC | 流媒体、高清视频 | 高 |
H.265/HEVC | 超高效视频压缩 | AAC 或其他 | 4K/8K 视频,VR/AR 内容 | 更高 |
MPEG-H | HEVC, 3D Audio | MPEG-H Audio | UHD、沉浸式多媒体体验 | 非常高 |
MPEG-DASH | 无特定编码 | 任意兼容音视频格式 | 流媒体传输 | 取决于编码 |
MPEG-4
MPEG-4,针对固定、移动设备的多媒体协议。目前共有 34 个 Part,简述如下图表:
Part n | 名称 | 简介 |
---|---|---|
Part 1 | Systems | 描述多媒体内容的系统层,包括时间同步、对象描述和流媒体传输。 |
Part 2 | Visual | 定义视频编码格式,支持基于对象的编码,早期支持 DivX 和 Xvid 等视频技术。 |
Part 3 | Audio | 定义音频编码格式,如 AAC 和 ALS,支持语音合成、无损音频和 3D 音频。 |
Part 4 | Conformance Testing | 提供标准一致性测试,用于验证编码器和解码器的兼容性和正确性。 |
Part 5 | Reference Software | 提供参考实现软件,展示标准功能的具体实现方法。 |
Part 6 | Delivery Multimedia Integration Framework | 定义用于多媒体数据传输的框架和协议。 |
Part 7 | Optimized Reference Software | 提供优化后的参考软件,更适合具体应用场景。 |
Part 8 | Intellectual Property Management and Protection (IPMP) | 描述知识产权管理和保护的机制,包括加密和内容权限管理。 |
Part 9 | Reference Hardware Description | 提供硬件实现的参考描述,帮助开发者设计硬件加速方案。 |
Part 10 | Advanced Video Coding (AVC) | 定义 H.264 视频编码标准,提供高效的视频压缩技术。 |
Part 11 | Scene Description and Application Engine | 定义场景描述和应用引擎,包括 2D/3D 场景的描述和对象间交互。 |
Part 12 | ISO Base Media File Format | 定义基础媒体文件格式,是 MP4 文件格式的基础。 |
Part 13 | Carriage of ISO Base Media File Format Over IP | 定义通过 IP 网络传输 ISO 基础媒体文件格式的技术。 |
Part 14 | MP4 File Format | 定义 MP4 文件容器格式,支持音频、视频、字幕和元数据的封装。 |
Part 15 | Advanced Video Coding File Format | 为 AVC/H.264 定义文件格式支持,增强 MP4 对高效视频编码的适配性。 |
Part 16 | Animation Framework Extension (AFX) | 提供动画框架扩展,支持复杂的 2D 和 3D 动画场景。 |
Part 17 | Timed Text | 定义定时文本格式,用于字幕和多语言显示。 |
Part 18 | Font Compression and Streaming | 描述字体压缩和流式传输的方法,适合网络环境使用。 |
Part 19 | Synthesized Texture | 定义合成纹理编码,用于图形和纹理生成。 |
Part 20 | Lightweight Application Scene Representation (LASeR) | 为移动和嵌入式设备提供轻量级场景描述和交互支持。 |
Part 21 | MPEG-J Graphics Framework | 定义基于 Java 的图形框架,用于互动多媒体应用开发。 |
Part 22 | Open Font Format | 描述开放字体格式,支持复杂的文字显示需求。 |
Part 23 | Symbolic Music Representation | 定义符号音乐表示法,用于音乐内容的编码和存储。 |
Part 24 | Audio and Systems Part of Error Resilient Coding | 描述在错误环境下的音频和系统部分的弹性编码技术。 |
Part 25 | Visual Part of Error Resilient Coding | 定义视频在传输错误情况下的弹性编码技术。 |
Part 26 | MPEG-4 Part 26 Multimedia Content Description Interface | 提供多媒体内容描述接口,用于检索和分类内容。 |
Part 27 | 3D Graphics Compression | 定义 3D 图形的压缩技术,用于虚拟现实和游戏场景。 |
Part 28 | Intellectual Property Rights Description | 描述数字版权的管理方法,扩展 IPMP 的功能。 |
Part 29 | Adaptive Audio Streaming | 定义音频的自适应流技术,适应不同带宽的网络环境。 |
Part 30 | Media Transport | 提供多媒体内容的传输协议,用于高效内容分发。 |
Part 31 | Multi-view Video Coding | 支持多视图视频编码,用于 3D 视频和多摄像头系统。 |
Part 32 | Stereoscopic Video Coding | 定义立体视频编码,用于 3D 内容显示和传输。 |
Part 33 | Green MPEG | 优化视频编码以减少能耗,适用于绿色节能应用。 |
Part 34 | Compact Descriptors for Visual Search | 定义视觉搜索的紧凑描述符,用于多媒体检索和分类。 |
其中重要部分如 Part 14(mp4 文件格式)、Part 4(音频格式)、Part 2(各种视觉信息的编解码格式)、Part 10(H.264 编码)、Part 12(ISO 媒体文件格式)等,后续会逐 Part 详述。
一些 Helper
- 相关的协议具体内容也通过搜索 “ISO/IEC 14496-14” 来获取。 iso 官网,很多协议都是收费的,但是呢,可以搜搜咸鱼和淘宝(注意版本)~~
- 为了读者方便,可直接下载示例文件:big_buck_bunny.mp4,通过 mp4box file reader 在线解析,方便可视化观看。
- Mac 下可使用 Hex Fiend 直接打开 mp4 文件,看看该文件具体的内容是什么,对比在线解析及文档,可以更直接的了解格式内容
- 还可以参考 sannies-mp4parser ,看一下别人是怎么解析 mp4 文件的(不过 Java 看这种结构真的是太冗杂了,暂时没找到更清晰的示例~)
MP4 文件格式
整体结构概览
- ftyp * 4.3 file type and compatibility
- pdin 8.1.3 progressive download information
- moov * 8.2.1 container for all the metadata
- mvhd * 8.2.2 movie header, overall declarations
- meta 8.11.1 metadata
- trak * 8.3.1 container for an individual track or stream
- tkhd * 8.3.2 track header, overall information about the track
- tref 8.3.3 track reference container
- trgr 8.3.4 track grouping indication
- edts 8.6.4 edit list container
- elst 8.6.6 an edit list
- meta 8.11.1 metadata
- mdia * 8.4 container for the media information in a track
- mdhd * 8.4.2 media header, overall information about the media
- hdlr * 8.4.3 handler, declares the media (handler) type
- elng 8.4.6 extended language tag
- minf * 8.4.4 media information container
- vmhd 12.1.2 video media header, overall information (video track only)
- smhd 12.2.2 sound media header, overall information (sound track only)
- hmhd 12.4.2 hint media header, overall information (hint track only)
- sthd 12.6.2 subtitle media header, overall information (subtitle track only)
- nmhd 8.4.5.2 Null media header, overall information (some tracks only)
- dinf * 8.7.1 data information box, container
- dref * 8.7.2 data reference box, declares source(s) of media data in track
- stbl * 8.5.1 sample table box, container for the time/space map
- stsd * 8.5.2 sample descriptions (codec types, initialization etc.)
- stts * 8.6.1.2 (decoding) time-to-sample
- ctts 8.6.1.3 (composition) time to sample
- cslg 8.6.1.4 composition to decode timeline mapping
- stsc * 8.7.4 sample-to-chunk, partial data-offset information
- stsz 8.7.3.2 sample sizes (framing)
- tz2 8.7.3.3 compact sample sizes (framing)
- stco * 8.7.5 chunk offset, partial data-offset information
- co64 8.7.5 64-bit chunk offset
- stss 8.6.2 sync sample table
- stsh 8.6.3 shadow sync sample table
- padb 8.7.6 sample padding bits
- stdp 8.7.6 sample degradation priority
- sdtp 8.6.4 independent and disposable samples
- sbgp 8.9.2 sample-to-group
- sgpd 8.9.3 sample group description
- subs 8.7.7 sub-sample information
- saiz 8.7.8 sample auxiliary information sizes
- saio 8.7.9 sample auxiliary information offsets
- udta 8.10.1 user-data
- mvex 8.8.1 movie extends box
- mehd 8.8.2 movie extends header box
- trex * 8.8.3 track extends defaults
- leva 8.8.13 level assignment
- moof 8.8.4 movie fragment
- mfhd * 8.8.5 movie fragment header
- meta 8.11.1 metadata
- traf 8.8.6 track fragment
- tfhd * 8.8.7 track fragment header
- trun 8.8.8 track fragment run
- sbgp 8.9.2 sample-to-group
- sgpd 8.9.3 sample group description
- subs 8.7.7 sub-sample information
- saiz 8.7.8 sample auxiliary information sizes
- saio 8.7.9 sample auxiliary information offsets
- tfdt 8.8.12 track fragment decode time
- meta 8.11.1 metadata
- mfra 8.8.9 movie fragment random access
- tfra 8.8.10 track fragment random access
- mfro * 8.8.11 movie fragment random access offset
- mdat 8.2.2 media data container
- free 8.1.2 free space
- skip 8.1.2 free space
- udta 8.10.1 user-data
- cprt 8.10.2 copyright etc.
- tsel 8.10.3 track selection box
- strk 8.14.3 sub track box
- stri 8.14.4 sub track information box
- strd 8.14.5 sub track definition box
- udta 8.10.1 user-data
- meta 8.11.1 metadata
- hdlr * 8.4.3 handler, declares the metadata (handler) type
- dinf 8.7.1 data information box, container
- dref 8.7.2 data reference box, declares source(s) of metadata items
- iloc 8.11.3 item location
- ipro 8.11.5 item protection
- sinf 8.12.1 protection scheme information box
- frma 8.12.2 original format box
- schm 8.12.5 scheme type box
- schi 8.12.6 scheme information box
- sinf 8.12.1 protection scheme information box
- iinf 8.11.6 item information
- xml 8.11.2 XML container
- bxml 8.11.2 binary XML container
- pitm 8.11.4 primary item reference
- fiin 8.13.2 file delivery item information
- paen 8.13.2 partition entry
- fire 8.13.7 file reservoir
- fpar 8.13.3 file partition
- fecr 8.13.4 FEC reservoir
- segr 8.13.5 file delivery session group
- gitn 8.13.6 group id to name
- paen 8.13.2 partition entry
- idat 8.11.11 item data
- iref 8.11.12 item reference
- meco 8.11.7 additional metadata container
- mere 8.11.8 metabox relation
- meta 8.11.1 metadata
- mere 8.11.8 metabox relation
- styp 8.16.2 segment type
- sidx 8.16.3 segment index
- ssix 8.16.4 subsegment index
- prft 8.16.5 producer reference time
直接拷贝自协议,大家想看的还是去看协议本身吧(有 * 号的表示必须存在的)
简要结构如下:
- ftyp(File Type Box),文件类型信息
- moov(Movie Box),原信息,轨道信息等
- mvhd(Movie Header)
- trak(Track Box)
- tkhd
- media
- mdhd(Media Header Box)
- hdlr(Handler Box)
- elng
- minf(Media Information Box)
- vmhd
- smhd (Sound Media Header Box)
- stbl (Sample Table Box)
- stsd (Sample Description Box)
- stts (Time-to-Sample Box)
- stsc (Sample-to-Chunk Box)
- stsz (Sample Size Box)
- stco (Chunk Offset Box)
- free/skip,占位符(8 字节长度)
- mdat(Media Data Box),实际音视频数据
每个 Box 的结构如下:
Box Size(4 字节):表示该 Box 的大小(包括 header 和 data)。
Box Type(4 字节):标识 Box 类型,例如 ftyp、moov。
Box Data(可变长度):存储具体内容。
以示例文件为例:
ftyp Box 信息:00000018 66747970 6D703432 00000001 6D703432 61766331
,表示该 Box 大小为 00000018
(即 24 Bytes),后续内容为 ftypmp42
、1
、mp42
、avc1
moov Box 信息:000090CA 6D6F6F76..
,表示该 Box 大小为 000090CA
(即 37066 Bytes),后续内容为 moov
….
mdat Box 信息:005385E6 6D646174..
,表示该 Box 大小为 005385E6
,后续内容为 mdat
…
trak Box
轨道,相信大家都听过“音轨”这个词。
具体类型可由 trak Box
中的 media
中的 hdlr
的 handler_type
字段解析得到,常见的类型如下:
处理器类型(Handler Type) | 轨道类型 | 描述 |
---|---|---|
vide |
视频轨道 | 用于存储视频数据(例如 H.264、HEVC)。 |
soun |
音频轨道 | 用于存储音频数据(例如 AAC、MP3)。 |
text |
字幕轨道 | 用于存储字幕或文本数据。 |
hint |
提示轨道(网络流轨道) | 用于描述与流媒体播放相关的提示数据(如流式传输信息)。 |
midi |
MIDI 轨道 | 用于存储 MIDI 数据。 |
clean |
清晰轨道 | 用于存储未经过处理的清晰数据,通常用于专业视频编辑。 |
meta |
元数据轨道 | 存储与媒体相关的元数据或附加信息,常见于多媒体容器中。 |
以“音轨”为例,具体信息(时长、媒体类型、采样信息等)存储在 moov 中,而音频的实际数据(即音频内容的比特流)则存储在 mdat 中。而其关联则是通过 stbl
来索引的。
比如示例文件,stbl
中的 stsd
中包含 mp4a
,及表示该音频类型为 aac
,其音频流的参数(声道、采样率等)则存储与 esds
中。
同样,视频信息也可以在对应 tack 中的 stsd
中找到,示例文件则为 avc1
。
其他
关于 mp4 的加载速度问题
很多年前在某教育公司做点播视频的时候,有讨论为什么不使用 mp4 而是 m3u8,当时看到有人说 mp4 加载慢,具体原因不明就里。
其实当时问题的核心就是播放是需要 moov 的,而 moov 很多时候被放在了视频数据的末尾(即 mdat 之后),那就必须加载完 moov 才能正确索引到 mdat 中的数据,也因为此造成加载慢。
解决方案就是将 moov 部分提前就可以。但是即使如此,如文中示例,moov 部分仍然有 37k,所以首次加载效率其实依然不高。
至于各种格式的流媒体加载效率及加载过程中具体的逻辑是什么,会放到后续的文章中~
参考
- ffmpeg开发——深入理解MP4文件格式
- MP4格式详解
- ChatGPT