视频格式与编解码:从原理到生产选型的完整指南

你的视频为什么在 Safari 上播不了?为什么同样是 1080p,文件大小差了 3 倍?为什么 AI 视频项目的流式播放必须用 fMP4?这些问题的答案,都藏在"容器"与"编解码器"这两个概念里。这篇文章带你从底层原理出发,把视频格式这件事彻底讲清楚。


第一步:先分清两个概念

视频开发中最基础也最容易混淆的概念是容器格式编解码器,它们是两件完全不同的事情。

容器格式(Container Format)是一个"盒子",负责把视频流、音频流、字幕、元数据打包在一起,并定义它们的组织结构。常见容器:.mp4.webm.mkv.mov

编解码器(Codec,Coder-Decoder)是压缩和解压视频数据的算法。同一个容器里可以装不同编解码器编码的内容,比如 MP4 容器里可以装 H.264,也可以装 H.265,甚至 AV1。

视频文件 = 容器格式(MP4)
              ├── 视频轨道:H.264 编码的画面数据
              ├── 音频轨道:AAC 编码的声音数据
              └── 元数据:时长、分辨率、章节信息...

类比:容器是快递箱,编解码器是箱子里货物的包装方式。同样的货物(视频内容),可以用不同的包装方式压缩,装进不同的箱子。


第二部分:容器格式详解

MP4(.mp4)— 兼容性最广的容器

MP4 是基于 MPEG-4 Part 12 标准的容器格式,是目前 Web 视频的事实标准。几乎所有浏览器、设备、播放器都支持它。内部结构由一系列 Box(原子) 组成,其中最关键的是两个:

  • moov box:包含视频的所有元数据(时长、编解码信息、每帧的位置索引)
  • mdat box:包含实际的音视频数据

moov 的位置决定了视频能否"边下边播"。默认情况下,很多编码工具生成的 MP4 文件,moov 在文件末尾。浏览器必须下载整个文件才能找到 moov,然后才能开始播放——这在网络视频场景下是灾难性的。

解决方案是使用 FFmpeg 的 -movflags faststart 参数,将 moov 移到文件头部:

# 将 moov 前置,实现边下边播
ffmpeg -i input.mp4 -movflags faststart -codec copy output.mp4

这一步对所有面向 Web 的 MP4 视频都是必做操作,直接影响首帧加载速度。github.com/haochuan9421


WebM(.webm)— Web 原生的开放格式

WebM 是 Google 于 2010 年推出的开放、免专利的视频格式,基于 Matroska 容器,专为 Web 流媒体设计。它只支持特定的编解码器组合:

  • 视频:VP8、VP9、AV1
  • 音频:Vorbis、Opus

WebM 的优势是完全开放、无专利费,且与 Chrome/Firefox 深度集成。劣势是 Safari 的支持历史上不稳定(Safari 14+ 才较好地支持 VP9 + WebM)。


fMP4(Fragmented MP4)— 流媒体的基石

fMP4 是 MP4 的流式变体,也是 MSE(Media Source Extensions)和 MPEG-DASH 的标准分片格式,理解它对 AI 视频的流式播放至关重要。

普通 MP4 的问题在于它的索引(moov)是一个整体,必须完整加载才能使用。fMP4 将视频数据切分成独立的片段(Fragment),每个片段包含自己的 moof(片段头)+ mdat(片段数据),可以独立解码,不依赖其他片段。

普通 MP4:[moov][mdat(全部数据)]
fMP4:    [ftyp][moov][moof+mdat][moof+mdat][moof+mdat]...
                       ↑片段1      ↑片段2      ↑片段3

这种结构使得 fMP4 天然支持:

  • 随机访问:直接跳到任意片段,无需从头加载
  • 码率切换:HLS 和 DASH 的码率自适应切换依赖于此
  • 边生成边播放:AI 视频生成完一个片段就推送一个,实现流式播放
# 用 FFmpeg 生成 fMP4
ffmpeg -i input.mp4 \
  -c:v libx264 \
  -c:a aac \
  -movflags frag_keyframe+empty_moov+default_base_moof \
  output.fmp4

