MP4 封装格式详解

MP4 封装格式详解

  • MP4 封装格式详解
    • 简介
    • 概念与术语
    • MP4 整体结构
    • Box 结构
      • Box Header
      • Box Data
    • MP4 典型 Box
      • ftyp(File Type Box)
      • moov(Movie Box)
        • mvhd(moov header)
        • trak
          • tkhd(track header box)
          • edts(edit Box)
          • mdia(media box)
        • udta(user data)
      • mdat(media data box)
      • free(free space box)
    • stbl(Sample Table Box)
      • MP4 中的 chunk 和 sample
      • stsd、stts、stss、ctts、stsc、stsz、stco 概述
      • stsd(Sample Description Box)
      • stts(Decoding Time to Sample Box)
      • stss(Sync Sample Box)
      • ctts(Composition Time to Sample Box)
      • stsc(Sample To Chunk Box)
      • stsz(Sample Size Boxes)
        • stsz
        • stz2
      • stco/co64(Chunk Offset Box)
    • MP4 音视频数据解析过程
    • MP4 的使用场景及优缺点
    • Q&A
      • metadata中的major_brand、minor_version、compatible_brands的作用都是什么?
      • 什么是isom?
      • hint track是什么?
      • 为什么mp4要采用这种chunk-sample这种方式进行逻辑上的存储呢?
      • 如何区分一个track描述的是视频流还是音频流?
    • 参考

MP4 封装格式详解

简介

MP4(MPEG-4 Part 14)是一种标准的数字多媒体容器格式,其扩展名为.mp4,以存储数字音频及数字视频为主,也可存储字幕和静止图像。

虽然被官方标准定义的唯一扩展名是.mp4,但第三方通常会使用各种扩展名来指示文件的内容:

  • 同时拥有音频视频的MPEG-4文件通常使用标准扩展名.mp4;
  • 仅有音频的MPEG-4文件会使用.m4a扩展名。

大部分数据可以通过专用数据流嵌入到MP4文件中,因此MP4文件中包含了一个单独的用于存储流信息的轨道。目前得到广泛支持的编解码器或数据流格式有:

视频格式:H.264/AVC、H.265/HEVC、VP8/9等。
音频格式:AAC、MP3、Opus等。

因其可容纳支持比特流的视频流(如高级视频编码),MP4可以在网络传输时使用流式传输。

在线解析 MP4 工具:
MP4box.js:https://gpac.github.io/mp4box.js/test/filereader.html
mp4parser:https://www.onlinemp4parser.com/

概念与术语

概念与术语是理解好MP4媒体封装格式和其操作算法的关键,为了方便了解MP4文件格式,需先了解以下几个概念与术语:

  1. Box:MP4文件是由一个个Box组成的,可以将其理解为一个数据块,它由Header+Data组成,Data 可以存储媒体元数据和实际的音视频码流数据。Box可直接存储数据块,也可包含其它Box,我们把包含其它Box的Box称为container box。
  2. Sample:可理解为采样,对于视频可理解为一帧数据,音频一帧数据就是一段固定时间的音频数据,可以由多个Sample数据组成,存储媒体数据的单位是sample。
  3. Chunk:连续几个sample组成的单元被称为chunk,每个chunk在文件中有一个偏移量,整个偏移量从文件头算起,在这个chunk内,sample是连续存储的。
  4. Track:表示一些chunk的集合,对于媒体数据而言就是一个视频序列或者音频序列,常说的音频/视频轨可对照该概念上。除了Video Track和Audio Track外,还可以有非媒体数据,比如Hint Track,这种类型的Track就不包含媒体数据,可以包含一些将其他数据打包成媒体数据的指示信息或者字幕信息。简单来说,Track是音视频中可以独立操作的媒体单位。

可理解为MP4文件中有多个Track,一个Track由多个Chunk组成,每个Chunk包含一组连续的Sample。例如视频流的一个Sample代表实际的nal数据,Chunk是数据存储的基本单位,它是一系列Sample数据的集合。

在这里插入图片描述

MP4 整体结构

MP4是一种描述较为全面的容器格式,被认为可以在其中嵌入任何形式的数据,以及各种编码的音视频。

MP4 文件由许多个 Box 和 FullBox 组成。每个Box 包含不同的信息, 这些 Box 以树形结构的方式组织。

