跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Shell / Bash

基于 Sunshine + Moonlight 将平板作为 Linux 扩展屏方案

基于 Sunshine 服务端与 Moonlight 客户端,配合 NVIDIA 虚拟显示技术,在 Ubuntu 系统下将平板配置为高性能扩展屏幕。通过 Xorg 配置强制开启虚拟显示器,锁定 Sunshine 捕获特定输出,实现低延迟、高画质的桌面流媒体传输,无需额外硬件即可解决多屏需求,适用于双显卡笔记本环境。

魔尊发布于 2026/3/15更新于 2026/7/2452 浏览

前言

作为开发者或极客,我们总觉得屏幕不够用。虽然市面上有不少便携显示器,但手边的 iPad、安卓平板甚至大屏手机其实就是一块绝佳的屏幕。

常见的将平板作为电脑副屏的方案(如 VNC、Deskreen)通常存在以下痛点:

  • 延迟高:鼠标移动有明显的'飘'感。
  • 画质差:压缩痕迹严重,看文字累眼。
  • 收费:好用的商业软件(如 Duet Display)往往价格不菲。
  • 只是镜像:很多方案只能镜像主屏,无法作为真正的扩展显示器使用。

本文将介绍一种低延迟、高画质、完全免费的'硬核'方案:利用开源游戏流媒体工具 Sunshine (服务端) 和 Moonlight (客户端),配合 NVIDIA 显卡 的虚拟显示技术,在 Linux (Ubuntu 24.04) 上'无中生有'地创造出一块虚拟屏幕,并将其流式传输到你的平板上。

核心优势:

  • 极低延迟:基于主要用于云游戏的流媒体技术,局域网内延迟通常低于 10ms。
  • 真·扩展屏:不是镜像,而是系统层面识别出的独立显示器,窗口可以拖过去。
  • 纯软件实现:无需购买显卡欺骗器(Dummy Plug)等硬件。

方案原理

核心思路
  1. 虚拟显示器:利用 NVIDIA 驱动的特性,在 X11 系统中强制开启一个物理上不存在的显示接口(Virtual Display)。
  2. 桌面扩展:操作系统将这个虚拟接口识别为真实显示器,你可以在系统设置里排列它的位置。
  3. 定向推流:配置 Sunshine 仅捕获这个虚拟显示器的画面。
  4. 客户端接收:平板上的 Moonlight 连接 Sunshine,显示画面并回传触摸/鼠标操作。
为什么选择 Sunshine + Moonlight?

Sunshine 是 NVIDIA GameStream 协议的开源实现。相比 VNC 等远程桌面协议,它利用 GPU 进行硬件编码(NVENC),效率极高,专为对延迟极度敏感的游戏场景设计,用来做桌面扩展简直是'降维打击'。


环境与硬件要求

本教程基于以下笔记本环境进行配置:

  • 操作系统: Ubuntu 24.04 LTS (使用 X11 窗口系统,暂不推荐 Wayland)
  • 显卡配置: 双显卡笔记本
    • iGPU: Intel Iris Xe (负责内屏 eDP)
    • dGPU: NVIDIA RTX 3060 (负责外接 HDMI/DP)
  • 显示设备:
    • 笔记本自带屏幕 (eDP-1)
    • 物理外接显示器 (HDMI-1-0)
    • 目标: 新增一个虚拟显示器 (DP-1-0) 推流给平板
  • 客户端设备: 华为平板 (HarmonyOS 6.0) 、小米 pad5 pro 或任意安装 Moonlight 的设备

详细配置步骤

第一步:安装 Sunshine 和 Moonlight
  1. 客户端 (平板): 在应用商店下载 Moonlight Game Streaming,或者前往 Moonlight Android Github Releases 安装对应的 .apk 文件。

服务端 (PC): 前往 Sunshine GitHub Releases 下载适用于 Ubuntu 24.04 的 .deb 包并安装:

sudo apt install ./sunshine_*.deb

安装后启动 Sunshine 服务:

systemctl --user start sunshine
systemctl --user enable sunshine
第二步:攻克双显卡难关 —— 配置 Xorg

这是最关键也最容易踩坑的一步。在双显卡笔记本上,通常 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 锁定虚拟屏