zhuanlan.zhihu.com lucius0.github.io


第三部分:编解码器深度解析

H.264 / AVC — 最广泛的编解码器

H.264(也叫 AVC,Advanced Video Coding)是 2003 年发布的视频编码标准,至今仍是 Web 视频的绝对主力。它的核心优势是兼容性无与伦比——从 IE9 到最新的 Safari,从 Android 2.3 到 iOS 最新版,几乎所有设备都有 H.264 的硬件解码器。

Profile 与 Level 是 H.264 最重要的两个参数,直接影响兼容性和画质:

Profile 定义了使用的压缩特性子集:

Profile特点适用场景
Baseline最基础,只支持 I/P 帧,无 B 帧低延迟视频通话、老旧移动设备
Main支持 B 帧,质量更好标清/高清广播
High最高压缩效率,支持 CABAC 熵编码Web 视频首选

Level 定义了分辨率、帧率和码率的上限。Web 视频常用 Level 4.1(支持 1080p@30fps)和 Level 5.1(支持 4K@30fps)。

<video>type 属性中,codec 字符串的完整写法是:

video/mp4; codecs="avc1.PPCCLL"
                        ↑↑ ↑↑ ↑↑
                        PP = Profile(42=Baseline, 4D=Main, 64=High)
                        CC = Constraint flags
                        LL = Level(1E=3.0, 28=4.0, 29=4.1, 32=5.0)

常用组合:

// High Profile, Level 4.1 — Web 视频最常用
'video/mp4; codecs="avc1.64002A"'
 
// Baseline Profile, Level 3.1 — 最大兼容性
'video/mp4; codecs="avc1.42E01F"'
 
// Main Profile, Level 4.0
'video/mp4; codecs="avc1.4D0028"'

H.265 / HEVC — 高压缩率的代价是专利费

H.265(HEVC,High Efficiency Video Coding)是 H.264 的继任者,相同画质下码率节省约 50%。但它有一个致命问题:复杂的专利授权体系,导致浏览器厂商的支持极不统一。

  • Safari(macOS/iOS):支持(Apple 有自己的专利授权)
  • Chrome:不支持(需要付专利费)
  • Firefox:不支持
  • Edge:部分支持(依赖系统解码器)

这意味着 H.265 在 Web 场景几乎无法作为主力格式,除非你的目标平台是纯 Apple 生态。


VP9 — Google 的开放编解码器

VP9 是 Google 于 2013 年发布的开放编解码器,相同画质下码率比 H.264 节省约 30~50%。YouTube 的大部分视频都在用 VP9。

浏览器支持情况:

浏览器支持版本
Chrome29+
Firefox28+
Edge14+
Safari14(macOS)/ 15(iOS)

Safari 对 VP9 的支持直到 2020 年才加入,这是 VP9 长期无法作为 Web 唯一格式的原因。

# FFmpeg 编码 VP9(两遍编码获得最佳质量)
# 第一遍:分析
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 33 -pass 1 -an -f null /dev/null
 
# 第二遍:编码
ffmpeg -i input.mp4 \
  -c:v libvpx-vp9 \
  -b:v 0 -crf 33 \
  -pass 2 \
  -c:a libopus -b:a 128k \
  output.webm

juejin.cn


AV1 — 下一代的开放标准

AV1 是由 Alliance for Open Media(AOM)于 2018 年发布的开放、免专利编解码器,成员包括 Google、Apple、Microsoft、Netflix、Amazon 等。它代表了当前编解码技术的最高水平:

  • 相比 H.264,相同画质码率节省约 43%(1080p)到 63%(4K)
  • 相比 VP9,码率节省约 20~30%
  • 完全开放,无专利费 news.qq.com developer.aliyun.com

浏览器支持现状(2026):

浏览器支持版本备注
Chrome70+软解;Chrome 113+ 支持硬件编码
Firefox67+软解为主
Edge18+部分依赖系统解码器
Safari16.4+(macOS)需要 Apple Silicon 或 A17+ 芯片的硬件解码