每个 Box 由 Header 和 Data 两部分组成。Data 是 Box 的实际数据,可以是纯数据,也可以是更多的子 Box(这个 Box 称为 Container Box)。

FullBox 是 Box 的拓展,其在 Box 结构的基础上,在 Header 中添加 1 字节的 version 标志和 3 字节的 flags 标志。

Box Header 至少占 8 字节。第一个字段是 size,占 4 字节, 表示整个 Box 的大小。第二个字段是 type,占 4字节,表示 Box 的类型。当 size = 0 时,代表这是 MP4 文件的最后一个 Box,当 size = 1 时,说明 Box 长度需要更多位才能描述,在 type 后会定义一个 8 字节的 largesize 用来描述 Box 的长度。当 type = uuid 时,说明这个 Box 中的数据时用户自定义拓展类型。

在这里插入图片描述

在这里插入图片描述

下图是常见的 Box 的结构图,可用来大致了解MP4文件的构造:

在这里插入图片描述

一个 MP4 文件的典型结构如下:

  +-+-+-+-+-+-+-+-+-+-+-+-+-+|  ftyp  |  moov |  mdat  |+-+-+-+-+-+-+-+-+-+-+-+-+-+

其中:

  • ftyp(file type box):在文件的开始位置,记录一些兼容性信息,比如文件的版本、兼容协议等;
  • moov(movie box):音视频数据的metadata信息。这个box中不包含具体媒体数据,但包含本文件中所有媒体数据的宏观描述信息,moov box下有mvhd box和trak box。
    • mvhd 中记录了创建时间、修改时间、时间度量标尺、可播放时长等信息。
    • trak 中的一系列子box描述了每个媒体轨道的具体信息。
  • mdat(media data box):媒体负载,media 数据容器。我们最终解码播放的实际媒体数据都在这里面。

因为 MP4 标准中没有对 moov 和 mdat 的存放位置没有强制先后要求,所以它们的顺序不定。在互联网视频的点播中,如果希望 MP4 文件被快速打开,则需要将 moov 存放在 mdat 的前面;如果moov 放在 mdat 的后面,则需要将 MP4 文件全部下载完才可以播放。

常见 Box 的简要说明:

在这里插入图片描述

Box 结构

通过上面的介绍,我们了解了MP4格式就是由一个个的box组合成的box树,所有的数据都包含在box里,下面来了解一下box的基本结构。

一个box是由Header+Data组成。

  +-+-+-+-+-+-+-+-+-+-+|  Header  |  Data  |+-+-+-+-+-+-+-+-+-+-+

其它所有 box 都在语法上继承自此基本 box 结构。

Box Header

Box 分为普通 Box 和 FullBox。

在这里插入图片描述

普通 Box Header 结构如下:

字段类型描述
size4 Bytes表示整个 box 的大小。size=0说明是最后一个box;size=1时,后面的largesize表示真正的box长度
type4 Bytes4 个 ASCII 值,如果是 “uuid”,则表示此 box 为用户自定义拓展类型
largesize8 Bytessize=1 时才有的字段,用于扩展,例如 mdat box 会需要此字段

FullBox 在上面的基础上新增了 2 个字段:

字段类型描述
version1 Byte版本号
flags3 Bytes标识

Box Data

一个 Box 可能会包含其它多个 Box,此种 Box 称为 Container Box。

因此,Box Data 可能是数据,也可能是其他 Box。

MP4 典型 Box

虽然Box的类型非常多,大概有70多种,但是并不是都是必须的,一般的MP4文件都是含有必须的Box和个别非必须Box。下面介绍几种典型的 Box。

ftyp(File Type Box)

ftyp是MP4文件的第一个Box,通过判断该Box来确定文件的类型。该Box有且仅有1个,并且只能被包含在文件层,而不能被其他Box包含。该Box放在文件的最开始,指示文件的相关信息。

在这里插入图片描述

ftyp Box Header首先是 size(4字节),表示整个 Box 的大小;然后是 type(4字节),表示 Box 类型,其内容当然是 “ftyp”。

ftyp Box Data 有三个字段:

字段类型描述
major_brand4 bytes主版本号
minor_version4 bytes次版本号
compatible_brands[]4×n bytes指定兼容的版本,注意此字段是一个 list,可以包含多个版本号,每个版本号占 4 字节

实例:

在这里插入图片描述

在这里插入图片描述

moov(Movie Box)

