跳转至

Evey 中的 ac3go

简而言之:

  • Chrome、Firefox 和 Edge 无法播放杜比数字(AC-3)或杜比数字增强版(E-AC-3)的声音。Evey 的网页播放器不让服务器转换它,而是在网页里自己解码,用的是 ac3go:一个以 WebAssembly 形式在浏览器里运行的解码器。
  • 声音按文件里的原样到达您这里,服务器不需要为此做任何音频转换。
  • 您不用设置任何东西。播放器的流信息会把音频显示为客户端解码,管理 → 正在播放会为这条音轨显示播放器内 ac3go。
  • 如果解码器无法运行,播放器会自动改用服务器转换的声音(AAC)。

本页其余部分说明什么时候走这条路、声音如何与画面保持同步,以及电影没有声音时该检查什么。播放哪条音轨,以及一般情况下音轨何时被复制或转换,见音频。

ac3go 作为一个独立的库开发,用 Go 编写,没有任何依赖:github.com/gravity-zero/ac3go。

浏览器什么时候自己解码声音

必须同时满足以下所有条件:

条件 否则
浏览器自己无法播放 AC-3 或 E-AC-3,并且能运行 WebAssembly。播放器会就这两点测试浏览器,而不是根据名称来识别它。 能原生解码杜比数字的浏览器(例如 Safari)会把这条音轨当作普通音轨接收。
正在播放的音轨是 AC-3 或 E-AC-3。电影的其他音轨不算在内。 其他编解码器按音频里的规则处理。
音轨最多六个声道(5.1),且不超过个人资料的最大音频声道。这条路按文件里的原样交付音轨,所以无法混缩声道。 服务器把音轨转换为 AAC,可以为立体声个人资料混缩声道。7.1 的 E-AC-3 音轨总是会被转换。
电影通过服务器的视频流播放(重封装或转码),而不是直接读取文件。 音轨按这次播放的决定处理。

播放过程

画面通过浏览器平常的播放器播放;它的流里不带任何音轨,播放器的音量和静音控制改为驱动声音引擎的增益。声音来自一条单独的音频流,由服务器在播放列表里给出:按文件里原样的音轨,能用 MKVGo 打包时由它打包,否则由 FFmpeg 复制。两者都不对它解码。

在网页里,一个后台线程(worker)加载 ac3go,把每个音频分段解码成普通声音,与绘制画面的代码分开进行。然后播放器通过浏览器的音频输出播放这些声音,跟着画面的节奏:画面提供时钟,声音依照它来安排。暂停会让两者一起停下。在电影里跳转,或者视频流卡住后出现空档,都会让声音重新对齐到新的位置。

5.1 音轨会按浏览器期望的声道顺序交给浏览器,这样它就能为立体声扬声器或耳机混缩。

电影开始时,解码器需要片刻来加载。如果服务器也提供了转换为 AAC 的同一音轨,这片刻里播放的就是这个声音,ac3go 一准备好就接手。浏览器只下载一次解码器,并在每次使用时重新检查它,所以服务器更新后绝不会把旧版本和新版本混在一起。

如果 ac3go 无法运行

当解码器加载失败、在某个分段上出错,或者服务器没有给它指定音频流时,播放器会在这部影片剩下的时间里不再使用它,并向服务器请求普通的视频流,其中的声音已转换为 AAC。电影仍然有声音;此时流信息会显示转换,而不是客户端解码。

Warning

如果反向代理设置了自己的 Content-Security-Policy,就必须在 script-src 里允许 'wasm-unsafe-eval',否则解码器无法启动。它还必须像网页应用的其他部分一样,提供 /wasm/ 下的解码器文件。见反向代理配置。

在投屏接收器上

Evey 的 Chromecast 接收器不使用 ac3go。在内存较小的电视盒子上,用这种方式解码声音的接收器播放几分钟后就会停止。当接收器报告它能直通杜比数字时,电视会收到原样的杜比数字,否则收到服务器的 AAC:见投屏到 Chromecast。

这个库及其许可证

ac3go 与 Evey 一样,以 GNU AGPLv3 发布。构建 Evey 镜像时会从源代码编译它(用 Go 工具编译为 WebAssembly),它的许可证与解码器一起提供,地址是 /wasm/ac3go.LICENSE.md。