OPTY

无线便携显示器

记录


 

无线便携显示器实现方案 (Windows → Ubuntu)*

本方案通过 FFmpeg 将 Windows 屏幕(经由 OBS 虚拟摄像头)通过 UDP 协议推送到 Ubuntu Server 的帧缓冲设备 (/dev/fb0),实现极低开销的无线投屏。

一、 环境准备

1. 被投屏端 (Ubuntu Server)

  • 系统要求:已安装 Ubuntu Server(无需 GUI 环境)。

  • 核心依赖:安装 ffmpegavahi-daemon(用于主机名解析)。

    sudo apt update && sudo apt install ffmpeg avahi-daemon -y

2. 主控端 (Windows)

  • OBS Studio:用于采集屏幕并开启“虚拟摄像头”。

  • FFmpeg:需下载并将 bin 目录添加到系统环境变量 Path 中。


二、 服务端配置 (Ubuntu)

1. 创建接收脚本

创建文件 /usr/local/bin/fbstream.sh,此脚本负责优化内核缓存并启动接收。

#!/bin/bash
FFMPEG_BIN=$(which ffmpeg)

if [ -z "$FFMPEG_BIN" ]; then
    FFMPEG_BIN="/usr/bin/ffmpeg"
fi

$FFMPEG_BIN \
    -fflags nobuffer \
    -flags low_delay \
    -thread_queue_size 2096 \
    -v quiet -stats \
    -buffer_size 1M \
    -i "udp://0.0.0.0:1234?listen=1&fifo_size=100000&overrun_nonfatal=1" \
    -vf "format=bgra" \
    -f fbdev /dev/fb0

赋予权限sudo chmod +x /usr/local/bin/fbstream.sh

2. 设置开机自启动 (Systemd)

创建服务文件 /etc/systemd/system/fbstream.service

[Unit]
Description=FFmpeg Framebuffer Receiver Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
ExecStart=/bin/bash /usr/local/bin/fbstream.sh
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

启用服务

sudo systemctl daemon-reload
sudo systemctl enable fbstream.service
sudo systemctl start fbstream.service

三、 发送端配置 (Windows)

1. OBS 设置

  1. 在 OBS 中添加“显示器采集”源。

  2. 点击 “启动虚拟摄像头” (Start Virtual Camera)

2. 创建推送脚本

创建 Screenmirroring.bat。该脚本会自动解析 .local 主机名,解决 IP 变动问题。

@echo off
setlocal enabledelayedexpansion

set HOSTNAME=surface.local
set PORT=1234

echo [INFO] 正在解析 %HOSTNAME% 的 IP 地址...

:: 核心逻辑:解析 mDNS 并提取 IP
set LINUX_IP=
for /f "tokens=2 delims=[]" %%i in ('ping -4 -n 1 %HOSTNAME% ^| findstr "["') do (
    set LINUX_IP=%%i
)

:: 检查是否成功获取 IP
if "%LINUX_IP%"=="" (
    echo [ERROR] 无法解析 %HOSTNAME%,请检查网络或确认目标设备开启了 mDNS 服务。
    pause
    exit /b
)

echo [INFO] 成功获取 IP: %LINUX_IP%
echo [INFO] 正在推送到 %LINUX_IP%:%PORT%

ffmpeg -f dshow -rtbufsize 200M -i video="OBS Virtual Camera" ^
 -r 60 ^
 -vcodec libx264 -preset ultrafast -tune zerolatency ^
 -x264-params "keyint=60:min-keyint=60:scenecut=0" ^
 -b:v  25M -maxrate 30M -bufsize 1M ^
 -pix_fmt yuv420p ^
 -f mpegts "udp://%LINUX_IP%:%PORT%?pkt_size=1316&buffer_size=33554432&fifo_size=100000"

pause

四、 核心参数说明

参数 作用
-fflags nobuffer 禁用流媒体输入/输出缓冲区。
fbdev /dev/fb0 直接将像素数据写入 Linux 帧缓冲,跳过 X11/Wayland 图形栈,开销极低。
surface.local 利用 mDNS 协议通信,只要在同一局域网,无需手动修改 IP。

五、 故障排查与验证

  1. 黑屏问题:检查 Ubuntu 端是否关闭了控制台光标闪烁,或者是否有其他 TTY 占用屏幕(可尝试 sudo systemctl stop getty@tty1.service)。

  2. 花屏/撕裂:通常是带宽不足,尝试将 .bat 脚本中的 BITRATE 降至 15M10M

  3. 服务检查:在 Ubuntu 使用 journalctl -u fbstream.service -f 查看实时报错日志。