UxPlay投屏录制调试4
UxPlay 录屏与播放方案笔记
一、UxPlay 录屏音画不同步问题
问题本质
UxPlay 录制文件音画不同步,根源在录制管线本身,不在播放器。
- AirPlay 镜像模式下,音频和视频独立传输,iOS 客户端会主动为音频流引入缓冲延迟。
- UxPlay 的
-vsync是播放同步选项,通过丢弃视频帧来保持实时同步,并非录制修正选项。 -vsync no关闭时间戳同步,录制流畅但音画对齐完全放弃,客户端初始延迟被原样固化进文件。- 十几秒的延迟属于 iOS 客户端自身引入的音频缓冲,远超
-vsync参数可补偿范围,录制时无法修复。
与系统时间的关系
UxPlay 同步依赖客户端(iPhone)通过 NTP 同步过来的时钟和音视频包时间戳,与服务器系统时间无关。
本地播放器正常、网页播放器不同步的原因
- PotPlayer、VLC 解码器容错能力强,能自动修正不规则时间戳。
- nowen-video 走 HLS 转码链路,对时间戳规范性要求严格,会强行插入静音帧或调整时间基准,反而破坏音画平衡。
二、落地方案
方案一:录制后 FFmpeg 修正音频延迟
确定延迟秒数后,用 itsoffset 将音频整体后移:
ffmpeg -i 原始录制.mp4 -itsoffset 12 -i 原始录制.mp4 -map 0:v -map 1:a -c copy 修正后.mp4延迟量固定时可批量处理:
for f in *.mp4; do
ffmpeg -i "$f" -itsoffset 12 -i "$f" -map 0:v -map 1:a -c copy "fixed_$f"
done方案二:去掉音频,只保留视频
ffmpeg -i "输入文件.mp4" -c:v copy -an "输出文件.mp4"音频损坏导致报错时:
ffmpeg -err_detect ignore_err -i "输入文件.mp4" -c:v copy -an "输出文件.mp4"视频流也有时间戳问题时:
ffmpeg -err_detect ignore_err -i "输入文件.mp4" -c:v libx264 -preset fast -crf 23 -an -movflags +faststart "输出文件.mp4"批量处理:
mkdir -p fixed
for f in *.mp4; do
ffmpeg -err_detect ignore_err -i "$f" -c:v copy -an "fixed/$f"
done方案三:规范化时间戳,适配 HLS 播放
ffmpeg -i "原始录制.mp4" -af aresample=async=1000 -c:v copy "修复后.mp4"-c:v copy:视频流不重新编码,画质无损。-af aresample=async=1000:重新采样音频,使音频样本时间戳与视频帧严格对齐,消除音频间隙。
三、替代方案评估
AirPlay 接收器替代品
| 项目 | 说明 |
|---|---|
| RPiPlay | 面向树莓派,已停止更新两年 |
| shairport-sync | 仅音频,不支持视频镜像 |
| goplay2 | 仅音频,更新停滞 |
| java-airplay-server | Java 实现,功能有限 |
| airplayreceiver | C# 实现,主要用于测试 |
结论:不存在能在录制时自动解决音画不同步的开源 AirPlay 接收器,UxPlay 已是该领域最活跃项目。
浏览器录屏方案(绕开 AirPlay 录制管线)
- SendRec:开源 Loom 替代品,浏览器内
getDisplayMedia录屏,优先输出 MP4,天然适配网页播放。 - OpenLoom:自托管浏览器录屏扩展,录制后上传自有存储。
- Direct Studio:支持导出 MP4 和 HLS 格式。
适用场景:仅需录屏并在网页回看,可放弃 AirPlay 路线。
四、nowen-video 部署要点
Podman Compose 配置
version: '3.8'
services:
nowen-video:
image: docker.io/cropflre/nowen-video:latest
container_name: nowen-video
restart: unless-stopped
ports:
- "8080:8080"
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai
- NOWEN_SECRETS_JWT_SECRET=可选手动指定,不设置则首次启动自动生成
- NOWEN_LOGGING_LEVEL=info
volumes:
- ./data:/data
- ./cache:/cache
- /path/to/your/media:/media:ro
devices:
- /dev/dri:/dev/dri # 无核显则删除关键说明
- 镜像版本 1.3.4,内部端口 8080,数据目录
/data,缓存目录/cache。 - 默认管理员账号
admin,密码admin123,登录后立即修改。 NOWEN_SECRETS_JWT_SECRET不设置时自动生成并持久化到数据目录;手动生成用openssl rand -base64 32。- 媒体库路径必须填容器内路径
/media,不能填宿主机路径。 - 媒体目录建议单独建视频专用目录,避免混合非视频文件。
媒体库为空排查
- 进入容器确认文件可见:
podman exec -it nowen-video ls -lah /media - 检查添加媒体库时填写的路径是否为容器内路径。
- 检查 PUID/PGID 与宿主机文件所有者是否一致。
五、VLC 容器方案(用于正常播放录屏文件)
Podman Compose 配置
version: '3.8'
services:
vlc:
image: docker.io/jlesage/vlc:latest
container_name: vlc
restart: unless-stopped
ports:
- "5800:5800"
# - "5900:5900"
environment:
- TZ=Asia/Shanghai
- USER_ID=1000
- GROUP_ID=1000
- DISPLAY_WIDTH=1920
- DISPLAY_HEIGHT=1080
- WEB_AUDIO=1
- VNC_PASSWORD=
volumes:
- ./config:/config
- /path/to/your/media:/storage
devices:
- /dev/dri:/dev/dri # 无核显则删除关键说明
- Web 界面端口 5800,VNC 端口 5900。
WEB_AUDIO=1必须开启,否则浏览器无声音。- 媒体目录挂载到
/storage,在 Web 界面中从该目录选择文件。 - VLC 容器使用完整桌面版 VLC 解码器,对不规则时间戳容错能力强,播放 UxPlay 录制文件同步表现与本地 VLC 一致。
六、UXPlay 命令参考
当前使用命令:
command: >
sh -c "uxplay -mp4 /recordings/screen_$(date +%Y%m%d_%H%M%S).mp4 -p -vsync no"参数说明:
-mp4:录制为 MP4 文件。-p:保留音视频流。-vsync no:关闭时间戳同步,录制流畅但音画对齐放弃。-vd avdec_h264:强制软件解码,CPU 占用高,已不推荐。
结论:-vsync 系列参数无法补偿十几秒级别的客户端音频延迟,录制后 FFmpeg 修正仍是唯一可靠路径。