前端音视频学习(二)- 视频播放原理

9 阅读4分钟

本篇深入探讨视频在浏览器中是如何从二进制数据变成画面的,涵盖播放链路、同步机制以及核心 API 的使用。


一、 视频播放链路(Pipeline)

一个完整的视频播放过程通常经历以下四个步骤:

  1. 解封装 (Demuxing) :从容器(如 MP4)中分离出视频压缩流和音频压缩流。
  2. 解码 (Decoding) :将压缩数据还原为原始的图像帧(YUV/RGB)和音频采样(PCM)。
  3. 音视频同步 (Synchronization) :通过时间戳(PTS)确保画面和声音对齐。
  4. 渲染 (Rendering) :将图像画在屏幕上(Canvas/GPU),将音频送入声卡。

浏览器能播放一部分 mp4 文件,是因为浏览器的音视频解码器是内嵌的,只能解压缩几种固定的编码格式, 补充说明:每一帧图像,音频采样本身也有自己的格式,图像会有 YUV,RGB 等格式,音频采样会有 float 等样本格式,但一般这些格式处理过程在音视频处理中是不需要特别关心的,因为编码解码时会自动处理这些。


二、 音视频同步机制

同步的核心是时间戳

  • PTS (Presentation TimeStamp) :显示时间戳。告诉播放器这一帧应该在什么时间点播放。

  • DTS (Decoding TimeStamp) :解码时间戳。告诉播放器这一帧应该在什么时间点解码。

    • 为什么需要两者? 因为存在 B 帧(双向预测),解码顺序可能和显示顺序不一致。
  • 时间基 (Timebase) :时间戳的单位。例如时间基是 1/90000,PTS 为 180000,则播放时间为 180000 * (1/90000) = 2秒


三、 浏览器播放核心组件

0. HTML5 标签

最基础、原生的播放组件

  • 角色:它是高层级的抽象,封装了底层复杂的 Pipeline。只需给它一个 src,浏览器就会自动完成“解复用 -> 解码 -> 渲染”。

  • 直播播放的真相

    • 原生支持:仅在极少数环境下(如 Safari)原生支持 HLS (.m3u8) 直播协议。
    • 局限性:原生不支持 HTTP-FLV、DASH 等复杂直播流,也无法实现动态码率切换。
    • 协作模式:在现代 Web 开发中,<video> 通常只充当 “渲染终端” 。开发者利用 MSE 插件(如 hls.js, flv.js)在外部处理复杂的协议逻辑,最后将解析好的数据块喂给 <video> 进行显示。

1. MediaSource Extensions (MSE)

允许 JS 动态控制视频流。它是 HLS.js、Flv.js 实现的基础。

  • 核心逻辑

    1. 创建 MediaSource 并绑定到 <video>.src
    2. 添加 SourceBuffer(指定格式,如 video/mp4; codecs="avc1.42E01E")。
    3. 通过 fetch 请求视频分片(fMP4),并 appendBuffer 喂给浏览器。
  • 优势:可以实现码率自适应切换、防盗链、直播拼接等。

2. WebCodecs API

直接操作解码器。它绕过了 <video> 标签,直接给你 VideoFrame

  • 流程

    1. 使用 VideoDecoderAudioDecoder 解码媒体数据;
    2. 解码后的帧以 VideoFrameAudioData 对象形式返回;
    3. 你可以将帧绘制到 <canvas>,或送入 WebGL / WebGPU
    4. 也可以用 VideoEncoder 重新压缩输出。
  • 场景:超低延迟视频(云游戏)、视频剪辑(逐帧处理)、添加实时水印/滤镜。

3. Web Audio API

高性能音频处理框架

  • 节点模型AudioContext 中通过各种 Node(GainNode, FilterNode)串联。
  • 用途:音效增强、多通道混音、音频可视化。

4. WebAssembly (WASM)

WASM 并不是浏览器内置的视频播放 API,而是一个高性能计算环境,它让你能在浏览器中运行 C/C++/Rust 等编译后的代码。

  • 用途:在浏览器运行 C++ 编写的 FFmpeg 库,用来解码浏览器原生不支持的格式(如 H.265, FLV)。

四、 硬件加速与性能

  • 硬件加速 (Hardware Acceleration) :利用 GPU 专有的解码电路(如 NVIDIA 的 NVDEC、Intel 的 QuickSync)代替 CPU 完成解码。

  • 优势:极大地降低 CPU 占用,减少发热,是播放 4K/8K 视频的必要条件。

  • 谁来控制?

    1. 浏览器自动管理:默认开启。浏览器会根据显卡驱动的稳定性自动决定。

    2. 用户设置:用户可以在浏览器设置中手动开关(“使用图形加速模式”)。

    3. 开发者偏好:在使用 WebCodecs 时,可以通过配置项明确要求使用硬件或软件解码:

      decoder.configure({
        codec: 'avc1.42E01E',
        hardwareAcceleration: 'prefer-hardware' // 或 'prefer-software'
      });
      
  • 如何判断?

    • 在 Chrome 的 Media 面板 中查看 Decoder Name
    • 如果显示为 VpxVideoDecoderFFmpegVideoDecoder,通常是软解
    • 如果显示为 D3D11VideoDecoderVaapiVideoDecoder,则是硬解

五、 转码过程简述

转码(Transcoding)本质上是:解封装 -> 解码 -> 处理(缩放/滤镜) -> 重新编码 -> 重新封装

  • 纯封转 (Remuxing) :如果不改变编码格式,只是把 MP4 转成 FLV,只需 解封装 -> 重新封装,性能极高且画质无损。这是 Web 端播放 FLV 直播流的核心思路。