Electron Development - Something about MSE & DASH & Shaka Player
KongHou

从 HTML5 Video 到 MSE、DASH 与 Shaka Player

在早期的前端视频开发中,<video> 标签几乎可以承担所有播放任务:设置 src、控制播放、暂停、倍速即可。然而,在一个更贴近真实视频网站的视频播放器实现中,例如构建一个类似 Bilibili 的小型项目,会很快遇到 <video> 的天然限制:

  • 大文件加载慢
  • 无法按需分片加载
  • 难以支持自适应码率
  • 不支持多清晰度无缝切换
  • 在 Electron + Web 环境中容易受平台解码能力影响
  • DRM、直播、长视频跳转等能力有限

这类问题在中大型平台已经有成熟的解决方案,核心技术包括 MSE(Media Source Extensions)DASH(Dynamic Adaptive Streaming over HTTP)MPD(DASH 的清单文件格式) 以及配套的播放器库 Shaka Player
在构建小型 Bilibili 项目时,引入这些技术能让播放器具备更专业、更现代化的能力。


1. 为什么不能继续用 <video>

1.1 Buffer 加载模式的局限

<video> 的默认行为是串流拉取整个 MP4 文件,这导致:

  • 初始加载慢
  • 跳转到后面片段时需要重新请求头部数据
  • 清晰度切换要重新加载整个视频
  • 播放过程无法自适应网络波动

对一个类似 Bilibili 的平台来说,用户操作非常频繁:跳转、倍速、清晰度切换,这意味着必须支持更高的灵活性。

1.2 无法满足现代流媒体需求

现代视频网站普遍使用 分片化格式(fragmented MP4 / TS)自适应码率(ABR)
这些都需要浏览器控制视频缓冲区,而 <video> 做不到。

这时就要靠 MSE


2. MSE:现代流媒体的关键能力

MSE(Media Source Extensions) 是浏览器提供的一组 API,用来让 JavaScript 在运行时手动向 <video> 的缓冲区塞数据。
其核心是:

MSE 允许应用自行维护播放器缓冲区,从而实现分片拉取、动态插入、网络自适应控制等能力。

2.1 MSE 能实现什么?

  • 通过 XHR / Fetch 分片拉取视频
  • 按需向 SourceBuffer 推入数据
  • 根据网络情况调整清晰度
  • 直播持续往缓冲区注入新切片
  • 利用浏览器提供的解码能力播放不同格式(mp4, webm, ts)

于是,播放器的控制权从 <video> 转移到应用层。

2.2 MSE 本身并不负责所有功能

MSE 只是一个“底层能力”。
如果要构建一个完整播放器,还需要:

  • 清晰度逻辑
  • 码率切换
  • 缓冲管理
  • MP4/TS 解析
  • DRM
  • 直播时延优化
  • 音视频轨道管理

手写这些成本极高,因此行业中更常使用 DASH + MPD + 播放器库(如 Shaka)。


3. DASH 与 MPD:自适应流媒体的行业标准

3.1 DASH 是什么?

DASH(Dynamic Adaptive Streaming over HTTP) 是视频分片传输的一套协议规范。
核心思想是:

  • 将一个视频切成几十到数百个小片段(1–6 秒)
  • 每个片段有多种码率和分辨率
  • 播放器根据网络实时选择合适的片段
  • 整个过程基于 HTTP,不需要额外协议

这就是常说的 **自适应码率 (ABR)**。

3.2 MPD:DASH 的“清单文件”

要播放 DASH,就需要一个 MPD(Media Presentation Description)文件。

MPD 文件包含:

  • 视频的所有清晰度
  • 每个片段的时长和 URL
  • 直播窗口信息
  • 编码参数
  • DRM 信息
  • 多音轨、多字幕信息

简而言之:

MPD = 视频播放的“地图 + 目录”。

一个类似 Bilibili 的项目需要清晰度多版本管理,MPD 正好解决了视频资源描述问题。


4. Shaka Player:企业级流媒体播放框架

许多库都支持 MSE(hls.js, dash.js, Video.js)。
但在一个结合 Web 与 Electron 的小型视频网站项目中,Shaka Player 是更稳妥的选择,原因包括:

4.1 全平台支持

  • Web
  • Electron
  • 原生 DRM
  • DASH / HLS 自动兼容
  • 完整 MSE 控制

4.2 原生支持 DRM(Widevine)

无需额外插件,直接支持:

  • Widevine
  • PlayReady

对于 Electron 视频平台,这非常重要,因为 Chrome 内核本身就是 DRM 的最佳宿主环境。

4.3 不依赖第三方转码库

Shaka 不需要浏览器原生支持 HLS,它能把 HLS 转成 MSE 可播放的格式。

4.4 API 粒度高

适合深度定制播放器(弹幕同步、倍速、进度管理、清晰度切换等)。


5. 将这些技术应用到个人 Bilibili 项目中

项目目标:
构建一个 Web + Electron 的小型 Bilibili 客户端,支持 DASH、清晰度切换、视频分片加载,并实现可靠的播放体验。

下面将整个技术路线完整结合起来。


5.1 资源准备:将视频切成 DASH 分片并生成 MPD

一般流程:

  1. 使用 FFmpeg 或转码服务生成:

    • 多码率视频(240P/480P/720P/1080P)
    • 分片(segment)
  2. 生成 MPD 文件

  3. 将所有资源放在 CDN 或服务器可访问位置


5.2 播放端架构:Electron + Web + Shaka Player

播放器流程:

1
2
3
4
             CDN / 服务器
↓ MPD 文件
Electron / Web App ——→ Shaka Player ——→ MSE ——→ <video>
↑ 分片请求(按需)

Shaka 负责:

  • 读取 MPD
  • 选择合适的视频分片
  • 进行 ABR
  • 控制 MSE buffer
  • 支持清晰度切换 + 码率切换
  • DRM 解密(如果使用)

应用只需要:

  • 调用 Shaka API
  • 提供 UI(播放按钮、清晰度列表等)

5.3 为什么这种结构适合一个“个人 Bilibili”项目?

稳定的 DASH 播放能力

普通 <video> 无法支持分片、清晰度列表、码率自适应。

方便扩展

未来可以扩展:

  • 直播
  • DRM
  • 多音轨
  • 弹幕同步
  • 预加载策略优化
  • 缓冲区监控

Shaka 提供 API 完全满足。

Web + Electron 统一开发

Electron 使用 Chromium 内核,兼容 MSE 和 DRM 标准,是开发播放器的绝佳环境。

Powered by Hexo & Theme Keep
Total words 32.9k