AV1 目前最大的挑战是编码速度极慢(比 H.264 慢 10~100 倍),以及旧设备缺少硬件解码器导致 CPU 占用高。但随着硬件普及,AV1 正在成为 Web 视频的未来标准。B 站、YouTube 都已大规模部署 AV1。

# FFmpeg 编码 AV1(使用 libaom-av1,速度较慢)
ffmpeg -i input.mp4 \
  -c:v libaom-av1 \
  -crf 30 \
  -b:v 0 \
  -cpu-used 4 \    # 0=最慢最优,8=最快最差,4是平衡点
  -c:a libopus -b:a 128k \
  output_av1.webm
 
# 更快的 AV1 编码器:SVT-AV1(Netflix 开源,速度快很多)
ffmpeg -i input.mp4 \
  -c:v libsvtav1 \
  -crf 30 \
  -preset 6 \     # 0=最慢,13=最快
  -c:a libopus -b:a 128k \
  output_svtav1.webm

音频编解码器

视频文件里的音频轨道同样需要编解码,Web 场景常用的三种:

编解码器容器特点
AACMP4兼容性最广,128kbps 音质优秀,iOS/Android 硬件支持
OpusWebM开放免费,低延迟,128kbps 效果优于 AAC,WebRTC 标准
MP3MP4/WebM老格式,仅兼容性需求时使用

Web 视频的音频选型很简单:MP4 用 AAC,WebM 用 Opus


第四部分:浏览器支持矩阵

格式组合                    Chrome  Firefox  Safari  Edge  iOS Safari
─────────────────────────────────────────────────────────────────────
MP4 + H.264 + AAC            ✅       ✅      ✅      ✅      ✅
WebM + VP9 + Opus            ✅       ✅      ✅*     ✅      ✅*
WebM + AV1 + Opus            ✅       ✅      ✅**    ✅      ✅**
MP4 + H.265 + AAC            ❌       ❌      ✅      △       ✅

* Safari 14+ (macOS), Safari 15+ (iOS)
** Safari 16.4+ (macOS), 需要硬件支持

从这张矩阵可以得出一个清晰的生产策略:必须提供 MP4/H.264 作为兜底,可以叠加 WebM/AV1 给支持的浏览器获得更好的压缩率。


第五部分:格式能力检测

在代码中动态选择最优格式,有三个层次的检测 API,精度依次递增:

层次一:canPlayType()

const video = document.createElement('video');
 
// 返回 'probably' | 'maybe' | ''
const support = {
  h264:  video.canPlayType('video/mp4; codecs="avc1.42E01E"'),
  vp9:   video.canPlayType('video/webm; codecs="vp9, opus"'),
  av1:   video.canPlayType('video/webm; codecs="av01.0.05M.08"'),
  hevc:  video.canPlayType('video/mp4; codecs="hev1.1.6.L93.B0"'),
};
 
console.log(support);
// Chrome: { h264: 'probably', vp9: 'probably', av1: 'probably', hevc: '' }
// Safari: { h264: 'probably', vp9: 'probably', av1: 'probably', hevc: 'probably' }

层次二:MediaSource.isTypeSupported()

用于 MSE 场景(HLS.js、Dash.js 等),检测是否支持通过 MSE 播放某种格式:

// 检测 fMP4 格式的 MSE 支持
const mseSupport = {
  h264:  MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E"'),
  vp9:   MediaSource.isTypeSupported('video/webm; codecs="vp9"'),
  av1:   MediaSource.isTypeSupported('video/mp4; codecs="av01.0.05M.08"'),
};

isTypeSupportedcanPlayType 更严格——它不仅检测解码能力,还检测是否支持通过 MSE 追加该格式的分片数据。

层次三:navigator.mediaCapabilities.decodingInfo()

最精准的检测 API,不仅告诉你"能不能播",还告诉你"播得流不流畅"、"有没有硬件加速":

async function checkDecodeCapability(config) {
  const result = await navigator.mediaCapabilities.decodingInfo({
    type: 'file',
    video: {
      contentType: 'video/mp4; codecs="avc1.42E01E"',
      width: 1920,
      height: 1080,
      bitrate: 4000000, // 4Mbps
      framerate: 30,
    },
  });
 
  console.log({
    supported:    result.supported,    // 是否支持
    smooth:       result.smooth,       // 是否流畅(不会掉帧)
    powerEfficient: result.powerEfficient, // 是否有硬件加速
  });
}
 