moov 是MP4文件中必须有的一个 Box,但只能存在一个,一般出现在 ftyp 之后或 MP4 文件末尾。

实例:

在这里插入图片描述

moov 是一个 Container Box,其包含的所有 Box 用于描述媒体信息(metadata),其子 Box 一般有三种:

  1. mvhd(moov header):用于简单描述一些所有媒体共享的信息。
  2. trak:即track,轨道。用于描述音频流或视频流信息,可以有多个轨道,上面的样例中trak出现了 2 次,分别表示一路音频和一路视频流。
  3. udta(user data):用户自定义,可忽略。

实例:

在这里插入图片描述

在这里插入图片描述

mvhd(moov header)

该box是全文件唯一的一个 Box,其对整个媒体文件所包含的媒体数据进行全面的描述。其中包含了媒体的创建和修改时间,默认音量、色域、时长等信息。

在这里插入图片描述

mvhd 语法继承自 FullBox,注意下述示例出现的 version 和 flags 字段属于 FullBox header。

字段类型描述
version1 Byte版本,取 0 或 1,一般取 0
flags3 Bytes标识
creation_time8/16 Bytes创建时间,当 version=0 时取 4 字节
modification_time8/16 Bytes修改时间,当 version=0 时取 4 字节
timescale8 Bytes时间基
duration8/16 Bytes文件时长,当 version=0 时取 4 字节
rate8 Bytes播放速率,默认取 0x00010000,即 1.0
volume4 Bytes音量,默认取 0x0100,即 1.0
reserved4 Bytes0
reserved2 x 8 Bytes0
matrix9 x 8 Bytes视频播放矩阵,可忽略
pre_defined6 x 8 Bytes0
next_track_id8 Bytes下一个紧邻的 track box id

实例:

在这里插入图片描述

trak

trak box 是一个 container box,其子 box 包含了该 track 的媒体信息。

一个 mp4 文件可以包含多个 track,track之间是独立的,trak box 用于描述每一路媒体流。一般情况下,一个MP4文件有两个trak,分别对应音频流和视频流。

每个Trak Box都需要有一个tkhd box和mdia box,其它的box都是可选择的。

  • tkhd(track header box):用于简单描述该路媒体流的信息,如时长,宽度等。
  • mdia(media box):用于详细描述该路媒体流的信息
  • edts(edit Box):子Box为elst(Edit List Box),它的作用是使某个track的时间戳产生偏移。
tkhd(track header box)

tkhd(track header box)是一个 FullBox,对应字段的含义参考下图:

在这里插入图片描述

edts(edit Box)

不是所有的 MP4文件有这个 Box

子Box为elst(Edit List Box),它的作用是使某个track的时间戳产生偏移。

实例:

在这里插入图片描述

mdia(media box)

mdia(media box)也是Container Box,里面包含子Box,一般必须有mdhd box、hdlr box、minf box。基本就是当前Track媒体头信息和媒体句柄以及媒体信息。它自身非常简单,就是一个标识而已,但最复杂的还是里面包含的子box。

其中:

  • mdhd(Media Header Box):用于简单描述该路媒体流的信息。其中我们最关心的两个字段是timescale和duration,分别表示了该Track的时间戳和时长信息,这个时间戳信息也是PTS和DTS的单位。
  • hdlr(Handler Reference Box):该box解释了媒体的播放过程信息,用来设置不同Track的处理方式,标识了该Track的类型,音频Track的handler为soun,视频Track的handler为vide。
  • minf(Media Information box):该box建立了时间到真实音视频sample的映射关系,是音视频数据操作的关键。该box是container box,含有三大必须的子Box:
    • Media Info Header Box:根据track type(即media handler type)分为“vmhd”(视频)、“smhd”(音频)、“hmhd”和“nmhd”
    • dinf(data information box):描述了如何定位媒体信息,是一个container box。“dinf”一般包含一个“dref”(data reference box)。“dref”下会包含若干个“url”或“urn”,这些box组成一个表,用来定位track数据。简单的说,track可以被分成若干段,每一段都可以根据“url”或“urn”指向的地址来获取数据,sample描述中会用这些片段的序号将这些片段组成一个完整的track。一般情况下,当数据被完全包含在文件中时,“url”或“urn”中的定位字符串是空的。
    • stbl(Sample Table Box):stbl box是一个container box,是整个track中最重要的一个box,其子box描述了该路媒体流的解码相关信息、音视频位置信息、时间戳信息等。

