V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kuanat
V2EX  ›  分享发现

一个好用的、纯软件的扩展屏方案

  •  
  •   kuanat · 14 天前 · 619 次点击

    起因是 /t/1044916 这个帖子,我原本认为这个方法会在开发者群体里很普遍,结果问了一圈才发现几乎没人用。我在 B 站也尝试搜索了一下,没有看到类似的用法,所以就有了这个帖子。

    1. 这个方案解决了什么问题

      • 外出环境需要扩展副屏,用于临时多屏提高效率或者展示

      • 老旧平板废物利用

    2. 这个方案的优点在哪里

      • 只依赖开源软件,免费可信。无需采集卡、或者商业软件

      • 无需物理连线,任何手机、平板都可以作为副屏

      • 可扩展的屏幕数量没有上限,不需要 HDMI 欺骗头

      • 可以自定义输出的分辨率,主动匹配显示设备( HDMI 欺骗头也可以通过重写 EDID 来实现,但不如软件方便)

      • 支持低功耗(远程桌面)和低延迟(串流)模式,在移动办公场景,远程桌面模式几乎不会带来功耗增加

      • 支持副屏单独操作副屏的窗口,不影响主机操作( multi-seat 或者多焦点,这个功能仅限 Linux 主机)

    3. 实现原理

      原理简单说分两部分,一部分是传统的 vnc/rdp/sunshine 软件,前两者是远程桌面模式,后者是串流模式。

      由于单纯的远程桌面、串流都需要先有一个桌面,属于镜像模式,对于“扩展屏”的场景来说没有帮助。所以第二个部分就是如何增加一个虚拟的桌面。

      之前的方法是 HDMI 欺骗头,这样就只能输出一个副屏。软件的方法如下:

      • Windows 使用 Virtual-Display-Driver 也有其他的实现可以用

      • Linux 目前有 X11/wayland 两个显示框架,X11 有 xvfb/xrdp 可以用,我很久都没用过 X11 了,所以这两个仅供参考,但是 X11 的支持是没什么问题的。

        Wayland 的话 KDE/KWin 是不行的。Gnome/Mutter 在 42 版本为了自家 rdp 应用增加了一个功能,可以创建一个虚拟桌面,这个 rdp 应用可以把这个虚拟显示器作为后端。wlroots 的实现 sway/hyprland 都支持直接创建。

      • macOS 我不知道……我主动远离苹果生态很久了。欢迎补充。

      剩下的事情就顺理成章了,让 vnc/rdp/sunshine 跑在这个虚拟显示器就可以。

      这样就可以根据显示设备的分辨率,创建一个虚拟显示器。平板手机连接对应的 vnc/rdp/moonlight 即可点对点显示。

    4. 实现原理续

      远程桌面模式需要实际测试一下 vnc/rdp/moonlight 客户端。

      以 Android 平板上的 vnc 客户端为例,如果需要在平板上滑动屏幕,实现显示区域里的浏览器窗口滚动,就需要这个 vnc 客户端将平板的输入映射为鼠标滚轮(或者手势)传递给 vnc 服务器端。不是所有的客户端都实现了类似的功能。

      Sway wm 环境还可以使用 seat 的功能对输入进行分组。vnc 服务器端会创建虚拟的鼠标、键盘或者触摸板输入设备,当客户端有输入传入时,相应指令就会通过虚拟设备发送给系统。

      这样能够实现实现:主机和触摸屏有两组输入焦点,副屏由于物理限制只能使用副屏桌面的应用。这对于演示场景非常有用,展示应用在副屏,客户还可以通过触屏实际体验。而主屏幕任何操作都不会受影响。

    5. 额外补充

      如果需要非常低的延迟,优选 sunshine/moonlight 的串流模式。由于现在的 cpu 普遍有硬件编码器,而平板作为播放器又都有硬件解码器,这个功能对于平板几乎没有硬件限制,十年前能硬解 h264 的即可,稍微新一点的硬件都可以利用上 hevc/av1 方案。

      实测下来,1080p60~10Mbps 大概硬件编码器功耗在 0.8W 左右,虽然比较低,但是会导致 cpu 一直后台处理网络功能,无法进入低功耗状态,所以只推荐固定场景有外接电源时使用。

      相对来说,vnc/rdp 模式更适合静态展示或者终端应用,这一类都是基于画面变化传输数据,对于功耗续航的影响很小,开手机热点即可快速建立连接。

      外出组网,方便的是手机开热点,然后笔记本和平板都连接热点。如果是笔记本开热点需要手动设置,一个频段上网,另一个频段共享。反过来平板开热点,平板有可能访问不到在热点子网里的笔记本。

    6. 使用指南

      这里就以我用的 sway/wayvnc 做个说明,其他的根据自己情况调整即可。需要做的就是两件事,创建虚拟输出,然后把输出投屏出去。图我就不放了,大家脑部一下效果就好。

    # 创建虚拟输出
    swaymsg create_output
    
    # 由于目前 wlroots 实现,这个输出的名字默认为 HEADLESS-1 ,继续创建则为 HEADLESS-2 以此类推
    # 可以在 sway config 中预定义其输出参数,也可以通过 IPC 手动调整
    # 在 (2560,0) 位置创建 1920x1200 的虚拟显示器
    swaymsg output HEADLESS-1 mode 1920x1200 pos 2560,0
    
    # 启动 vnc 服务端并将 HEADLESS-1 作为显示后端,设定监听入口
    wayvnc --output=HEADLESS-1 0.0.0.0 5900
    
    # 如果需要单独输入设备为单独 seat
    # 目前 wayvnc 不支持直接创建 seat ,所以需要先创建 seat1 来占位,系统默认的是 seat0
    swaymsg seat seat1 attach PLACEHOLDER
    
    # 将 wayvnc 输入设备绑定到 seat1
    wayvnc --output=HEADLESS-1 --seat=seat1 0.0.0.0 5900
    
    # 临时切断副屏输出
    swaymsg output HEADLESS-1 toggle
    
    # 反正用 sway 的基本都有自己的自动化逻辑,这一整套可以完全自定义
    
    2 条回复    2024-06-04 22:45:38 +08:00
    swordsmile
        1
    swordsmile  
       13 天前
    如果是 Hyprland ,如何创建虚拟 seat 呢
    kuanat
        2
    kuanat  
    OP
       13 天前
    @swordsmile #1

    Hyprland 目前还不支持 multi-seat 功能 https://github.com/hyprwm/Hyprland/issues/1731

    这也是我一直主用 sway 的原因。其他方面 hyprland 易用性好太多了,不得已我还给 sway 写了个简陋的 master stack 布局管理器……

    另外还有些 layer-shell 协议的应用(悬浮显示状态、通知和关机菜单这一类)也是硬编码了 seat0 的,有可能会导致显示位置或者输入焦点异常。对我影响比较大的是 tofi (一个 wofi 的改版)会有输入焦点问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3178 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 11:31 · PVG 19:31 · LAX 04:31 · JFK 07:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.