MP4 格式:最少加载多少数据就能渲染出视频首帧?优化短视频播放体验必须先了解它丨音视频基础

本文详细介绍了MP4文件结构,包括ftyp、moov、mdat等Box的解析,强调了moov的重要性。通过实战案例探讨了如何通过moov优化短视频的秒开体验和预加载策略,指出moov前置可以改善网络播放延迟,同时计算出预加载数据量以保证首帧渲染,提升用户体验。
摘要由CSDN通过智能技术生成

(本文基本逻辑:MP4 封装格式概览 → 重要 Box 具体信息介绍 → 实战中对 MP4 Box 信息的使用)

MP4 也称为 MPEG-4 第 14 部分,是继承 MPEG-4 第 12 部分的 ISO 基础媒体文件格式并略作扩展而来,定义于标准 ISO/IEC 14496-14 中,是一种标准的数字多媒体容器格式。

在现在互联网使用的视频中,MP4 是最常见的格式之一,尤其是短视频。如果我们要对短视频的播放体验做优化,了解 MP4 的格式是非常必要的。所以本文我们将介绍一下如下内容:

  • MP4 格式概览
  • File Type Box(ftyp) 介绍
  • Movie Box(moov) 及其重要子 Box 的介绍
  • Media Data Box(mdat) 介绍
  • 实战解析案例:
    • moov 和 MP4 视频的秒开:moov Box 位置对 MP4 秒开的影响。
    • MP4 视频的预加载:最少加载多少数据可以渲染出 MP4 视频首帧。

1、MP4 格式概览

MP4 文件的数据都是封装在一个又一个名为 Box 的单元中。一个 MP4 文件由若干个 Box/FullBox 组成,每个 Box 包含了 Header 和 Data。FullBox 是 Box 的扩展,其包含的 Header 增加了 version(8bits) 和 flags(24bits) 部分。Header 部分包含了 size(32bits) 和 type(32bits) 部分。size 用于描述整个 Box 的长度,type 用于描述 Box 的类型。当 size 为 0 时,表示这是文件中最后一个 Box;当 size 为 1 时,表示 Box 长度需要更多 bits 来描述,这时在后面会定义一个 64bits 的 largesize 来描述 Box 的长度。当 type 是 uuid 时,代表 Box 中的数据是用户自定义扩展类型。

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;
    }
}

FullBox 的数据格式定义:

aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f) extends Box(boxtype) {
    unsigned int(8) version = v;
    bit(24) flags = f;
}

下图是对 Box/FullBox 结构的描述:

 Box 有不同的类型,有着不同的数据结构,Box 中还可以包含其他 Box。Box 的类型详见下表(其中 * 表示当父 Box 存在时,则必须包含该 Box):

 

在众多类型的 Box 中,最常见的第一层级 Box 有 3 个,分别是 ftypmoovmdat

下面就着重介绍和分析一下这几个 Box 以及他们包含的子 Box。

2、File Type Box(ftyp) 解析

ftyp,即 File Type Box,包含文件的类型、版本、兼容信息等。在一个 MP4 文件中,该 Box 有且只有一个,并且需要尽可能放在文件最开始的位置,除非有必要的固定长度的文件签名信息 Box 可以放在该 Box 前面,其他非固定长度的 Box 数据都必须放在它后面。

ftyp Box 的数据格式定义:

aligned(8) class FileTypeBox extends Box(‘ftyp’) {
    unsigned int(32) major_brand;
    unsigned int(32) minor_version;
    unsigned int(32) compatible_brands[]; // to end of the box
}

下面是一个 MP4 文件的 ftyp Box 的 16 进制示例数据:

按照上文所述,前 4 个字节 00 00 00 20 表示该 Box 的 size,即 32 字节。接着 4 个字节 66 74 79 70 是该 Box 的 type,即 ftyp。接下来 4 个字节 69 73 6F 6D 是主 brand,表示该文件所遵循的标准规格,这里是 isom,即遵循 ISO Base Media File Format。接下来的 4 个字节 00 00 02 00 表示的是这个 Box 格式的版本号。接下来的 16 个字节则是兼容的 compatible brands,即该文件兼容的其他标准规格,这里是 isomiso2avc1mp41

虽然这个 Box 是 MP4 文件所必须的,但是通常我们并不太关注这里的信息,所以这里不再多讲。

3、Movie Box(moov) 解析

moov,即 Movie Box,包含文件中所有媒体数据的宏观描述信息。实际的音视频数据都存储在 mdat 中,那么多的数据,我们怎么确定每一帧数据的位置呢,这就需要解析 moov 中的数据来得到实际音视频数据的索引。

moov Box 可以说是 MP4 文件中最重要的 Box,一般播放器的实现都需要读取到 moov 的数据才能开始播放流程。

moov Box 是一个 container box,所以它的数据格式定义比较简单:

aligned(8) class MovieBox extends Box(‘moov’){
}

moov 通常包含 1 个 mvhd 和若干个 trak。

3.1、Movie Header Box(moov/mvhd)

mvhd,Movie Header Box,包含与具体媒体数据无关,但与整体播放相关的信息,比如 timescale、duration 等信息。

mvhd Box 的数据格式定义:

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;
}

下面是一些字段的含义:

  • version:该 Box 的版本号。
  • creation_time:创建时间。
  • modification_time:最新修改时
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值