实例:

在这里插入图片描述

在这里插入图片描述

udta(user data)

udta中保存了用户定义数据,例如iTune使用的meta数据就保存在udta中。

mdat(media data box)

mdat 用于存储音视频数据,可从该Box解封装出真实的媒体数据。该Box一般都会存在,但非必须。

mdat的位置比较灵活,可以位于moov之前,也可以位于moov之后,但必须和stbl中的信息保持一致。

另外,在写mp4文件的时候,对于mdat这个Atom,一般是先将Atom size填写0,待数据写完之后,再回过来填入具体大小。

mdat 可以引用外部的数据,参见 moov -> udta -> meta,这里不讨论,只讨论数据存储在本文件中的形式。

mdat 也是一个 box,拥有 box header 和 box body。

对于 box body 部分,采用一个一个 samples 的形式进行存储,即一个一个音频帧或视频帧的形式进行存储。没有同步字,没有分隔符,只能根据索引进行访问。即:

Box header + Box Data
==>
Box size + Box type + NALU + ... + NALU
NALU = NALU length + NALU Header + NALU Data

码流组织方式采用 avcc 格式,即 AUD + slice size + slice 的形式。

free(free space box)

free box 是可选的,如果存在,则通常出现在moov与mdat之间,即moov-free-mdat。

free中的数据通常为全0,其作用相当于占位符,其内容是无关紧要的,可以被忽略。该box被删除后,不会对播放产生任何影响。

在实时拍摄视频,moov数据增多时,将free分配给moov使用。因为设备录制视频时并不能预先知道视频数据大小,如果moov在mdat之前,随着拍摄mdat的数据会增加,moov数据也会增多,如果没有free预留的空间,则要不停的向后移动mdat数据以腾出moov空间。

stbl(Sample Table Box)

stbl 表在 MP4 文件中的位置:moov -> trak -> mdia -> minf -> stbl。不要因为它是一个五级容器就小看它,它是整个 track 中最重要的一个 box,其子 box 描述了该路媒体流的解码相关信息、音视频位置信息、时间戳信息等。想要播放一个 MP4 文件,必须根据stbl正确找到每个sample并送给解码器。stbl用来描述每个sample的信息。

MP4 中的 chunk 和 sample

在介绍stbl box之前,需要先介绍一下 MP4 中定义的sample与chunk:

  • sample:ISO/IEC 14496-12 中定义 samples 之间不能共享同一个时间戳,因此,在音视频 track 中,一个 sample 代表一个视频或音频帧。
  • chunk:多个 sample 的集合,实际上音视频 track 中,chunk 与 sample 一一对应。

在这里插入图片描述

stsd、stts、stss、ctts、stsc、stsz、stco 概述

stbl(Sample Table Box)的子 Box 的简要介绍:

  • stsd(sample description box):存储了编码类型和初始化解码器需要的信息,并与具体编解码器类型有关。给出视频、音频的编码、宽高、音量等信息,以及每个sample中包含多少个frame。
  • stts(time to sample box):存储了该 track 每个 sample 到 dts 的时间映射关系。
  • stss(sync sample box):针对视频 track,关键帧所属 sample 的序号。
  • ctts(composition time to sample box)存储了该: track 中,每个 sample 的 cts 与 dts 的时间差。
  • stsc/stz2(sample to chunk box):存储了该 track 中每个 sample 与 chunk 的映射关系。
  • stsz(sample size box):存储了该 track 中每个 sample 的字节大小。
  • stco/co64(chunk offset box):存储了该 track 中每个 chunk 在文件中的偏移。

实例:

在这里插入图片描述

下面开始逐个讲解各子 Box 的细节。

stsd(Sample Description Box)

stsd 是个 container box,其存储了编码类型和初始化解码器需要的信息。

stsd的内容和track的类型有关,也就是和hdlr的handler_type参数有关。

字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
entry_count32 bitentry 个数
开始循环
AudioSampleEntry()不定大小子 box,当 handler_type=‘soun’ 时才有
VisualSampleEntry()不定大小子 box,当 handler_type=‘vide’ 时才有
HintSampleEntry()不定大小子 box,当 handler_type=‘hint’ 时才有
MetadataSampleEntry()不定大小子 box,当 handler_type=‘meta’ 时才有
结束循环

