一、什么是MP4?
MP4是一套用于音频、视频信息的压缩编码标准,由国际标准化组织(ISO)和国际电工委员会(IEC)下属的“动态图像专家组”(Moving Picture Experts Group,即MPEG)制定,第一版在1998年10月通过,第二版在1999年12月通过。MPEG-4格式的主要用途在于网上流、光盘、语音发送(视频电话),以及电视广播。
MPEG-4包含了MPEG-1及MPEG-2的绝大部份功能及其他格式的长处,并加入及扩充对虚拟现实模型语言(VRML , VirtualReality Modeling Language)的支持,面向对象的合成档案(包括音效,视讯及VRML对象),以及数字版权管理(DRM)及其他互动功能。而MPEG-4比MPEG-2更先进的其中一个特点,就是不再使用宏区块做影像分析,而是以影像上个体为变化记录,因此尽管影像变化速度很快、码率不足时,也不会出现方块画面。
二、多媒体封装格式
多媒体封装格式(也叫容器格式),是指按照一定的规则,将视频数据、音频数据等,放到一个文件中。常见的 MKV、AVI 以及本文介绍的 MP4 等,都是封装格式。
MP4是最常见的封装格式之一,因为其跨平台的特性而得到广泛应用。MP4文件的后缀为.mp4,基本上主流的播放器、浏览器都支持MP4格式。
三、MP4文件的组织方式
MP4文件一般有3种组织方式
1.普通MP4
又称:General MP4,box模式为ftyp-mdat-moov
- 组织方式: ftyp-mdat-moov
- 特点: box的顺序是 ftyp(文件类型)在开头,mdat(媒体数据)紧接其后,最后是 moov(元数据)。 在播放视频时,由于 moov box位于文件尾部,需要在文件完全下载后才能开始播放。
- 适用场景: 适用于本地存储和播放场景,例如在存储于硬盘或 USB 设备上的视频文件。 不适合流媒体或点播服务,因为需要在传输完所有数据后才能解码播放。
2.快速MP4
又称:Faststart MP4,box模式为ftyp-moov-mdat
- 组织方式: ftyp-moov-mdat
- 特点: box的顺序是 ftyp(文件类型)在开头,紧接其后的是 moov(元数据),最后才是 mdat(媒体数据)。 这种配置方式允许视频播放器在下载文件的初期就可以访问到 moov box,从而提前开始播放,提供更快的启动时间。
- 适用场景: 适用于需要更快启动时间的场景,如网络流媒体和点播服务。 可以在视频文件尚未完全下载的情况下就开始播放,提升用户体验。
3.切片 MP4
又称:fMP4(Fragmented MP4)
- 组织方式: ftyp-moov-moof-mdat
- 特点: 多个 moof 和 mdat 片段存在于文件中,每个片段包括它自己的元数据和媒体数据。 支持动态打包和传输,适合流媒体传输。 允许在各种网络条件下实现更灵活的文件下载和播放。
- 适用场景: 主要用于自适应流媒体传输。 适合需要频繁切换码率和分辨率的网络环境,例如移动网络。 提供更加平滑和连续的播放体验,适应不同带宽和播放条件。
4、三种组织方式的联系
这三种组织方式都是基于 MP4容器格式,只是 box 的排列顺序不同,目的是为了适应不同的使用场景。它们都有相同的基本元素(ftyp、moov、mdat),只是添加了特定的box(如moof)来增强某些功能。
总结而言,这三种 MP4 组织方式通过不同的box排列方式和附加功能来优化特定的使用场景,普通MP4适用于本地存储和播放,快速MP4适用于快速启动的网络播放 (边下载边播放),而切片MP4则适用于自适应流媒体传输。
四、MP4封装格式
1、概览
MP4文件由多个box组成,每个box存储不同的信息,且box之间是树状结构,如下图所示。
box类型有很多,下面是3个比较重要的顶层box:
- ftyp:File Type Box,描述文件遵从的MP4规范与版本
- moov:Movie Box,媒体的metadata信息,有且仅有一个
- mdat:Media Data Box,存放实际的媒体数据,一般有多个
当然,还有其他的一些常用的box:
- mvhd(Movie Header Box):存储电影的基本信息,如创建时间、持续时间等。
- trak(Track Box):存储轨道信息,每个轨道包含一个或多个媒体数据的集合。
- tkhd(Track Header Box):存储轨道的基本信息。
- mdia(Media Information Box):存储媒体信息,包括媒体头信息、样本表、样本描述等。
- stbl(Sample Table Box):存储样本表信息,包括样本描述、样本大小、样本偏移等。
这些Box通过不同的组合和嵌套,构成了MP4文件的完整结构。每个Box都包含一个Header和一个Data部分,Header用于描述Box的类型、大小等信息,Data部分则存储实际的媒体数据或元数据
下图是一个典型mp4文件的基本结构:
2、MP4 box解析
mp4 封装格式采用称为 box 的结构来组织数据。结构如下:
+-+-+-+-+-+-+-+-+-+-+| header | body |+-+-+-+-+-+-+-+-+-+-+
其它所有 box 都在语法上继承自此基本 box 结构。
2.1 box header
box 分为普通 box 和 fullbox。
2.1.1 普通 box header
字段 | 类型 | 描述 |
size | 4 Bytes | 包含 box header 的整个 box 的大小 |
type | 4 Bytes | 4 个 ascii 值,如果是 "uuid",则表示此 box 为用户自定义,可忽略 |
large size | 8 Bytes | size=1 时才有的字段,用于扩展,例如 mdat box 会需要此字段 |
2.1.2 fullbox header
fullbox 在上面的基础上新增了 2 个字段
字段 | 类型 | 描述 |
version | 1 Bytes | 版本号 |
flags | 3 Bytes | 标识 |
2.2 box body
一个box可能会包含其它多个box,此种box称为container box。因此box body可能是一种具体box类型,也有可能是其它box。
下面,我们找一个mp4文件,用MP4info这个工具打开mp4,来看看具体的Box内容:
通过查看mp4文件的box的内容,我们大概可以总结出MP4以下几个特点:
- MP4文件就是由一个个Box组成,其中Box还可以相互嵌套,排列紧凑没有多的冗余数据
- Box类型并没有很多,主要是由必须的ftyp、moov、mdat组成,还有free,udta非必须box组成,即去掉这两种box对于播放音视频也没有啥影响
- Moov一般存储媒体元数据,比较复杂嵌套层次比较深
2.2.1 ftyp(File Type Box)
ftyp 一般出现在文件的开头,用来指示该 mp4 文件使用的标准规范:
字段 | 类型 | 描述 |
major_brand | 4 bytes | 主版本 |
minor_version | 4 bytes | 次版本 |
compatible_brands[] | 4 bytes | 指定兼容的版本,注意此字段是一个 list,即可以包含多个 4 bytes 版本号 |
刚才打开的mp4文件,其ftyp内容如下:
2.2.2 moov(Movie Box)
- moov是一个container box,一个文件只有一个,其包含的所有box用于描述媒体信息(metadata)
- moov的位置可以紧随着 ftyp 出现,也可以出现在文件末尾
- 由于是一个 container box,所以除了 box header,其 box body 就是其它的 box
子box:
- mvhd(moov header):用于简单描述一些所有媒体共享的信息
- trak:即 track,轨道,用于描述音频流或视频流信息,可以有多个轨道,如上出现了 2 次,分别表示一路音频和一路视频流
- udta(user data):用户自定义,可忽略
继续以上面打开的mp4文件为例,查看moov box
子Box:mvhd
用于简单描述一些所有媒体共享的信息。
子Box:trak
track,轨道,用于描述音频流或视频流信息,可以有多个轨道。
2.2.3 mvhd(Movie Header Box)
- mvhd 作为媒体信息的 header 出现(注意此header不是box header,而是moov媒体信息的header),用于描述一些所有媒体共享的基本信息。
- mvhd 语法继承自fullbox,注意下述示例出现的version和flags字段属于fullbox header。
Box Body:
2.2.4 trak(track Box)
- trak box 是一个 container box,其子 box 包含了该 track 的媒体信息
- 一个 mp4 文件可以包含多个 track,track之间是独立的,trak box 用于描述每一路媒体流
- 一般情况下有两个trak,分别对应音频流和视频流
继续以上面打开的mp4文件为例,查看trak box
从图上信息可以看到:
- tkhd(track header box):用于简单描述该路媒体流的信息,如时长,宽度等
- mdia(media box):用于详细描述该路媒体流的信息
- edts(edit Box):子Box为elst(Edit List Box),它的作用是使某个track的时间戳产生偏移
2.2.5 tkhd(track header box)
- tkhd 作为媒体信息的header出现(注意此 header 不是 box header,而是 track 媒体信息的 header),用于描述一些该track的基本信息。
- tkhd语法继承自fullbox,注意下述示例出现的version和flags 字段属于fullbox header
Box Body:
2.2.6 edts(edit Box)
它下边有一个elst(Edit List Box),它的作用是使某个track的时间戳产生偏移
- segment_duration: 表示该edit段的时长,以Movie Header Box(mvhd)中的timescale为单位,即 segment_duration/timescale = 实际时长(单位s)
- media_time: 表示该edit段的起始时间,以track中Media Header Box(mdhd)中的timescale为单位。如果值为-1(FFFFFF),表示是空edit,一个track中最后一个edit不能为空。
- media_rate: edit段的速率为0的话,edit段相当于一个”dwell”,即画面停止。画面会在media_time点上停止segment_duration时间。否则这个值始终为1
注意:
为使PTS从0开始,media_time字段一般设置为第一个CTTS的值,计算PTS和DTS的时候,他们分别都减去media_time字段的值就可以将PTS调整为从0开始的值。
如果media_time是从一个比较大的值,则表示要求PTS值大于该值时画面才进行显示,这时应该将第一个大于或等于该值的PTS设置为0,其他的PTS和DTS也相应做调整
2.2.7 mdia(media box)
- 定义了track媒体类型以及sample数据,描述sample信息
- 它是一个container box,它必须包含mdhd,hdlr 和 minf
从图上信息可以看到:
- mdhd(Media Header Box):用于简单描述该路媒体流的信息。
- hdlr(Handler Reference Box):主要定义了 track 类型。
- stbl(Media Information Box):用于描述该路媒体流的解码相关信息和音视频位置等信息
未完。。。