WebScreen 高光录制部署、使用与测试手册
1. 范围
本文用于同事在新 Linux 服务器部署 WebScreen,并只对 xdyui2 验证高光 MP4 录制。
当前规则:
- 一个高光时间段生成一个 MP4。
- 一个课堂有 N 条高光,生成 N 个 MP4。
- 全量模式录制 xdyui2 前一天全部高光。
- 任务模式只处理
status=0 && onlyHighlight=1。 - WebScreen 只生成本地文件,服务器原任务负责搬运到 OSS。
- 暂不启用 CrazyTalk。
不要直接覆盖现有正式录制服务器。
2. 交付物和外部依赖
项目包:
webScreen-full-latest.zip
包内含源码、Git 历史、.env、node_modules、文档和测试。node_modules 来自 macOS,Linux 必须重新安装。
项目不包含 web_capture_c。需从现有录制服务器复制完整运行目录:
/root/web_capture_release
/root/web_capture_release/linux-x64/web_capture_c
同时复制其动态库、字体、浏览器运行环境和显示服务配置。
3. 部署前检查
date
timedatectl
node -v
npm -v
ss -lntp | grep ':3001'
df -h /root
test -x /root/web_capture_release/linux-x64/web_capture_c && echo CAPTURE_OK
要求:
- 时区为
Asia/Shanghai,NTP 已同步。 - Node.js 与现有正式服务器一致。
- 端口
3001未被占用。 - 录制程序可执行,磁盘空间充足。
4. 解压和安装
cd /root
unzip webScreen-full-latest.zip
cd /root/webScreen
mv node_modules node_modules.macos.bak
npm install
npm test
预期测试输出:
highlightRecordingService tests passed
highlight routes tests passed
5. 环境变量
.env 需要包含:
ALIBABA_CLOUD_ACCESS_KEY_ID=...
ALIBABA_CLOUD_ACCESS_KEY_SECRET=...
只检查是否存在:
grep -q '^ALIBABA_CLOUD_ACCESS_KEY_ID=' .env && echo ACCESS_KEY_ID_OK
grep -q '^ALIBABA_CLOUD_ACCESS_KEY_SECRET=' .env && echo ACCESS_KEY_SECRET_OK
这两个变量只用于查询 OSS 状态;WebScreen 不主动上传文件。
6. 配置
编辑 /root/webScreen/config/config.json。保留服务器原有:
GETCLASSURLGETCLASSURLPARAMETERPROJECTWINCATALOGPROJECTCATALOGBACKMEDIACONFIGclassLastNumber
目录应与服务器一致:
"PROJECTWINCATALOG": "/root/web_capture_release/linux-x64",
"PROJECTCATALOG": "/root/web_capture_release"
BACKMEDIACONFIG.url 必须指向已支持 recBeginTime/recEndTime 的 PCLive 测试版本。保留验证服务器已确认可用的 devback 或测试路径,不在代码中硬编码。
高光配置:
"HIGHLIGHTCONFIG": {
"enabled": false,
"sourceMode": "site",
"siteIds": ["xdyui2"],
"apiBaseUrl": "https://saas.xuedianyun.com",
"pageSize": 100,
"taskPageSize": 100,
"maxPages": 1000,
"maxConcurrent": 2,
"maxDurationMs": 21600000,
"apiTimeoutMs": 10000,
"apiRetryCount": 2,
"apiRetryBaseDelayMs": 500,
"loadGraceMs": 60000,
"endGraceMs": 10000,
"taskRetentionMs": 86400000,
"outputNamespace": "",
"outputBaseUrl": "https://xdymp4.xuedianyun.com"
}
首次启动保持 enabled=false。验证 JSON:
node -e "JSON.parse(require('fs').readFileSync('config/config.json')); console.log('config ok')"
7. 启动服务
测试期间先不要配置 cron。
npm run pm2
pm2 show webScreen
curl http://127.0.0.1:3001/highlight/status
若 PM2 已有同名进程:
pm2 restart webScreen
状态接口预期:
{
"code": 0,
"message": "success",
"data": {
"queued": 0,
"recording": 0,
"knownTasks": 0
}
}
查看日志:
pm2 logs webScreen --lines 100
8. 开启 xdyui2
基础服务正常后修改:
"enabled": true,
"sourceMode": "site",
"siteIds": ["xdyui2"]
pm2 restart webScreen
9. 准备测试课堂
选择一个 xdyui2 已结束课堂:
- 至少两条高光。
- 回放正常。
- 最好含教师、学生音视频、屏幕共享和声音。
记录:
siteId:xdyui2
classId:__________
高光数量:__________
课堂日期:__________
10. 只读预览
预览不会启动录制程序:
curl -X POST http://127.0.0.1:3001/highlight/preview/by-class \
-H 'Content-Type: application/json' \
-d '{"classId":"替换为课堂号"}'
逐条检查:
-
siteId是xdyui2。 -
highlightId不重复。 -
classId正确。 -
beginTime/endTime是 13 位毫秒时间戳。 -
duration = endTime - beginTime。 -
playbackUrl含正确的recBeginTime/recEndTime。 - 文件名为
{classId}_highlight_{highlightId}.mp4。 - 路径位于
/root/web_capture_release/media/xdyui2/{yyyyMMdd}/。
返回“无高光数据”时,先让后端确认高光表确实存在记录。
11. 单课堂录制
curl -X POST http://127.0.0.1:3001/highlight/recording/by-class \
-H 'Content-Type: application/json' \
-d '{"classId":"替换为课堂号"}'
新任务初始状态应为 queued;已有文件可能返回 uploading 或 generated。
观察队列和进程:
watch -n 2 'curl -s http://127.0.0.1:3001/highlight/status'
tail -f /root/webScreen/log/$(date +%Y%m%d).txt
ps -ef | grep '[w]eb_capture_c'
响应返回后不能立即停止 PM2;录制在后台队列继续执行。
12. 本地文件验证
find /root/web_capture_release/media/xdyui2 -type f -name '课堂号_highlight_*.mp4' -ls
要求:
- N 条高光生成 N 个文件。
- 文件名中的
highlightId不同。 - 文件大小大于 0。
- 不覆盖旧
{classId}.mp4。 - 日期目录包含
download.json。 -
.highlight_tmp无本次任务残留。
如有 ffprobe:
ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 /完整/文件路径.mp4
人工播放检查:
- 开始位置接近
beginTime。 - 结束位置接近
endTime。 - 教师、学生、屏幕共享画面正常。
- 声音正常。
- 文件不是整堂课堂。
13. 重复录制验证
再次调用同一课堂的 /highlight/recording/by-class。
要求:
- 不再启动新的
web_capture_c。 - 文件数量不增加。
- 原文件不被覆盖。
- OSS 已有文件时也不重复录制。
14. OSS 搬运和多地址查询
等待服务器原搬运任务执行。预期 OSS Key:
oss/xdyui2/{yyyyMMdd}/{classId}_highlight_{highlightId}.mp4
查询:
curl -X POST http://127.0.0.1:3001/highlight/fileExists \
-H 'Content-Type: application/json' \
-d '{"siteId":"xdyui2","classId":"替换为课堂号"}'
OSS 尚不可见时:
status = uploading
generated = false
OSS 可见后:
status = generated
generated = true
url = https://xdymp4.xuedianyun.com/oss/...
N 条高光时,classUrlList 必须有 N 条记录。
15. 前一天全量验证
保持:
"sourceMode": "site",
"siteIds": ["xdyui2"]
手工调用 cron 入口:
curl -fsS -X POST http://127.0.0.1:3001/highlight/recording/scheduled
检查:
-
code为"0"。 -
data.mode为site。 -
beginTime/endTime是 Asia/Shanghai 前一天。 - 只查询 xdyui2。
- 前一天每条有效高光都进入队列。
16. 任务模式验证
全量模式通过后改为:
"sourceMode": "task"
pm2 restart webScreen
请后端创建四组任务:
-
status=0, onlyHighlight=1, siteId=xdyui2:应录制。 -
status!=0, onlyHighlight=1:不录制。 -
status=0, onlyHighlight=0:不进入高光录制。 - 其他站点
status=0, onlyHighlight=1:不录制。
curl -fsS -X POST http://127.0.0.1:3001/highlight/recording/scheduled
检查:
-
data.mode为task。 -
pendingTasks只统计第一类任务。 - 使用
taskList.meetingNumber查询课堂高光。
后端尚未确认任务状态回写接口。当前依靠内存队列、本地文件和 OSS 文件避免重复录制。
17. 启用每日 cron
只有单课堂、重复录制、OSS 搬运和全量模式全部通过后才启用:
57 7 * * * curl -fsS -X POST http://127.0.0.1:3001/highlight/recording/scheduled >/dev/null 2>&1
crontab -l
任务每天 07:57 执行。任务模式中新任务最多等待约 24 小时,业务已确认可接受。
18. 日常使用
pm2 show webScreen
curl http://127.0.0.1:3001/highlight/status
pm2 logs webScreen --lines 200
tail -n 200 /root/webScreen/log/$(date +%Y%m%d).txt
手工补录:
curl -X POST http://127.0.0.1:3001/highlight/recording/by-class \
-H 'Content-Type: application/json' \
-d '{"classId":"课堂号"}'
查询地址:
curl -X POST http://127.0.0.1:3001/highlight/fileExists \
-H 'Content-Type: application/json' \
-d '{"siteId":"xdyui2","classId":"课堂号"}'
19. 故障排查
高光录制功能未启用
检查 HIGHLIGHTCONFIG.enabled=true,修改后执行 pm2 restart webScreen。
SaaS 接口 code=4
检查服务器时间、NTP、apiBaseUrl 和最新代码。签名时间戳必须是 13 位毫秒。
无高光数据
检查高光表记录、meetingNumber、siteId=xdyui2,以及全量模式时间窗是否为前一天。
web_capture_c 启动失败
ls -l /root/web_capture_release/linux-x64/web_capture_c
ldd /root/web_capture_release/linux-x64/web_capture_c
echo "$DISPLAY"
比较正式服务器的显示服务、字体、浏览器依赖和 PM2 环境变量。
一直是 uploading
检查搬运任务是否运行,是否支持 {classId}_highlight_{highlightId}.mp4、download.json 和 oss/xdyui2/{yyyyMMdd}/。
OSS文件状态查询失败
检查 .env、AccessKey 权限、OSS 网络和 bucket xdymp4。OSS 查询异常不会被当作“文件不存在”。
视频时间错误
确认 playbackUrl 的 recBeginTime/recEndTime 与接口原值完全一致。不能传 duration,不能换算相对秒数。
20. 回滚
优先使用配置回滚:
"HIGHLIGHTCONFIG": {
"enabled": false
}
pm2 restart webScreen
关闭后,高光查询、录制和文件检查接口停止处理,状态接口仍可访问;GET /recording 始终执行原整堂录制逻辑。POST /recording、POST /recordingTask、POST /fileExists 和实时录制接口不变。
21. 测试记录模板
测试服务器:
测试日期:
测试人员:
Git 提交(执行 git rev-parse --short HEAD):
站点:xdyui2
课堂号:
高光记录数:
本地 MP4 数量:
OSS MP4 数量:
预览接口:通过 / 失败
单课堂录制:通过 / 失败
时间范围:通过 / 失败
音频:通过 / 失败
教师视频:通过 / 失败
学生视频:通过 / 失败
屏幕共享:通过 / 失败
重复录制:通过 / 失败
OSS 搬运:通过 / 失败
多地址查询:通过 / 失败
前一天全量:通过 / 失败
任务模式:通过 / 失败 / 未测试
问题记录:
结论:可继续验证 / 需要修复