现在我们需要告诉 Sunshine:'不要录制整个桌面,只录制这块虚拟屏幕'。

  1. 打开 Sunshine Web 管理界面(通常是 https://localhost:47990)。
  2. 进入 Configuration -> Audio/Video。
  3. 找到 Output Name。这里不能随便填,需要填入系统的 Display ID。

如何查找正确的 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。

  1. 修改 Sunshine 配置文件 ~/.config/sunshine/sunshine.conf (或者在 Web UI 中设置):
[general]
# 刚才查到的 ID
output_name = 4

[video]
# 强制使用 X11 捕获模式,对虚拟显示器兼容性更好
capture = x11

[audio]
# 如果不需要平板发声,可以留空或配置 sink
# audio_sink =
第五步:调整屏幕布局 (xrandr)

为了让鼠标移动符合物理摆放,可以使用 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

你可以将此命令保存为脚本,每次连接前运行。


连接与使用

  1. 平板连接 WiFi (建议 5GHz 频段)。
  2. 打开 Moonlight,搜索局域网主机。
  3. 点击连接,输入 PIN 码配对。
  4. 在应用列表中选择 Desktop。

此时平板即显示 Ubuntu 扩展桌面。


常见问题排查 (Troubleshooting)

Q1: Moonlight 报错 'Error 503' 或画面黑屏

  • 原因: Sunshine 无法捕获指定的画面。
  • 解法:
    1. 检查 output_name 是否填错了 ID,显示接口的 ID 在重启后可能会变,务必看日志。
    2. 尝试将 capture 模式改为 x11 (默认可能是 kms)。

Q2: Sunshine 日志提示 'Couldn't find monitor'

  • 原因: 配置文件里的显示器名称或 ID 不存在。
  • 解法: 确保虚拟显示器在 xrandr 中是 connected 状态。如果 xrandr 里都没有,说明 xorg.conf 配置失败。

Q3: 虚拟显示器分辨率不对/无法调整

  • 原因: EDID 文件限制了分辨率。
  • 解法: 使用 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
# 卸载 sunshine(保留配置文件)
sudo dpkg -r sunshine
# 卸载并删除所有配置文件
sudo dpkg -P sunshine
# 重启电脑
sudo reboot

目录

  1. 前言
  2. 方案原理
  3. 核心思路
  4. 为什么选择 Sunshine + Moonlight?
  5. 环境与硬件要求
  6. 详细配置步骤
  7. 第一步:安装 Sunshine 和 Moonlight
  8. 第二步:攻克双显卡难关 —— 配置 Xorg
  9. 复制现有显示器的 EDID 到系统目录
  10. 注意:路径中的 card1-HDMI-A-1 需根据你的实际情况调整,可能是 card0 或 card2
  11. 第三步:验证虚拟显示器
  12. 第四步:配置 Sunshine 锁定虚拟屏
  13. 刚才查到的 ID
  14. 强制使用 X11 捕获模式,对虚拟显示器兼容性更好
  15. 如果不需要平板发声,可以留空或配置 sink
  16. audio_sink =
  17. 第五步:调整屏幕布局 (xrandr)
  18. 假设每个屏幕宽 2560
  19. 连接与使用
  20. 常见问题排查 (Troubleshooting)
  21. 删除配置
  22. 删除 sunshine 配置
  23. 删除 xorg.conf 和 EDID 文件
  24. 停止 sunshine
  25. 重启电脑
  26. 卸载 sunshine(保留配置文件)
  27. 卸载并删除所有配置文件
  28. 重启电脑
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于大疆 SRT 数据的高精度 AR 视频投射实现方案
  • Python 100 个常用函数全面解析
  • 无人机视觉语言导航概述:概念、定义与应用场景
  • AI 绘画提示词引导系数设置指南:从原理到实践
  • 无人机避障:Mid360+Fast-lio 感知建图与 Ego-planner 运动规划
  • ClawPanel v4.4.0 发布:AI 智能助手与模型兼容性修复
  • Linux 系统编程:构建基础文件操作库与理解标准错误流 stderr
  • 前端文件上传优化方案:分片与断点续传实现
  • HTTP 请求方式详解:GET、POST 与其他方法
  • SQL 查询:组合两个表
  • ClawdBot Web 控制台模型切换实操:Config→Models→Providers
  • AI 大模型通信机制:深入理解流式传输与数据封装逻辑
  • Spring Cloud Gateway 网关核心原理与使用指南
  • 谷歌 TurboQuant 内存压缩与 RWKV-6 开源重构大模型部署范式
  • Obsidian Copilot API 密钥配置指南:OpenRouter、Gemini、OpenAI
  • Python 自学指南:从入门到实战的完整学习路线规划
  • TRAE 与 VSCode 中的 Git 项目管理实战
  • Caddy:现代 Web 服务器,默认开启 HTTPS
  • GitHub Copilot 中配置并使用 MCP 服务指南
  • 汽车雷达多径幽灵目标检测:GLRT 与稀疏压缩感知解析

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online