checkDecodeCapability();
// { supported: true, smooth: true, powerEfficient: true }

powerEfficient: true 意味着有硬件解码器介入,功耗低、性能高;false 表示纯软件解码,在低端设备上可能导致发热和掉帧。zhuanlan.zhihu.com


第六部分:硬件解码 vs 软件解码

这是影响移动端体验的关键因素,但很多开发者没有意识到。

硬件解码:由 GPU 或专用解码芯片处理,CPU 占用极低,功耗小,播放 4K 视频不发热。几乎所有现代设备都有 H.264 的硬件解码器。AV1 的硬件解码器从 2022~2023 年的新设备开始普及。

软件解码:由 CPU 处理,高分辨率视频会导致 CPU 满载、发热、掉帧、耗电。

对 Web 开发者的影响:当你用 canPlayType 检测到浏览器"支持"某种格式时,不代表有硬件加速。在老旧移动设备上用软件解码播放 AV1,体验可能还不如 H.264 硬件解码。这正是 mediaCapabilities.decodingInfo() 的价值所在——它能区分硬件解码和软件解码。


第七部分:Web 视频格式选型决策树

你的视频需要在哪些平台播放?
│
├── 必须支持所有浏览器(含旧版 Safari)
│   └── 主力格式:MP4 + H.264 + AAC
│       可选叠加:WebM + VP9/AV1 + Opus(给 Chrome/Firefox 更好体验)
│
├── 只需支持现代浏览器(2022年以后)
│   └── 主力:WebM + VP9 + Opus
│       叠加:WebM + AV1 + Opus(Chrome/Firefox 优先选择)
│       兜底:MP4 + H.264 + AAC(Safari 兜底)
│
├── 流媒体/直播(需要 MSE)
│   └── 必须使用 fMP4(H.264 或 AV1)或 WebM 分片
│       配合 HLS.js / Dash.js / Shaka Player
│
└── AI 视频流式播放(边生成边播)
    └── fMP4 + MSE 的 appendBuffer 方案
        或 HLS 分片推送方案

第八部分:生产环境转码工具链

FFmpeg — 命令行瑞士军刀

FFmpeg 是视频处理的核心工具,以下是针对 Web 视频的常用转码命令:

# ── 生成 Web 最优 MP4(H.264 High Profile + AAC + moov 前置)──
ffmpeg -i input.mp4 \
  -c:v libx264 \
  -profile:v high \     # High Profile
  -level:v 4.1 \        # Level 4.1,支持 1080p@30fps
  -preset slow \        # 编码速度/质量平衡(ultrafast/fast/medium/slow/veryslow)
  -crf 23 \             # 质量因子,18=高质量,28=低质量,23是默认
  -c:a aac \
  -b:a 128k \
  -movflags faststart \ # moov 前置!
  output_h264.mp4
 
# ── 生成 WebM/VP9(双遍编码)──
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 33 -pass 1 -an -f null /dev/null && \
ffmpeg -i input.mp4 \
  -c:v libvpx-vp9 -b:v 0 -crf 33 -pass 2 \
  -c:a libopus -b:a 128k \
  output_vp9.webm
 
# ── 生成 fMP4 分片(用于 MSE/DASH)──
ffmpeg -i input.mp4 \
  -c:v libx264 -profile:v high -level:v 4.1 -crf 23 \
  -c:a aac -b:a 128k \
  -movflags frag_keyframe+empty_moov+default_base_moof \
  -g 48 \               # 关键帧间隔(影响分片大小)
  output.fmp4
 
# ── 批量生成多码率版本(用于自适应码率)──
ffmpeg -i input.mp4 \
  -map 0:v -map 0:a -c:v libx264 -crf 28 -vf scale=640:-2  -c:a aac -b:a 96k  360p.mp4 \
  -map 0:v -map 0:a -c:v libx264 -crf 25 -vf scale=1280:-2 -c:a aac -b:a 128k 720p.mp4 \
  -map 0:v -map 0:a -c:v libx264 -crf 23 -vf scale=1920:-2 -c:a aac -b:a 192k 1080p.mp4