video track的stsd body内容(不同的编码方式,stsd的子box的名称会有不同,但是box中的字段都是相同的):

FieldComment
typebox类型,包括 “预定义类型”、“自定义扩展类型”。预定义类型:比如ftyp、moov、mdat等预定义好的类型;自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)
size包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
data_reference_index当MP4文件的数据部分,可以被分割成多个片段,每一段对应一个索引,并分别通过URL地址来获取,此时,data_reference_index 指向对应的片段(比较少用到)
width、height视频的宽高,单位是像素
horizresolution、vertresolution水平、垂直方向的分辨率(像素/英寸),默认是0x00480000(72dpi)
frame_count一个sample中包含多少个frame,对video track来说,默认是1
compressorname仅供参考的名字,通常用于展示,占32个字节,比如 AVC Coding。第一个字节,表示这个名字实际要占用N个字节的长度。第2到第N+1个字节,存储这个名字。第N+2到32个字节为填充字节。compressorname 可以设置为0
depth位图的深度信息,比如 0x0018(24),表示不带alpha通道的图片

实例:

在这里插入图片描述

audio track的stsd body内容(不同的编码方式,stsd的子box的名称会有不同,但是box种的字段都是相同的):

FieldComment
typebox类型,包括 “预定义类型”、“自定义扩展类型”。预定义类型:比如ftyp、moov、mdat等预定义好的类型;自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)
size包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理
data_reference_index当MP4文件的数据部分,可以被分割成多个片段,每一段对应一个索引,并分别通过URL地址来获取,此时,data_reference_index 指向对应的片段(比较少用到)
channel_count声道数,取值为1或2
samplesize采样位宽,一般为8bit或16bit
samplerate采样率

实例:

在这里插入图片描述

hint track的stsd body内容:

FieldComment
datahint数据

stts(Decoding Time to Sample Box)

stts包含了DTS到sample number的映射表,主要用来推导每个帧的时长,描述了sample时序的映射方法,通过它可以找到任何时间的sample。

字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
entry_count32 bit条目个数
开始循环
sample_count32 bit单个entry中,具有相同时长(duration 或 sample_delta)的连续sample的个数
sample_delta32 bit单个 sample 的播放时长,单位为 timescale,也可以说是相邻两个sample之间dts的差值
结束循环

实例:第1个sample的时长是33333,第2个sample的时长是33334,第3-4个sample的时长是33333,以此类推(假设mdhd中timescale为1000,则实际时长需要除以1000)。

在这里插入图片描述

stss(Sync Sample Box)

针对视频 track,它包含关键帧所在的 sample 序号。

关键帧是为了支持随机访问。如果此表不存在,说明每一个 sample 都是一个关键帧。

字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
entry_count32 bit条目个数
开始循环
sample_number32 bitsample 计数,从 1 开始
结束循环

实例:第1帧、第151帧、第301帧…,是关键帧,以此类推。

在这里插入图片描述

ctts(Composition Time to Sample Box)

存储了该 track 中,每个 sample 的 pts 与 dts 时间差,cts = pts - dts。

对于只有I帧、P帧的视频来说,解码顺序、渲染顺序是一致的,此时,ctts没必要存在。

对于存在B帧的视频来说,ctts就需要存在了。当PTS、DTS不相等时,就需要ctts了,公式为 PTS(n) = DTS(n) + TTS(n) 。

字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
sample_counts单个entry中,具有相同差值(pts-dts)的连续sample的个数
sample_offsets从解码(dts)到渲染(pts)之间的差值

实例:第1个sample的pts-dts=2002,第2个sample的pts-dts=5005,第3个sample的pts-dts=2002,以此类推,真实时长还要除以mdhd中的timescale。

在这里插入图片描述

stsc(Sample To Chunk Box)

字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
first_chunk当前表项中,对应的第一个chunk的序号
samples_per_chunk同一个entry中每个chunk包含的sample数
sample_description_indexchunk使用的stsd的序号,即不同chunk可以使用不同编解码信息

实例:

在这里插入图片描述

第1个entry的第一个chunk的序号是1,第2个entry的第一个chunk的序号是8225(即第1个entry包含索引值为1-8224的chunk),第3个entry的第一个chunk的索引值时8226,以此类推,最后一个entry就是从first_chunk开始一直到结束为止。

