前言
作为开发者或极客,我们总觉得屏幕不够用。虽然市面上有不少便携显示器,但手边的 iPad、安卓平板甚至大屏手机其实就是一块绝佳的屏幕。
常见的将平板作为电脑副屏的方案(如 VNC、Deskreen)通常存在以下痛点:
- 延迟高:鼠标移动有明显的'飘'感。
- 画质差:压缩痕迹严重,看文字累眼。
- 收费:好用的商业软件(如 Duet Display)往往价格不菲。
- :很多方案只能镜像主屏,无法作为真正的显示器使用。
基于 Sunshine 服务端与 Moonlight 客户端,配合 NVIDIA 虚拟显示技术,在 Ubuntu 系统下将平板配置为高性能扩展屏幕。通过 Xorg 配置强制开启虚拟显示器,锁定 Sunshine 捕获特定输出,实现低延迟、高画质的桌面流媒体传输,无需额外硬件即可解决多屏需求,适用于双显卡笔记本环境。
作为开发者或极客,我们总觉得屏幕不够用。虽然市面上有不少便携显示器,但手边的 iPad、安卓平板甚至大屏手机其实就是一块绝佳的屏幕。
常见的将平板作为电脑副屏的方案(如 VNC、Deskreen)通常存在以下痛点:
本文将介绍一种低延迟、高画质、完全免费的'硬核'方案:利用开源游戏流媒体工具 Sunshine (服务端) 和 Moonlight (客户端),配合 NVIDIA 显卡 的虚拟显示技术,在 Linux (Ubuntu 24.04) 上'无中生有'地创造出一块虚拟屏幕,并将其流式传输到你的平板上。
核心优势:
Sunshine 是 NVIDIA GameStream 协议的开源实现。相比 VNC 等远程桌面协议,它利用 GPU 进行硬件编码(NVENC),效率极高,专为对延迟极度敏感的游戏场景设计,用来做桌面扩展简直是'降维打击'。
本教程基于以下笔记本环境进行配置:
.apk 文件。服务端 (PC):
前往 Sunshine GitHub Releases 下载适用于 Ubuntu 24.04 的 .deb 包并安装:
sudo apt install ./sunshine_*.deb
安装后启动 Sunshine 服务:
systemctl --user start sunshine
systemctl --user enable sunshine
这是最关键也最容易踩坑的一步。在双显卡笔记本上,通常 Intel 核显负责内屏,NVIDIA 独显负责外接口。我们需要强制 NVIDIA 驱动开启一个并没有连接真实显示器的端口。
我们需要修改或创建 /etc/X11/xorg.conf。
1. 准备 EDID 文件
显卡需要 EDID 信息才知道显示器支持什么分辨率。既然是虚拟显示器,我们可以'借用'现有显示器的 EDID。
假设你已经连接了一个 HDMI 显示器(可以通过 xrandr 查看名称,如 HDMI-1-0 或在 /sys/class/drm/ 下查找):
# 复制现有显示器的 EDID 到系统目录
sudo cp /sys/class/drm/card1-HDMI-A-1/edid /etc/X11/edid.bin
# 注意:路径中的 card1-HDMI-A-1 需根据你的实际情况调整,可能是 card0 或 card2
2. 编辑 /etc/X11/xorg.conf
备份原文件(如果有),然后写入以下配置。这段配置极其关键,请仔细阅读注释:
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0"
# 定义第二个屏幕 Screen1,放在 Screen0 右边
Screen 1 "Screen1" RightOf "Screen0"
# 关键选项:允许 NVIDIA GPU 在有 Intel 核显的情况下独立管理屏幕
Option "AllowNVIDIAGPUScreens"
EndSection
Section "Device"
Identifier "intel"
Driver "modesetting"
# Intel 核显的总线 ID,使用 lspci | grep VGA 查看 (例如 00:02.0 对应 PCI:0:2:0)
BusID "PCI:0:2:0"
EndSection
Section "Device"
Identifier "nvidia"
Driver "nvidia"
# NVIDIA 独显的总线 ID (例如 01:00.0 对应 PCI:1:0:0)
BusID "PCI:1:0:0"
# 核心魔法:强制 NVIDIA 认为连接了两个显示器
# DFP-0 是真实的物理外接显示器 (如果没接外接屏,这里可能只需要配置虚拟的)
# DFP-1 是我们要伪造的虚拟显示器
Option "ConnectedMonitor" "DFP-0,DFP-1"
# 为虚拟显示器 DFP-1 指定我们刚才复制的 EDID 文件
Option "CustomEDID" "DFP-1:/etc/X11/edid.bin"
# 忽略 EDID 校验,允许强制设置分辨率
Option "ModeValidation" "DFP-1:AllowNonEdidModes,NoMaxPClkCheck"
EndSection
Section "Screen"
Identifier "Screen0"
Device "intel"
EndSection
Section "Screen"
Identifier "Screen1"
Device "nvidia"
EndSection
配置解析:
ConnectedMonitor: 欺骗驱动,让它以为特定端口上有显示器。CustomEDID: 赋予虚拟显示器'灵魂',让系统知道它支持什么分辨率(1080p, 2k 等)。保存后,重启电脑。
重启后,打开终端输入 xrandr。
如果配置成功,你应该能看到一个新的输出端口(例如 DP-1-0 或 DP-0)显示为 connected,并且可以设置分辨率。
此时,在 Ubuntu 的'设置 -> 显示器'中,你应该能看到这块新屏幕,并可以调整它的位置。
现在我们需要告诉 Sunshine:'不要录制整个桌面,只录制这块虚拟屏幕'。
https://localhost:47990)。如何查找正确的 Display ID?
查找方法如下。最准确的方法是查看 Sunshine 的日志。
在终端运行:
journalctl --user -u sunshine -f | grep "Detected display"
此时重启一下 Sunshine (systemctl --user restart sunshine),观察日志输出。你会看到类似这样的信息:
... Info: Detected display: eDP-1 (id: 0) connected: true ...
Info: Detected display: HDMI-1-0 (id: 1) connected: true ...
Info: Detected display: DP-1-0 (id: 4) connected: true
这里 DP-1-0 就是我们的虚拟显示器,它的 id 是 4。
~/.config/sunshine/sunshine.conf (或者在 Web UI 中设置):[general]
# 刚才查到的 ID
output_name = 4
[video]
# 强制使用 X11 捕获模式,对虚拟显示器兼容性更好
capture = x11
[audio]
# 如果不需要平板发声,可以留空或配置 sink
# audio_sink =
为了让鼠标移动符合物理摆放,可以使用 xrandr 快速调整布局。
假设笔记本屏 (eDP-1) 在左,虚拟平板屏 (DP-1-0) 在中,外接显示器 (HDMI-1-0) 在右:
# 假设每个屏幕宽 2560
xrandr --output eDP-1 --pos 0x0 --output DP-1-0 --pos 2560x0 --output HDMI-1-0 --pos 5120x0
你可以将此命令保存为脚本,每次连接前运行。
此时平板即显示 Ubuntu 扩展桌面。
Q1: Moonlight 报错 'Error 503' 或画面黑屏
output_name 是否填错了 ID,显示接口的 ID 在重启后可能会变,务必看日志。capture 模式改为 x11 (默认可能是 kms)。Q2: Sunshine 日志提示 'Couldn't find monitor'
xrandr 中是 connected 状态。如果 xrandr 里都没有,说明 xorg.conf 配置失败。Q3: 虚拟显示器分辨率不对/无法调整
xrandr --addmode 手动添加分辨率,或者在 xorg.conf 的 ModeValidation 中确保添加了 AllowNonEdidModes。Q4: 鼠标在平板上无法点击
sudo usermod -a -G input $USER 确保当前用户有输入设备权限,重启生效。如果后续需要移除所有配置,可以执行以下步骤:
# 删除 sunshine 配置
rm -f ~/.config/sunshine/sunshine.conf
# 删除 xorg.conf 和 EDID 文件
sudo rm -f /etc/X11/xorg.conf /etc/X11/edid.bin
# 停止 sunshine
systemctl --user stop sunshine
# 重启电脑
sudo reboot
# 卸载 sunshine(保留配置文件)
sudo dpkg -r sunshine
# 卸载并删除所有配置文件
sudo dpkg -P sunshine
# 重启电脑
sudo reboot

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online