ffprobe — 视频信息检测

# 查看视频的编解码、分辨率、码率等完整信息
ffprobe -v quiet -print_format json -show_streams input.mp4
 
# 快速查看关键信息
ffprobe -v error -select_streams v:0 \
  -show_entries stream=codec_name,width,height,bit_rate,r_frame_rate \
  -of default=noprint_wrappers=1 input.mp4

第九部分:生产环境最佳实践模板

把以上知识整合成一个完整的格式选择和 <video> 配置方案:

// 智能格式选择器
async function getBestVideoSource(sources) {
  // sources = { av1: 'video_av1.webm', vp9: 'video_vp9.webm', h264: 'video.mp4' }
 
  const checks = [
    {
      src: sources.av1,
      type: 'video/webm; codecs="av01.0.05M.08"',
      label: 'AV1',
    },
    {
      src: sources.vp9,
      type: 'video/webm; codecs="vp9, opus"',
      label: 'VP9',
    },
    {
      src: sources.h264,
      type: 'video/mp4; codecs="avc1.64002A"',
      label: 'H.264',
    },
  ];
 
  for (const check of checks) {
    const supported = MediaSource.isTypeSupported(check.type);
    if (!supported) continue;
 
    // 进一步检查是否有硬件加速(可选)
    if (navigator.mediaCapabilities) {
      const info = await navigator.mediaCapabilities.decodingInfo({
        type: 'file',
        video: {
          contentType: check.type,
          width: 1920, height: 1080,
          bitrate: 4000000, framerate: 30,
        },
      });
      if (info.supported) {
        console.log(`选择格式: , 硬件加速: `);
        return check;
      }
    } else {
      return check;
    }
  }
 
  // 最终兜底
  return { src: sources.h264, type: 'video/mp4', label: 'H.264 fallback' };
}
 
// 使用示例
const best = await getBestVideoSource({
  av1:  'https://cdn.example.com/video_av1.webm',
  vp9:  'https://cdn.example.com/video_vp9.webm',
  h264: 'https://cdn.example.com/video.mp4',
});
 
const video = document.querySelector('video');
video.src = best.src;

对应的 HTML 静态写法(无需 JS 检测,浏览器自动选择):

<video controls preload="metadata" playsinline>
  <!-- AV1:最优压缩,现代浏览器优先选择 -->
  <source src="video_av1.webm"
          type="video/webm; codecs='av01.0.05M.08, opus'" />
  <!-- VP9:次优,广泛支持 -->
  <source src="video_vp9.webm"
          type="video/webm; codecs='vp9, opus'" />
  <!-- H.264:最终兜底,100% 兼容 -->
  <source src="video.mp4"
          type="video/mp4; codecs='avc1.64002A, mp4a.40.2'" />
  <p>您的浏览器不支持 HTML5 视频</p>
</video>

编解码器速查表

编解码器标准组织专利压缩效率编码速度硬件解码普及度Web 推荐度
H.264ITU/ISO有(MPEG-LA)基准极高(所有设备)⭐⭐⭐⭐⭐ 兜底必选
H.265ITU/ISO有(多个池)H.264 的 2x高(新设备)⭐⭐ 仅 Apple 生态
VP9GoogleH.264 的 1.5x中(2018年后设备)⭐⭐⭐⭐ 主力之一
AV1AOMH.264 的 2x极慢低(2022年后设备)⭐⭐⭐⭐ 未来主力

小结

视频格式的选型本质上是在兼容性、压缩效率、编码成本三者之间寻找平衡。对于今天的 Web 视频项目,最稳健的策略是:H.264 作为必备兜底,VP9 或 AV1 作为现代浏览器的优选格式,fMP4 作为流式播放和 AI 视频场景的基础格式。

下一篇将深入流媒体协议,把 HLS 的 m3u8 结构、DASH 的 MPD 文件、自适应码率的切换算法,以及 MSE 如何把这一切串联起来,完整地讲透。