HIGHLIGHT_DEPLOYMENT_USAGE_TEST.md 10.8 KB

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。保留服务器原有:

  • GETCLASSURL
  • GETCLASSURLPARAMETER
  • PROJECTWINCATALOG
  • PROJECTCATALOG
  • BACKMEDIACONFIG
  • classLastNumber

目录应与服务器一致:

"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

请后端创建四组任务:

  1. status=0, onlyHighlight=1, siteId=xdyui2:应录制。
  2. status!=0, onlyHighlight=1:不录制。
  3. status=0, onlyHighlight=0:不进入高光录制。
  4. 其他站点 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 搬运:通过 / 失败
多地址查询:通过 / 失败
前一天全量:通过 / 失败
任务模式:通过 / 失败 / 未测试
问题记录:
结论:可继续验证 / 需要修复