功能:完善2K串流、显示恢复与输入优化

This commit is contained in:
songyiming committed 2026-11-03 13:43:50 +08:00
1 parent e47b01beec
commit 938ec97cce
95 files changed
+5788 -72

No files matched your search

+54 -7
View File
@@ -3,7 +3,7 @@
#
# 职责:
# 1. 读取本地配置(主机、应用、分辨率、帧率、码率、编解码)
# 2. 以软件解码拉起 moonlight-qt,全屏串流云桌面
# 2. 按配置拉起 Moonlight,全屏串流云桌面
# 3. 写心跳文件,供 vdi-kiosk-monitor 判断是否假死
# 4. 检测串流假死(CPU 与网络均无流量)并杀掉重连
#
@@ -12,7 +12,8 @@
#
# 说明:RK3528 当前没有可用的 V4L2 request/m2m 硬解设备,moonlight-qt 的
# --video-decoder auto 会选到 h264_v4l2m2m 并报 "Could not find a valid device",
# 因此配置里显式指定 decoder=software。接入 MPP/VPU 硬解后再改回 auto。
# 因此系统客户端默认 decoder=software;验证后的独立 RKMPP 客户端
# 通过 VDI_MOONLIGHT_PROGRAM 与 decoder=hardware 显式启用。
set -u
@@ -38,9 +39,10 @@ DECODER="software"
DISPLAY_MODE="fullscreen"
AUDIO=1
ABSOLUTE_MOUSE=1
VSYNC=0
FRAME_PACING=0
VSYNC=1
FRAME_PACING=1
PERFORMANCE_OVERLAY=0
PROFILE=""
RETRY=3
RETRY_DELAY=5
HANG_TIMEOUT=90
@@ -76,6 +78,7 @@ load_config() {
vsync) VSYNC="$value" ;;
frame-pacing) FRAME_PACING="$value" ;;
performance-overlay) PERFORMANCE_OVERLAY="$value" ;;
profile) PROFILE="$value" ;;
retry) RETRY="$value" ;;
retry-delay) RETRY_DELAY="$value" ;;
hang-timeout) HANG_TIMEOUT="$value" ;;
@@ -84,6 +87,33 @@ load_config() {
done < "$CONF"
}
apply_profile() {
case "$PROFILE" in
smooth)
VSYNC=1
FRAME_PACING=1
;;
low-latency)
VSYNC=0
FRAME_PACING=0
;;
diagnostic)
VSYNC=1
FRAME_PACING=1
PERFORMANCE_OVERLAY=1
;;
"")
# 兼容旧配置:没有profile时保留moonlight.conf中的显式开关。
;;
*)
log "未知串流 profile=$PROFILE,回退 smooth"
PROFILE=smooth
VSYNC=1
FRAME_PACING=1
;;
esac
}
# 默认路由出接口的累计收字节数,用于判断串流是否还有数据流入
rx_bytes() {
iface=$(awk '$2=="00000000" {print $1; exit}' /proc/net/route)
@@ -145,7 +175,7 @@ disable_screensaver() {
build_cmd() {
# moonlight-qt stream 只接受 <host> <app> 位置参数,没有 --port 选项,
# 服务端端口由 moonlight 自身按 GameStream 协议协商。
CMD="moonlight-qt stream $HOST $APP"
CMD="${VDI_MOONLIGHT_PROGRAM:-moonlight-qt} stream $HOST $APP"
CMD="$CMD --resolution ${WIDTH}x${HEIGHT}"
CMD="$CMD --fps $FPS"
CMD="$CMD --bitrate $BITRATE"
@@ -155,7 +185,7 @@ build_cmd() {
CMD="$CMD --keep-awake"
[ "$ABSOLUTE_MOUSE" = "1" ] && CMD="$CMD --absolute-mouse"
[ "$AUDIO" = "1" ] && CMD="$CMD --audio-on-host" || CMD="$CMD --no-audio-on-host"
# 低延迟开关:默认关闭 vsync 与 frame-pacing,削减帧队列/呈现延迟
# 按profile选择同步策略;默认保持当前稳定档。
[ "$VSYNC" = "1" ] && CMD="$CMD --vsync" || CMD="$CMD --no-vsync"
[ "$FRAME_PACING" = "1" ] && CMD="$CMD --frame-pacing" || CMD="$CMD --no-frame-pacing"
[ "$PERFORMANCE_OVERLAY" = "1" ] && CMD="$CMD --performance-overlay"
@@ -163,7 +193,7 @@ build_cmd() {
run_stream() {
build_cmd
log "启动串流: $CMD"
log "启动串流 profile=${PROFILE:-config} decoder=$DECODER codec=$CODEC vsync=$VSYNC frame-pacing=$FRAME_PACING renderer=${SDL_RENDER_DRIVER:-} video-driver=${SDL_VIDEODRIVER:-}: $CMD"
# shellcheck disable=SC2086
$CMD >> "$LOG_FILE" 2>&1 &
ML_PID=$!
@@ -220,6 +250,19 @@ stop)
esac
load_config
PROFILE="${VDI_STREAM_PROFILE:-$PROFILE}"
apply_profile
DECODER="${VDI_MOONLIGHT_DECODER:-$DECODER}"
CODEC="${VDI_MOONLIGHT_CODEC:-$CODEC}"
case "$DECODER" in
software|hardware|auto) ;;
*) log "未知解码器 $DECODER,回退 software"; DECODER=software ;;
esac
case "$CODEC" in
H.264|HEVC|AV1|auto) ;;
*) log "未知视频编码 $CODEC,回退 H.264"; CODEC=H.264 ;;
esac
PERFORMANCE_OVERLAY="${VDI_STREAM_STATS:-$PERFORMANCE_OVERLAY}"
if [ -z "$HOST" ]; then
log "配置缺失或缺少 host: $CONF"
exit 2
@@ -227,6 +270,10 @@ fi
export DISPLAY="${VDI_DISPLAY:-:0}"
export XAUTHORITY="${VDI_XAUTHORITY:-$HOME/.Xauthority}"
export SDL_RENDER_DRIVER="${VDI_SDL_RENDER_DRIVER:-opengles2}"
export SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR="${VDI_SDL_BYPASS_COMPOSITOR:-1}"
[ -n "${VDI_SDL_FORCE_EGL:-}" ] && export SDL_VIDEO_X11_FORCE_EGL="$VDI_SDL_FORCE_EGL"
[ -n "${VDI_SDL_VIDEODRIVER:-}" ] && export SDL_VIDEODRIVER="$VDI_SDL_VIDEODRIVER"
disable_screensaver
kill_stale