第一个entry每一个chunk包含一个sample,即第1-8224个chunk,每个chunk包含1个sample。第二个entry每一个chunk包含342个sample,即第8225的chunk个chunk包含342个sample。第三个entry每一个chunk包含382个sample,即第8226个chunk包含382个sample,以此类推。

以上所有chunk中的sample,对应的sample description的序号都是1,也就是用第一个stsd。

stsz(Sample Size Boxes)

存储了该 track 中每个 sample 的字节大小。

这个box相对来说体积比较大的。表明视频帧或者音频帧大小,FFmpeg 里面的AVPacket 的size 数据大小,就是从这个box中来的。

有两种不同的box类型:stsz、stz2。

stsz
字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
sample_size默认的sample大小(单位是byte),通常为0。如果sample_size不为0,那么,所有的sample都是同样的大小。如果sample_size为0,那么,sample的大小可能不一样
sample_count当前track里面的sample数目。如果 sample_size==0,那么,sample_count 等于下面entry_size中的数据个数
entry_size(sample_sizes)单个sample的大小(如果sample_size==0的话)

实例:

在这里插入图片描述

stz2
字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
field_sizeentry表中,每个entry_size占据的位数(bit),可选的值为4、8、16。4比较特殊,当field_size等于4时,一个字节上包含两个entry,高4位为entry[i],低4位为entry[i+1]
sample_count等于下面entry_size中的数据个数
entry_size单个sample的大小

stco/co64(Chunk Offset Box)

chunk在文件中的偏移量(不是mdat中的偏移量)。

针对小文件、大文件,有两种不同的box类型,分别是stco、co64,它们的结构是一样的,只是字段长度不同。

需要注意的是一旦前面的box有了任何改变,这张表都要重新建立。

chunk_offset 指的是在文件本身中的 offset,而不是某个box内部的偏移。

在构建 MP4 文件的时候,需要特别注意 moov 所处的位置,它对于chunk_offset 的值是有影响的。有一些MP4文件的 moov 在文件末尾,为了优化首帧速度,需要将 moov 移到文件前面,此时,需要对 chunk_offset 进行改写。

字段类型描述
version8 bit取 0 或 1,一般取 0
flags24 bit
chunk_offsetchunk 在文件中的位置(在文件本身中的 offset,而不是某个box内部的偏移)

实例:第1个chunk的offset是48,第2个chunk的偏移是72831,以此类推。

在这里插入图片描述

MP4 音视频数据解析过程

这里说的解析基本是指解封装、播放的过程,都是先读取box中的内容,然后根据box中内容可以找到每一个sample也就是每一帧数据,然后进行解封装、播放。

详细过程如下:

  1. 通过stss确定关键帧的数据和每个关键帧的序号。
  2. 通过stts获取音视频流的总帧数、每一帧的dts和整体时长。
  3. 通过ctts获取每一帧中pts与dts的差值。
  4. 通过stsz获取每个sample的大小及整个流的总大小。
  5. 通过stco获取音视频流中chunk的数据和在文件中的位置(不是在mdat中的位置)。
  6. 通过stsc计算出流中chunk的数据和在文件中的位置,并通过chunk在文件中的位置及chunk中每个sample的大小,确定每个sample在文件中的位置和大小。
  7. 整理每个流的码流信息和时间戳信息,构成整体播放的时间轴,之后进行解码的渲染播放。

MP4 的使用场景及优缺点

使用场景:主要是点播场景。

优点:

  1. MP4的标准非常灵活,可扩展性比较好,有很多常见的格式是基于MP4做了一些扩展,然后被应用到比较广的范围,比如 CMAF、DASH、HLS。
  2. 因为MP4格式的开放性和灵活性,使得使用范围非常广泛,我们日常看电视剧,录视频时,最常见的就是MP4格式了。

缺点:

  1. 普通mp4情况下,会导致播放延时较高。
  2. 如果moov在文件尾,播放器需要遍历整个文件后才会找到moov并播放。

Q&A

metadata中的major_brand、minor_version、compatible_brands的作用都是什么?

ftyp Box Data 有三个字段:

字段类型描述
major_brand4 bytes主版本号
minor_version4 bytes次版本号
compatible_brands[]4×n bytes指定兼容的版本,注意此字段是一个 list,可以包含多个版本号,每个版本号占 4 字节

实例:

在这里插入图片描述

什么是isom?

