在 AGX Orin 上用 chiaki-ng 和双账号实现 headless PS5 录制
记录从同一局域网配置、macOS 注册信息迁移、AGX Orin 编译 chiaki-ng,到实现并验证 headless ps5-recorder 的完整过程。
在 AGX Orin 上用 chiaki-ng 和双账号实现 headless PS5 录制
这篇记录一个比较具体的折腾过程:先在 Mac 上用 chiaki-ng 完成 PS5 注册,再把配置迁移到 AGX Orin,编译出命令行版 chiaki-ng,最后用 libchiaki 写一个没有桌面界面的 ps5-recorder,把 PS5 的画面录成 Jellyfin 可以直接扫描的 Matroska 视频。
网络部分只讨论一个局域网段。示例拓扑如下:
| 设备 | 示例地址 |
|---|---|
| PS5 | 192.168.1.20 |
| AGX Orin | 192.168.1.30 |
| 局域网 | 192.168.1.0/24 |
这里的重点不是把 PS5 暴露到公网,而是让 Orin 和 PS5 在同一个局域网段内完成发现、连接和录制。
1. 最终链路
最后得到的链路是:
Mac chiaki-ng 注册
│ 导出 QSettings INI
▼
AGX Orin ~/Downloads/chiaki-ng-*.ini
│
├── chiaki-cli:discover / wakeup 验证主机
│
└── ps5-recorder:读取注册凭据
│
▼
libchiaki Remote Play session
│
H.264 视频 + Opus 音频
│
▼
FFmpeg 最终封装为 MKV
│
▼
Jellyfin 媒体目录
这里有一个容易混淆的地方:chiaki-cli 能证明主机发现和唤醒链路正常,但它本身不是一个完整的无界面录制器。录制需要建立 session、接收视频和音频回调,再把数据交给文件写入器和 FFmpeg,所以最终单独实现了 ps5-recorder。
2. 双账号应该怎样处理
双账号最重要的原则是:两个账号是两套独立的注册配置,不是把两套密钥合并进一个 INI 文件。
可以把两个账号叫作 Account A 和 Account B:
- 在 Mac 的 chiaki-ng 中登录 Account A,完成 PS5 注册并导出配置。
- 切换到 Account B,完成同样的注册流程,导出另一份配置。
- 分别命名为
chiaki-ng-account-a.ini和chiaki-ng-account-b.ini。 - 使用哪个账号录制,就通过
--config选择对应文件。
配置里可能包含 psn_account_id、rp_regist_key、rp_key 以及 token 等敏感字段。它们不能提交到 Git、发到聊天窗口,也不应该放进公开仓库。两个配置文件的权限都应限制为当前用户可读写:
chmod 600 ~/Downloads/chiaki-ng-account-a.ini
chmod 600 ~/Downloads/chiaki-ng-account-b.ini
一次运行只使用一个配置。这样做既避免误用账号凭据,也让输出目录可以按账号分开:
MEDIA_ROOT="$(readlink -f "$HOME/Downloads/torrents")"
mkdir -p "$MEDIA_ROOT/ps5-recorder/account-a"
PS5_RECORDER_OUTPUT_DIR="$MEDIA_ROOT/ps5-recorder/account-a" \
~/ps5-recorder/run.sh \
--config "$HOME/Downloads/chiaki-ng-account-a.ini"
切换到 Account B 时,只替换配置文件和输出目录:
mkdir -p "$MEDIA_ROOT/ps5-recorder/account-b"
PS5_RECORDER_OUTPUT_DIR="$MEDIA_ROOT/ps5-recorder/account-b" \
~/ps5-recorder/run.sh \
--config "$HOME/Downloads/chiaki-ng-account-b.ini"
这不是让两个账号在同一个录制进程里同时登录,而是让同一套 recorder 程序安全地选择不同账号。是否能在同一台 PS5 上切换不同用户、是否需要重新注册,仍然取决于 PS5 用户和 Remote Play 的实际状态;不要用一套账号的注册密钥去替换另一套配置里的字段。
3. 在 Mac 上注册并迁移配置
Mac 端的 chiaki-ng 适合完成需要交互的登录和注册流程。注册成功后,从设置中导出配置文件,再复制到 Orin:
scp ~/Downloads/chiaki-ng-account-a.ini \
wooley@192.168.1.30:~/Downloads/
如果只使用一个账号,文件名也可以保持为:
~/Downloads/chiaki-ng-PS5.ini
在 Orin 上不要直接把整个 INI 打印出来。先确认文件类型、权限和大小:
file ~/Downloads/chiaki-ng-PS5.ini
stat ~/Downloads/chiaki-ng-PS5.ini
chmod 600 ~/Downloads/chiaki-ng-PS5.ini
这个导出的文件是 Qt QSettings 风格的 ASCII INI。它包含 registered_hosts、manual_hosts 等区段,主机地址和昵称可以被程序读取;二进制注册字段会以 @ByteArray(...) 形式保存,其中还可能有转义字节。不能只按普通字符串读取,需要按 QSettings 的编码规则解码。
4. 在 AGX Orin 上编译 chiaki-ng CLI
Orin 使用 aarch64 Linux,目标是保留 core 和 CLI,关闭桌面 GUI。这样可以减少 Qt 窗口系统的依赖,也方便把设备放在电视柜或机架里长期运行。
源码目录和构建目录分开:
cd ~/chiaki-ng
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCHIAKI_ENABLE_CLI=ON \
-DCHIAKI_ENABLE_GUI=OFF
cmake --build build -j"$(nproc)"
编译完成后,CLI 通常位于:
~/chiaki-ng/build/cli/chiaki-cli
先用 discovery 检查局域网连接:
~/chiaki-ng/build/cli/chiaki-cli \
discover -h 192.168.1.20 -t 3
正常情况下可以看到 PS5 主机处于可用状态,并显示注册时设置的昵称。wakeup 也可以作为第二个验证点,但不要把唤醒凭据写进博客或命令历史;它应该只从本机受保护的配置中读取。
5. 给 recorder 准备非敏感环境变量
为了不把路径和主机信息重复写在每条命令里,可以创建一个只保存非敏感元数据的环境文件:
install -d -m 700 ~/.config/chiaki-ng
cat > ~/.config/chiaki-ng/ps5-recorder.env <<'EOF'
export CHIAKI_CONFIG_FILE="${HOME}/Downloads/chiaki-ng-PS5.ini"
export CHIAKI_CONFIG_FORMAT="qsettings-ini"
export CHIAKI_CLI="${HOME}/chiaki-ng/build/cli/chiaki-cli"
export CHIAKI_HOST_ADDR="192.168.1.20"
export CHIAKI_HOST_NAME="PS5"
export CHIAKI_TARGET="ps5"
EOF
chmod 600 ~/.config/chiaki-ng/ps5-recorder.env
实际文件中不要额外写入 PSN token、注册密钥或明文密码。run.sh 会自动加载这个环境文件,命令行的 --config 可以临时覆盖默认账号,正好适合双账号切换。
6. headless ps5-recorder 的实现
recorder 单独放在 ~/ps5-recorder,不直接改动 chiaki-ng 源码:
ps5-recorder/
├── CMakeLists.txt
├── main.cpp
├── run.sh
├── README.md
├── build/
└── recordings/
实现分成四层。
6.1 读取 QSettings 配置
程序读取导出的 INI,定位注册主机,并解析 @ByteArray(...) 中的十六进制和反斜杠转义。随后只做结构校验:
- 目标必须是 PS5;
- 主机地址必须存在;
- 注册字段必须解码成功;
rp_regist_key和rp_key的长度应符合 16 字节注册密钥的预期。
校验命令只输出主机、昵称、目标类型和字节数,不输出密钥内容:
~/ps5-recorder/run.sh --check-config
实际验证时可以看到类似结果:
config_ok=1
host=192.168.1.20
nickname=PS5
target=1000100
ps5=1
regist_key_bytes=16
morning_bytes=16
6.2 建立本地 Remote Play session
recorder 将解析出来的主机地址、目标类型和注册凭据转换为 ChiakiConnectInfo,请求指定的视频分辨率和帧率,然后建立本地局域网 session。
默认请求 1080p/60,也可以降低为 720p/30 来减少带宽和磁盘压力:
~/ps5-recorder/run.sh --resolution 720 --fps 30
视频回调收到 H.264 数据,音频回调收到 Opus 数据。程序不会把 PSN token 打到日志里,连接失败时只报告阶段和错误信息。
6.3 临时文件和最终封装
录制期间先写入临时的 H.264 和 PCM 文件,结束时调用系统 FFmpeg:
- 视频直接复制,避免再次编码损失画质;
- Opus 音频转成 AAC;
- 最终封装为 MKV;
- 成功后删除
.part.h264和.part.pcm; - 输出文件权限设置为
0600。
这样做比边收包边依赖复杂的实时 muxer 更容易排查问题,也能在 Ctrl-C 时执行一次正常的 finalize。--raw 可以保留原始 H.264,通常只建议在调试时使用。
6.4 退出和录制时长
指定 --duration 时,达到秒数后自动结束:
PS5_RECORDER_OUTPUT_DIR="$HOME/Downloads/ps5-recorder" \
~/ps5-recorder/run.sh --duration 60
这表示录制 60 秒。省略 --duration 就是持续录制,直到主动按 Ctrl-C:
PS5_RECORDER_OUTPUT_DIR="$HOME/Downloads/ps5-recorder" \
~/ps5-recorder/run.sh
默认文件会写到 ~/ps5-recorder/recordings/,文件名带有时间戳。连接建立本身需要一点时间,因此最终媒体时长可能比参数略短,这是启动握手发生在计时窗口内造成的。
7. 验证结果
先跑一次短测试,避免直接开启长时间录制:
~/ps5-recorder/run.sh --duration 10 \
--output ~/ps5-recorder/recordings/smoke-test.mkv
再用 FFprobe 检查容器和轨道:
ffprobe -hide_banner \
~/ps5-recorder/recordings/smoke-test.mkv
实际测试得到的文件包含:
- H.264 视频,1920×1080;
- AAC 音频,48 kHz、双声道;
- Matroska 容器;
Ctrl-C结束后仍能正常播放;- 正常结束后没有残留
.part.*文件。
这说明从配置解析、局域网 session、视频/音频回调到最终封装的链路已经闭合。原始 chiaki-ng 工作树保持干净,recorder 是独立的小项目,后续升级 chiaki-ng 时可以分别验证。
8. 让 Jellyfin 扫描到录制文件
之前直接在 Downloads 下再套一层软链接时,Jellyfin 可能因为容器挂载路径、扫描策略或权限,看不到最终文件。更稳妥的方式是解析 ~/Downloads/torrents 的真实目标,把 recorder 直接写进真实的媒体目录:
MEDIA_ROOT="$(readlink -f "$HOME/Downloads/torrents")"
mkdir -p "$MEDIA_ROOT/ps5-recorder"
PS5_RECORDER_OUTPUT_DIR="$MEDIA_ROOT/ps5-recorder" \
~/ps5-recorder/run.sh
这里的关键是 readlink -f:如果 Downloads/torrents 本身已经指向 media,程序就直接使用 media/ps5-recorder,不再创建“软链接里面再套软链接”的路径。
如果 Jellyfin 运行在 Docker 中,还要确认这个真实目录已经映射进容器,并且容器用户对它有读取权限。Jellyfin 看到的路径必须是容器内的挂载路径,而不是 Orin 宿主机上的路径字符串。
双账号也可以沿用这个目录结构:
media/
└── ps5-recorder/
├── account-a/
└── account-b/
这样两个账号的录制文件不会混在一起,Jellyfin 也可以按目录组织媒体。
9. 这套方案的边界
这套实现适合一个局域网内的长期录制节点,但仍有几个边界:
chiaki-cli不是 recorder,不能只靠 CLI 命令完成视频采集;- 配置文件是账号和主机的敏感凭据,必须保存在受保护的本机路径;
- 双账号要保持两份完整配置,不能手工拼接字段;
- 一个 recorder 进程一次只使用一个账号配置;
- PS5 休眠、用户切换或系统更新后,可能需要重新确认 Remote Play 注册状态;
- 录制程序目前以本地网络和 FFmpeg 为前提,不负责公网穿透或跨网段连接。
对我来说,这次最有价值的结果不是又做了一个 GUI,而是把一次性的桌面注册流程拆成了三个可验证的阶段:先用 chiaki-ng 注册,再用 chiaki-cli 验证主机,最后由一个很小的 headless recorder 完成持续录制。以后换账号、换输出目录或接入 Jellyfin,都只需要替换明确的配置和路径,不必重新改动核心代码。
Conversation
正在读取留言…