前言
MP4标准是一种视频的封装格式(关于封装格式,可以看前一篇笔记 音视频编码基础),是在前端视频点播中比较常见的一种格式。MP4是一种比较全面的容器,可以封装很多种类型的音频和视频,比较常见的是H.264(AVC)视频+AAC音频 的搭配。今天我们来简单学习一下MP4的格式,为后续音视频学习打下基础。
MP4格式
基本概念
Sample:采样,对于视频来说,可以理解为视频的一帧。对于音频来说,代表一小段音频数据。
Chunk:连续好几个Sample组成一个chunk,一小段视频
Track:连续的chunk组成一个Track,代表一个视频或者一个音频序列。常见的视频轨音频轨即为Track的一种
组成结构
MP4由多个box组成,box之间呈树状结构组织息。box有好多种,不同的box携带不同的信息。并且box还可以包含box,称为container box。还有一种特殊的full box,用于moov
每个box由两部分组成:
box header:携带box元数据
box body:实际的box数据,实际存储内容和box的类型有关
常见的box如下表
类型有很多,我们挑常用的来学习
顶层box-moov
Movie Box,存储 mp4 的 metadata,一般位于mp4文件的开头,有且仅有一个。
moov.mvhd
mp4文件的整体信息,比如创建和修改时间、文件时长等,仅有一个
moov.trak
记录每个track的元信息,是个container box,我们主要看子box
moov.trak.tkhd
分别记录每个track的整体信息,例如当前轨道的id,对于视频轨的宽高、所处层级,对于音频轨的音量大小等。数量对应track的数量。
每个Track Box都需要有一个tkhd box和mdia Box,其它的box都是可选择的
moov.trak.mdia
Track媒体头信息以及媒体信息,是个container box,我们主要看子box
moov.trak.mdia.hdlr
声明当前track的类型,以及对应的处理器(handler),包括三种:vide (video track)、soun(sound track)、hint(hint track)
moov.trak.mdia.mdhd
定义了该Track的媒体头信息,我们主要关心timescale和duration,分辨表示了时间戳和时长,这个时间戳也是PTS和DTS的单位
moov.trak.mdia.minf
该box建立了时间到真实音视频sample的映射关系,是moov中最重要的box,也是音视频数据操作的关键。
moov.trak.mdia.minf.stbl
媒体流每一个sample在文件中的offset,pts,duration等信息,播放时需要根据stbl找到正确对应的sample送给解码器
moov.trak.mdia.minf.stbl.stsd
Sample Description Box,一个非常复杂的container box,有很多子box。存放解码必须的描述信息,给出视频、音频的编码、宽高、音量等信息,以及每个sample中包含多少个frame
moov.trak.mdia.minf.stbl.stco
每个chunk在文件中的偏移位置,注意是在整个文件中的偏移位置,而不是在box中的
moov.trak.mdia.minf.stbl.stsc
sample 以 chunk 为单位分成多个组,stsc记录sample-chunk的映射表,记录sample所在chunk,包括共有几个chunk,每个chunk有几个sample
moov.trak.mdia.minf.stbl.stsz
可以推导出每个sample的大小,单位是字节。
stsz+stsc+stco结合可以推导出每个sample在文件中的位置,从而取出正确的sample
moov.trak.mdia.minf.stbl.stts
DTS到sample number的映射表,主要用来推导每个sample的时长
moov.trak.mdia.minf.stbl.stss
存放关键帧列表,记录哪个sample是关键帧。如果每个都是关键帧的话则不存在此box
moov.trak.mdia.minf.stbl.ctts
时间偏移记录表,记录PTS和DTS,当PTS与DTS不一致时(有B帧)存在此box
顶层box-mdat
mdat box存储真实的媒体数据,根据moov box中的数据,计算出偏移量和size从mdat box的数据中获取对应的帧
MP4Box
在前端我们可以使用mp4box.js来解析MP4文件,可以解析box结构或者提取MP4的视频流,官方也提供了在线工具gpac.github.io/mp4box.js/t…