isom(ISO Base Media file)是在 MPEG-4 Part 12 中定义的一种基础文件格式,MP4、3gp、QT 等常见的封装格式,都是基于这种基础文件格式衍生的。

  • MP4 文件可能遵循的规范有mp41、mp42,而mp41、mp42又是基于isom衍生出来的。

    • 3gp(3PP):一种文件格式,主要用于3G手机上。

QT(QuickTime):.qt文件代表苹果QuickTime媒体文件。

hint track是什么?

hint track:这个特殊的track并不包含媒体数据,而是包含了一些将其它数据track打包成流媒体的指示信息。

下面是mp4官方文档对hint track的描述:

在这里插入图片描述

为什么mp4要采用这种chunk-sample这种方式进行逻辑上的存储呢?

总的来说是用时间换空间,因为chunk描述的是一组sample,这些sample相同的性质可以通过chunk去统一描述,比如stsc的sample_description_index就是直接对chunk描述,如果没有chunk则需要对每一个sample都描述一遍。但是在解析sample的时候就需要获取chunk的部分信息来帮助解析,没有那么直接,需要临时建一张表。

如何区分一个track描述的是视频流还是音频流?

方法一:

  • 视频:track->tkhd中width、height不为零,volume为零
  • 音频:track->tkhd中width、height为零,volume不为零

方法二:

  • 视频:track->mdia->hdlr中handler是vide
  • 音频:track->mdia->hdlr中handler是soun

方法三:

  • 视频:track->mdia->minf中有vmhd box(Video Media Information Header)
  • 音频:track->mdia->minf中有smhd box(Sound Media Information Header)

参考

  1. https://blog.csdn.net/m0_60259116/article/details/132714706
  2. https://www.jianshu.com/p/0edc3df5cae6
  3. https://zhuanlan.zhihu.com/p/639897218
  4. https://zhuanlan.zhihu.com/p/637337464
  5. https://cloud.tencent.com/developer/article/1958147
  6. https://blog.csdn.net/weixin_39399492/article/details/127837222

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/307649.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3大事件项目3

