惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
P
Proofpoint News Feed
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
Microsoft Security Blog
Microsoft Security Blog
F
Fortinet All Blogs
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
美团技术团队
D
Docker
博客园 - Franky
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

树 - 洞

SMTP2GO 拯救你的 25 端口限制 | 树 SMTP2GO 拯救你的 25 端口限制 | 树 Bilibili Linux 客户端 VAAPI 硬解折腾全记录 | 树 震惊!insmtr 的 MySQL 数据库居然被勒索软件攻击了! | 树 震惊!insmtr 的 MySQL 数据库居然被勒索软件攻击了! | 树 再探阿里云 DNS 对 CloudFront 的解析情况 | 树 再探阿里云 DNS 对 CloudFront 的解析情况 | 树 为单板机配置超简单 VNC 环境 改良版 | 树 为单板机配置超简单 VNC 环境 改良版 | 树 Ubuntu 22.04 Rust OpenCV 注意事项 | 树 Redmi AX6000 hanwckf U-Boot 安装 OpenWrt 24 | 树 为单板机配置超简单 VNC 环境 | 树 Ubuntu 22.04 Rust OpenCV 注意事项 | 树 Redmi AX6000 hanwckf U-Boot 安装 OpenWrt 24 | 树 为单板机配置超简单 VNC 环境 | 树 在 WSL 中使用 ISE | 树 在 WSL 中使用 ISE | 树 Jetson AGX Orin CH340 驱动安装 | 树 Jetson AGX Orin CH340 驱动安装 | 树 在 Ubuntu 22.04 上运行 PX4-Autopilot 1.13 | 树 在 Ubuntu 22.04 上运行 PX4-Autopilot 1.13 | 树 在 Thunderbird 里使用沉浸式翻译插件 | 树 在 Thunderbird 里使用沉浸式翻译插件 | 树 搭建自定义域名邮箱 | 树 - 洞 搭建自定义域名邮箱 | 树 - 洞 Android Box for root 透明代理 | 树 再见,曾经热爱的算法竞赛 | 树 - 洞 再见,曾经热爱的算法竞赛 | 树 - 洞
Bilibili Linux 客户端 VAAPI 硬解折腾全记录 | 树
insmtr · 2026-05-18 · via 树 - 洞

可能和大部分小伙伴的习惯不同,我平时比较喜欢使用 B 站的客户端看视频,不喜欢网页端。可是有个问题一直卡了我很久,那就是 B 站的 Linux 客户端 bilibili-linux 项目一直不支持 VAAPI 硬件加速,导致我在看高清视频的时候 CPU 占用率非常高,视频也掉帧严重。

搜索后发现,和我有类似抱怨的用户还不少。近些年,这个项目的 issue 里也有至少 5 个讨论了这个问题,但是基本都是无果而终。

尝试

之前在安装 Arch Linux 的时候,我参考了极地萤火的 Arch Linux 安装笔记,笔记中提到,对于 Electron 应用,可以在启动参数中加入 --enable-features=AcceleratedVideoDecodeLinuxZeroCopyGL,AcceleratedVideoDecodeLinuxGL 来启用 VAAPI 硬件加速。这个参数对于 Edge 浏览器来说确实是有效的,实测在 ~/.config/microsoft-edge-stable-flags.conf 中加上这个参数后在 Edge 中观看 B 站视频时可以正常调用 VAAPI 加速。于是我就尝试在 B 站客户端的启动参数中也加入这个参数,却无果。

顺带一提,B 站客户端的启动参数可以写在 ~/.config/bilibili-flags.conf 中,也可以写在 ~/.config/bilibili/bilibili-flags.conf 中,两者都可以被识别到。前者是 bilibili 启动脚本中解析并追加到 Electron 命令行里的,后者是 bilibili 启动后内部的 electron-tool 模块在 Electron 主进程启动后读取的,因此两者都生效。

转机

既然 Edge 浏览器都能正常调用 VAAPI,说明我这套系统环境里的 VA-API 驱动、Mesa/libva 和硬件本身大概率是可用的,作为同样 Electron 出身的 B 站客户端也理应支持。

在翻阅 bilibili-linux 项目的 issue 时,我看到了一例成功案例。issue #193 中,有用户提到,可以在启动参数中加入如下参数:

--ignore-gpu-blocklist
--disable-gpu-driver-bug-workarounds
--enable-gpu-rasterization
--enable-zero-copy
--enable-native-gpu-memory-buffers
--enable-features=VaapiVideoDecodeLinuxGL,VaapiVideoEncoder,PlatformHEVCDecoderSupport,CanvasOopRasterization
--disable-features=UseChromeOSDirectVideoDecoder

可是我实测后发现,加上这些参数后我的 B 站客户端播放视频时直接花屏了!无论是我点开视频播放,还是鼠标在视频封面悬停预览,都会出现横向的条纹状的花屏,完全无法正常观看视频。但是打开 intel_gpu_top 一看,发现 Video 视频解码单元确实被调用了,说明这套参数确实让 B 站调用了 VAAPI,所以问题更可能出在显示 / 合成路径上。

思考片刻后,我意识到,这很可能是 Electron 的版本问题导致的。B 站客户端目前使用的 Electron 版本是 28,而主流的 Electron 应用再低也都是三十几了。bilibili-linux 的作者为了确保兼容性,也使用了 28 版本。那换上更高版本的 Electron 会不会解决这个问题呢?

我果断创建了一个新的 wrapper,将启动脚本里调用的 Electron 改成了 37,而启动参数里我只写了 --enable-features=AcceleratedVideoDecodeLinuxZeroCopyGL,AcceleratedVideoDecodeLinuxGL,和 Edge 一样的参数。结果一测试,视频可以正常播放了!intel_gpu_top 中的 Video 视频解码单元也确实被调用了,CPU 占用率也从之前的 90% 降到了 30% 左右,视频也不再掉帧了!

后来又测试了多个中间版本的 Electron,发现从 36 开始就不再花屏了。

原理

后来,我针对这一系列现象查阅了资料,也询问了 AI,得到了一些答案:

为什么最初的时候,同样的参数在 Edge 上有效,在 B 站客户端上却无效? 我一开始照着新版 Edge/Chromium 的写法,在 Electron 28/Chromium 120 上使用 AcceleratedVideoDecodeLinuxZeroCopyGL,AcceleratedVideoDecodeLinuxGL,但 Chromium 120 当时的 Linux VAAPI GL feature 还叫 VaapiVideoDecodeLinuxGL。因此把新版 flag 直接塞给 Electron 28,没法启用旧版的 VAAPI GL 解码路径。

为什么我加上了那些参数后虽然花屏了,但是却能成功调用 VAAPI? issue #193 中这组里包含 --ignore-gpu-blocklist--disable-gpu-driver-bug-workarounds--enable-zero-copy 等比较激进的开关,可能绕过了 Chromium 对 GPU / 驱动组合的一些保守判断。同时,它使用了 Chromium 120 能识别的旧 feature 名 VaapiVideoDecodeLinuxGL。因此,它能触发硬解路径。因此这套参数没错,只是我的核显型号太新了,被 Chromium 按保守路线降级了。

为什么加上了那些参数后会花屏? 这个花屏说明 VAAPI 解码路径被触发后,后续的视频帧导入、纹理上传、DMABUF modifier、GL 合成或显示后端链路里仍然存在兼容性问题。它不一定是「解码器不能解码」,更像是「解码后的图像没有被正确显示」。Chromium 131 把 VaapiVideoDecodeLinuxGL 统一改名为 AcceleratedVideoDecodeLinuxGL,旧 flag 失效,可是用了新 flag 后这个 bug 依旧存在。一直到 Chromium 136 之后画面才变得正常,所以我这套硬件升级到 Electron 36 就不会有这个问题了。

为什么换到 Electron 36 之后,两个简单的 flag 就够了? Electron 36 对应 Chromium 136,这个版本距 Chromium 120 跨越了整整 16 个版本。Linux VAAPI、ANGLE/GL、DMABUF、Wayland/EGL 以及 Intel 新平台相关代码都有持续变化。AcceleratedVideoDecodeLinuxGL 在新版 Chromium 里走的渲染路径已经能正确处理 MTL 的纹理格式。

结语

总的来说,这次折腾虽然有点曲折,但最终还是成功了。现在我终于可以在 B 站客户端上愉快地看高清视频了!希望这个经验也能帮助到其他有同样问题的小伙伴们。