Arch Linux KDE Wayland 下腾讯会议屏幕共享黑屏修复
问题现象
大概一两个月前,在 KDE Plasma Wayland 环境中使用腾讯会议时,突然无法正常查看其他参会者共享的屏幕了,这个情况困扰了我很久,导致经常不得不用手机来参会。今天有空闲时间,上网搜索了一下,终于找到了解决方案。
本机环境大致如下:
- Arch Linux
- KDE Plasma Wayland
wemeet-bin 3.26.10.401-1- Intel 核显 + NVIDIA RTX 4060 Max-Q 混合显卡
xdg-desktop-portal-kde、PipeWire、WirePlumber
原因定位
此前腾讯会议也有问题,根据AUR对应包的评论区中的建议,修改方案是添加一个环境变量:
1 | __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json |
这个主要是之前的解决方案,很长一段时间内是管用的。但是最近失灵了。根据Arch Linux CN论坛中网友的说法,是以下两个地方出现问题:
1. Wemeet 的 DBus 调用存在时序问题
屏幕共享请求应该依次完成:
1 | CreateSession → SelectSources → Start → OpenPipeWireRemote |
但当前版本在 SelectSources 完成前就调用了 Start。某些 portal 后端会容忍这个竞态,另一些后端则会导致共享请求失败或没有视频数据。
2. PipeWire 颜色格式协商不兼容
Wemeet 原本硬编码了 BGRx 等颜色格式,而当前 portal 后端可能协商出 RGBx。格式协商失败时,界面可能已经显示“正在共享”,但实际没有可显示的视频帧,于是看到黑屏或白屏。
具体解释还是要看源仓库中的文档。
解决方法
使用该网友自行逆向后给出的补丁 wemeet-screenshare-patch 修复 Wemeet 的屏幕共享二进制。该补丁包含:
- Hunk 0:修复 DBus
SelectSources与Start的异步调用顺序。 - Hunk 1a/1b:修复 PipeWire 的颜色格式协商,并通过 hook 转换缓冲区颜色格式。
1. 下载补丁并备份原文件
1 | git clone --depth=1 https://github.com/Matheritasiv/wemeet-screenshare-patch.git /tmp/wemeet-screenshare-patch |
2. 适配 Arch Linux 的文件布局
可以直接按照
README说的去做,也可以看下面的解决方案,Codex实际的操作步骤。
补丁仓库默认假设 libxcast.so 位于 /opt/wemeet/lib/,但 Arch 的 wemeet-bin 将它安装在 /usr/lib/wemeet/。因此需要复制一份补丁脚本并调整两个路径:
1 | cd /tmp/wemeet-screenshare-patch |
先执行 dry-run,确认当前 Wemeet 版本匹配:
1 | python3 patch-arch.py / --dry-run |
看到所有 Hunk 都显示 [OK] 后再正式写入:
1 | sudo python3 patch-arch.py / |
3. 安装 hook 到用户目录
1 | mkdir -p ~/.local/lib/wemeet-screenshare-patch |
临时测试启动:
1 | env __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json LD_PRELOAD="$HOME/.local/lib/wemeet-screenshare-patch/libhook.so" wemeet |
固定到 KDE 应用启动项
创建用户级桌面文件,避免修改系统包管理的文件:
1 | mkdir -p ~/.local/share/applications |
将用户级文件中的 Exec 改为:
1 | Exec=env __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json LD_PRELOAD=/home/ziyu/.local/lib/wemeet-screenshare-patch/libhook.so wemeet %u |
如果文件中存在下面这一项,建议设置为 false,避免 KDE 再次强制使用 NVIDIA:
1 | PrefersNonDefaultGPU=false |
刷新 KDE 应用菜单缓存:
1 | kbuildsycoca6 --noincremental |
之后从 KDE 应用菜单启动腾讯会议即可。
不要安装旧的 wemeet-wayland-screenshare-git
这个项目已经归档,而且它仍然使用 OpenCV 旧版 C API。当前 Arch 的 OpenCV 5 已经移除了:
1 | opencv2/core/core_c.h |
因此安装它会在编译阶段失败。这和 Wemeet 本次黑屏问题是两个不同的问题;当前应直接修补 wemeet-bin 自带的屏幕共享模块。
Warning
wemeet-screenshare-patch 直接修改 /opt/wemeet 和 /usr/lib/wemeet 中的二进制文件。以后升级 wemeet-bin 后,补丁可能被覆盖,需要重新备份、dry-run 并应用补丁。不要将 __EGL_VENDOR_LIBRARY_FILENAMES 全局写入系统环境变量,只对腾讯会议设置即可。