弹框验证 先准备变量: const formModel ref({ cate_name: , cate_alias: }) 还有规则: const rules { cate_name: [ { required: true, message: please input name, trigger: blur }, { pattern: /^\S{1,10}$/, message: must be 1-10, trigger: blur } ], …

太阳光光照试验耐久性老化试验使用太阳光模拟器系统

上海科迎法电气科技有限公司生产的太阳光模拟器系统主要应用于太阳能研究、材料研究、光伏组件测试、空间环境模拟器、植物生长研究、光热模拟等领域,主要表现特征为: 1. 太阳能研究:可用于模拟不同光照条件下太阳能电池的性能测试和研究&am…

高清视频素材,免费下载,收藏好这6个网站。

国内大部分视频素材网站都需要付费购买,这让很多从事视频剪辑的朋友不知道去哪里找免费的视频素材,本期就给大家分享我收藏多年的6个视频素材网站,都可以免费下载,还可以商用,而且国内外的都有哦,有需要的朋…

java-spring 图灵 02 手写spring

01.idea中创建一个maven管理的空项目 02.模拟创建出spring容器类,这里叫wzpApplicationContext,创建的时候会自动加载配置类的数据 public class wzpApplicationContext {private Class configClass;public wzpApplicationContext(Class configClass) …

【Qt 学习笔记】QWidget的windowOpacity属性 | cursor属性 | font属性

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ QWidget的windowOpacity属性 | cursor属性 | font属性 文章编号&#…

解决 MSYS2 Qt 6.7 默认 stylesheet 在 windows 11 下的显示故障

项目场景: MSYS2 升级到 Qt6.7.0,发现显示故障,所有Qt6程序以及 QtCreator的SpinBox都显示不全,Combox的底色不对。 问题描述 2024年4月1日,pacman升级MSYS2后,Qt6遇到风格错误。 msys环境: …

ThingsBoard实现告警规则创建并生成报警信息

一、概述 1.概念 2.告警规则 3.简单报警条件 步骤1. 打开设置配置 ​步骤2. 单击警报规则 ​步骤3. 单击警报条件 ​步骤4. 单击过滤条件 ​步骤5. 选择数据键 ​步骤6. 设置条件 ​步骤7. 保存条件 ​步骤8. 应用更改 4.测试告警 1、使用MQTT发送遥测属性 2、查看…

数据结构:双向链表

一.双向链表的结构 最常用的链表就是单链表和双向链表。我们首先要知道,链表有八种分类。单链表是不带头单向不循环链表。而此篇博客要讲的是带头双向循环链表。 结构如下: 注意:带头链表里的头节点,实际为“哨兵位”&#xff0…

【python】python饮料销售数据分析可视化(源码+数据集)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

机器人瓶胚检测工作站(H3U脉冲轴控制)

1、变量定义 2、程序监控1 2、 程序监控2 3、程序监控3 机器人输送料和机构的动作安全尤为重要,下面我们讨论下安全联锁控制逻辑 4、相机拍照触发信号 5、相机拍照触发时序

回归预测 | MATLAB实现BO-GRNN贝叶斯优化广义回归神经网络多输入单输出预测

回归预测 | MATLAB实现BO-GRNN贝叶斯优化广义回归神经网络多输入单输出预测 目录 回归预测 | MATLAB实现BO-GRNN贝叶斯优化广义回归神经网络多输入单输出预测预测效果基本介绍程序设计参考资料预测效果 基本介绍

【SpringBoot】获取参数

获取参数 传递单个参数传递多个参数传递对象后端参数重命名传递数组传递 json 数据获取 URL 中参数上传文件获取 cookie 和 session获取cookie获取session 传递单个参数 RequestMapping("/user") RestController public class UserController {// 传递单个参数Reque…

简单好用的SaaS知识库工具都在这了,看完赶紧收藏!

在信息飞速发展的今天,企业如何有效地管理海量的信息和知识成为了提高工作效率的关键。SaaS知识库工具正成为企业寻求的解决方案,它们不仅能够帮助团队组织文档,而且优化知识分享流程。现在就让我们来看看市场上几款简单又好用的SaaS知识库工…

华为云配置安全组策略开放端口

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C 🔥座右铭:“不要等到什么都没有了,才下…

C语言 | 内存函数memcpy,memmove,memset,memcmp

目录&#xff1a; 1. memcpy使用和模拟实现 2. memmove使用和模拟实现 3. memset函数的使用 4. memcmp函数的使用 头文件&#xff1a;<string.h> 1. memcpy使用和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); • 从source的…

【CPA考试】2024注册会计师报名照片尺寸要求解读及手机拍照方法

随着2024年注册会计师考试的临近&#xff0c;众多会计专业人士和学生都开始准备报名参加这一行业的重要考试&#xff0c;报名时间为4月8日至4月30日。报名过程中&#xff0c;一张符合要求的证件照是必不可少的。本文将为您详细解读2024年注册会计师考试报名照片的尺寸要求&…

Git以及Gitlab的快速使用文档

优质博文&#xff1a;IT-BLOG-CN 安装git 【1】Windows为例&#xff0c;去百度下载安装包。或者去官网下载。安装过秳返里略过&#xff0c;一直下一步即可。丌要忉记设置环境发量。 【2】打开cmd&#xff0c;输入git –version正确输出版本后则git安装成功。 配置ssh Git和s…

C++ 之 【类与对象】 从入门到精通一条龙服务 进阶篇(类的6个默认成员函数,构造,析构。。。)

以后把闹钟换成唢呐&#xff0c;醒了就起床&#xff0c;不醒就上天堂 一、类的6个默认成员函数 二、构造函数 1.概念 2.特性 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 五、赋值运算符重载 1.运算符重载 2.赋值运算符重载 3.前置和后置重载 六…

rancher踩坑日志:prometheus访问kubelet 10250端口提示鉴权失败

该原因是因为kubectl禁止了非授权用户访问10250端口来获取node的数据。 解决思路&#xff1a; 添加prometheus访问kubelet时带上证书进行验证匹配 --> 由于我的prometheus是rancher安装的&#xff0c;不知道要怎么修改所以研究了一会没研究明白就放弃了。设置prometheus访问…

关于Ribbon在SpringCloudAlibaba2021.1版本中,找不到服务实例

关于Ribbon在SpringCloudAlibaba2021.1版本中&#xff0c;找不到服务实例 放个妹子 SpringCloudAlibaba在2021.1版本中,spring-cloud-starter-alibaba-nacos-discovery默认已经移除了ribbon模块 手动加上spring-cloud-starter-netflix-ribbon依赖后&#xff0c;项目能正常启动…