目录
一、基本概念
1 mp4概述
MP4文件中的所有数据都装在box(QuickTime中为atom)中,也就是说MP4文件由若干个box组成,每个box有类型和长度,可以将box理解为一个数据对象块。box中可以包含另一个box,这种box称为container box。一个MP4文件首先会有且只有一个“ftyp”类型的box,作为MP4格式的标志并包含关于文件的一些信息;之后会有且只有一个“moov”类型的box(Movie Box),它是一种container box,子box包含了媒体的metadata信息;MP4文件的媒体数据包含在“mdat”类型的box(Midia
Data Box)中,该类型的box也是container box,可以有多个,也可以没有(当媒体数据全部引用其他文件时),媒体数据的结构由metadata进行描述。
track 表示一些sample的集合,对于媒体数据来说,track表示一个视频或音频序列。
hint track 这个特殊的track并不包含媒体数据,而是包含了一些将其他数据track打包成流媒体的指示信息。
sample 对于非hint track来说,video sample即为一帧视频,或一组连续视频帧,audio sample即为一段连续的压缩音频,它们统称sample。对于hint track,sample定义一个或多个流媒体包的格式。
sample table 指明sampe时序和物理布局的表。
chunk 一个track的几个sample组成的单元。
2、Box
首先需要说明的是,box中的字节序为网络字节序,也就是大端字节序(Big-Endian),简单的说,就是一个32位的4字节整数存储方式为高位字节在内存的低端。Box由header和body组成,其中header统一指明box的大小和类型,body根据类型有不同的意义和格式。
标准的box开头的4个字节(32位)为box size,该大小包括box header和box body整个box的大小,这样我们就可以在文件中定位各个box。如果size为1,则表示这个box的大小为large size,真正的size值要在largesize域上得到。(实际上只有“mdat”类型的box才有可能用到large size。)如果size为0,表示该box为文件的最后一个box,文件结尾即为该box结尾。(同样只存在于“mdat”类型的box中。)
size后面紧跟的32位为box type,一般是4个字符,如“ftyp”、“moov”等,这些box type都是已经预定义好的,分别表示固定的意义。如果是“uuid”,表示该box为用户扩展类型。如果box type是未定义的,应该将其忽略
(1、 mp4文件由许多Box和FullBox组成。
(2、 Box,每个Box由Header和Data组成。
(3、 FullBox,是Box的扩展,Box结构的基础上在Header中增加8bits version和24bits flags。
(4、 Header,包含了整个Box的长度size和类型type。当size==0时,代表这是文件中最后一个Box;当size==1时,意味着Box长度需要更多bits来描述,在后面会定义一个64bits的largesize描述Box的长度;当type是uuid时,代表Box中的数据是用户自定义扩展类型。
(5、 Data,是Box的实际数据,可以是纯数据也可以是更多的子Boxes。
(6、 当一个Box的Data中是一系列子Box时,这个Box又可成为Container Box。当一个Box里面不包含子Box时,这个Box称为leaf Box,而FullBox是mp4格式协议规定的某些特殊的Box。
3 MP4三种组织方式
(1)普通MP4,General MP4,box模式为ftyp-mdat-moov。头在后面,FFMPEG默认出的就是这种,写入比较简单。读取时需要seek;所以有些浏览器会需要完全下载后才能开始播放,有些应该可以用HTTP RANGE跳过mdat读取moov。SRS录制MP4文件可以用这种模式。
(2)快速MP4,Faststart MP4,box模式为ftyp-moov-mdat。头在前面,FFMEPG需要指定参数,生成MP4后,再过一遍文件才能支持。比上面的对于某些浏览器会比较友好,但是就需要再过一遍文件。对于SRS录制成MP4文件而言,容易造成IO阻塞(等待的时间过长,导致服务线程挂起,具体看ST的实现,不可以长时间的做CPU操作或者磁盘操作)。
(3)切片MP4或FMP4,Fragmented MP4,box模式为ftyp-moov-moof-mdat,视频/音频 metadata 信息与数据都存在一个个 moof、mdat 中,它是一个流式的封装格式。分段模式,浏览器H5直接播放时,有些能播,有些不行。这种一般用在DASH中,不会直接用浏览器播放,而是通过JS解析后,给MSE播放(APPEND到Video对象的Buffer中去,具体参考MSE的文章)。FFMPEG也是需要指定参数才能生成。这种对于流媒体比较合适,SRS生成DASH可以用这种。
注意:
1)MP4中所有的序号都是从1开始:比如track_ID、chunk序号、sample序号都是从1开始
MP4支持可变码率,可变帧率,通过stsc中sample_description_index的需要来决定chunk使用哪个stsd来进行编解码
2)普通mp4用于点播,fmp4通常用于直播,文件结构一样,主要有以下差别:
(1)普通mp4的时长、内容通常是固定的。fMP4 时长、内容通常不固定,可以边生成边播放;
(2)普通mp4完整的metadata都在moov里,需要加载完moov box后,才能对mdat中的媒体数据进行解码渲染;FMP4中,媒体数据的metadata在moof box(Movie Fragment Box)中,moof 跟 mdat (通常)结对出现。moof 中包含了sample duration、sample size等信息,因此,fMP4可以边生成边播放;
(3)普通mp4和fMP4区分:一般可以看下是否存在存在mvex box(Movie Extends Box)。当存在mvex时,表示当前文件是fmp4(非严谨)。此时,sample相关的metadata不在moov里,需要通过解析moof box来获得。
二、MP4文件格式详解(ISO-14496-12/14)
文件解析工具:
MP4Box.js - JavaScript MP4 Reader/Fragmenter
mp4info,mp4explorer等。
MP4文件就是由各式各样的Box组成的,√代表Box必选。
ftyp | √ | file type and compatibility | |||||
pdin | progressive download information | ||||||
moov | √ | container for all the metadata | |||||
mvhd | √ | movie header, overall declarations | |||||
trak | √ | container for an individual track or stream | |||||
tkhd | √ | track header, overall information about the track | |||||
tref | track reference container | ||||||
edts | edit list container | ||||||
elst | an edit list | ||||||
mdia | √ | container for the media information in a track | |||||
mdhd | √ | media header, overall information about the media | |||||
hdlr | √ | handler, declares the media (handler) type | |||||
minf | √ | media information container | |||||
vmhd | video media header, overall information (video track only) | ||||||
smhd | sound media header, overall information (sound track only) | ||||||
hmhd | hint media header, overall information (hint track only) | ||||||
nmhd | Null media header, overall information (some tracks only) | ||||||
dinf | √ | data information box, container | |||||
dref | √ | data reference box, declares source(s) of media data in track | |||||
stbl | √ | sample table box, container for the time/space map | |||||
stsd | √ | sample descriptions (codec types, initialization etc.) | |||||
stts | √ | (decoding) time-to-sample | |||||
ctts | (composition) time to sample | ||||||
stsc | √ | sample-to-chunk, partial data-offset information | |||||
stsz | sample sizes (framing) | ||||||
stz2 | compact sample sizes (framing) | ||||||
stco | √ | chunk offset, partial data-offset information | |||||
co64 | 64-bit chunk offset | ||||||
stss | sync sample table (random access points) | ||||||
stsh | shadow sync sample table | ||||||
padb | sample padding bits | ||||||
stdp | sample degradation priority | ||||||
sdtp | independent and disposable samples | ||||||
sbgp | sample-to-group | ||||||
sgpd | sample group description | ||||||
subs | sub-sample information | ||||||
mvex | movie extends box | ||||||
mehd | movie extends header box | ||||||
trex | √ | track extends defaults | |||||
ipmc | IPMP Control Box | ||||||
moof | movie fragment | ||||||
mfhd | √ | movie fragment header | |||||
traf | track fragment | ||||||
tfhd | √ | track fragment header | |||||
trun | track fragment run | ||||||
sdtp | independent and disposable samples | ||||||
sbgp | sample-to-group | ||||||
subs | sub-sample information | ||||||
mfra | movie fragment random access | ||||||
tfra | track fragment random access | ||||||
mfro | √ | movie fragment random access offset | |||||
mdat | media data container | ||||||
free | free space | ||||||
skip | free space | ||||||
udta | user-data | ||||||
cprt | copyright etc. | ||||||
meta | metadata | ||||||
hdlr | √ | handler, declares the metadata (handler) type | |||||
dinf | data information box, container | ||||||
dref | data reference box, declares source(s) of metadata items | ||||||
ipmc | IPMP Control Box | ||||||
iloc | item location | ||||||
ipro | item protection | ||||||
sinf | protection scheme information box | ||||||
frma | original format box | ||||||
imif | IPMP Information box | ||||||
schm | scheme type box | ||||||
schi | scheme information box | ||||||
iinf | item information | ||||||
xml | XML container | ||||||
bxml | binary XML container | ||||||
pitm | primary item reference | ||||||
fiin | file delivery item information | ||||||
paen | partition entry | ||||||
fpar | file partition | ||||||
fecr | FEC reservoir | ||||||
segr | file delivery session group | ||||||
gitn | group id to name | ||||||
tsel | track selection | ||||||
meco | additional metadata container | ||||||
mere | metabox relation |
1、 ftyp box,在文件的开始位置,描述的文件的版本、兼容协议等;
2、 moov box,这个box中不包含具体媒体数据,但包含本文件中所有媒体数据的宏观描述信息,moov box下有mvhd和trak box。
>>mvhd中记录了创建时间、修改时间、时间度量标尺、可播放时长等信息。
>>trak中的一系列子box描述了每个媒体轨道的具体信息。
3、 moof box,这个box是视频分片的描述信息。并不是MP4文件必须的部分,但在我们常见的可在线播放的MP4格式文件中(例如Silverlight Smooth Streaming中的ismv文件)确是重中之重。
4、 mdat box,实际媒体数据。我们最终解码播放的数据都在这里面。
5、 mfra box,一般在文件末尾,媒体的索引文件,可通过查询直接定位所需时间点的媒体数据。