MP4格式详解
一、MP4基本结构
MP4由多个Box组成,Box又由Header和Data组成。
Header:包含Box的类型(type)和大小(size);当size为0时,表示文件中的最后一个Box;当size为1时,会定义largesize描述Box长度;当type为UUID时,表示Box是用户自定义扩展类型。
Data:包含Box的实际数据,可以是纯数据或者是子Box;其中包含子Box的又称为Container Box。
FullBox:Box扩展,Box结构基础上在Header照片那个增加了8 bits version和24 bits flags。
Box的结构伪代码:
aligned(8) class Box (unsigned int(32) boxtype,optional unsigned int(8)[16] extended_type)
{
unsigned int(32) size;
unsigned int(32) type = boxtype;
if (size==1)
{
unsigned int(64) largesize;
}
else if (size==0)
{
// box extends to end of file
}
if (boxtype==‘uuid’)
{
unsigned int(8)[16] usertype = extended_type;
}
二、MP4 Box
1、MP4 Box
ftpy | file type and compatibility | MP4第一个Box,描述文件的类型、版本、兼容协议等 |
moov | container for all the metadata | 媒体文件的描述信息 |
mdata | media data container | 实际媒体数据 |
mfra | movie fragment random access | 一般在文件末尾,媒体的索引文件,可通过查询直接定位所需时间点的媒体数据 |
moof | movie fragement | 媒体分片文件(fmp4)的描述信息 |
2、ftyp Box
ftyp box通常放在文件的开始,通过对该box解析可以让我们的软件(播放器、demux、解析器)知道应该使用哪种协议对这该文件解析。
3、moov Box
媒体文件的描述信息。视频信息包括码率、帧率、分辨率、时长、色域、位深等;音频信息包括声道数、采样率等。
moov | ||
---|---|---|
mvhd | movie header, overall declarations | 包含媒体的创建和修改时间、时间刻度、默认音量、色域、可播放时长等信息。 |
trak | container for an individual track or stream | 包含每个媒体轨道(track)的描述信息;视频轨道、音频轨道、字幕轨道等 |
- mvhd伪代码
aligned(8) class MovieHeaderBox extends FullBox(‘mvhd’, version, 0)
{
if (version==1)
{
unsigned int(64) creation_time;
unsigned int(64) modification_time;
unsigned int(32) timescale; //时间刻度
unsigned int(64) duration; //播放时长
}
else
{ // version==0
unsigned int(32) creation_time;
unsigned int(32) modification_time;
unsigned int(32) timescale;
unsigned int(32) duration;
}
template int(32) rate = 0x00010000; // typically 1.0
template int(16) volume = 0x0100; // typically, full volume
const bit(16) reserved = 0;
const unsigned int(32)[2] reserved = 0;
template int(32)[9] matrix = { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };
// Unity matrix
bit(32)[6] pre_defined = 0;
unsigned int(32) next_track_ID;
}
- tkhd伪代码
aligned(8) class TrackHeaderBox extends FullBox(‘tkhd’, version, flags)
{
if (version==1)
{
unsigned int(64) creation_time;
unsigned int(64) modification_time;
unsigned int(32) track_ID;
const unsigned int(32) reserved = 0;
unsigned int(64) duration;
}
else
{ // version==0
unsigned int(32) creation_time;
unsigned int(32) modification_time;
unsigned int(32) track_ID;
const unsigned int(32) reserved = 0;
unsigned int(32) duration;
}
const unsigned int(32)[2] reserved = 0;
template int(16) layer = 0;
template int(16) alternate_group = 0;
template int(16) volume = {if track_is_audio 0x0100 else 0};
const unsigned int(16) reserved = 0;
template int(32)[9] matrix= { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };
// unity matrix
unsigned int(32) width;
unsigned int(32) height;
}
三、Sample Table Box 拓展
“stbl”几乎是普通的MP4文件中最复杂的一个box了,首先需要回忆一下sample的概念。sample是媒体数据存储的单位,存储在media的chunk中,chunk和sample的长度均可互不相同,如下图所示。
1、Sample Description Box(stsd)包含视频的编码类型、宽高、长度,音频的声道、采样等信息
box header和version字段后会有一个entry count字段,根据entry的个数,每个entry会有type信息,如“vide”、“sund”等,根据type不同sample description会提供不同的信息,例如对于video track,会有“VisualSampleEntry”类型信息,对于audio track会有“AudioSampleEntry”类型信息。
2、Time To Sample Box(stts)存储了sample的duration,描述了sample时序的映射方法,我们通过它可以找到任何时间的sample
“stts”可以包含一个压缩的表来映射时间和sample序号,用其他的表来提供每个sample的长度和指针。表中每个条目提供了在同一个时间偏移量里面连续的sample序号,以及samples的偏移量。递增这些偏移量,就可以建立一个完整的time to sample表。
上一篇: Python爬取m3u8格式视频并解密ts文件合并转为mp4格式
下一篇: Appium 混合H5