正在显示
1 个修改的文件
包含
496 行增加
和
0 行删除
HIGHLIGHT_DEPLOYMENT_USAGE_TEST.md
0 → 100644
| 1 | +# WebScreen 高光录制部署、使用与测试手册 | ||
| 2 | + | ||
| 3 | +## 1. 范围 | ||
| 4 | + | ||
| 5 | +本文用于同事在新 Linux 服务器部署 WebScreen,并只对 `xdyui2` 验证高光 MP4 录制。 | ||
| 6 | + | ||
| 7 | +当前规则: | ||
| 8 | + | ||
| 9 | +- 一个高光时间段生成一个 MP4。 | ||
| 10 | +- 一个课堂有 N 条高光,生成 N 个 MP4。 | ||
| 11 | +- 全量模式录制 xdyui2 前一天全部高光。 | ||
| 12 | +- 任务模式只处理 `status=0 && onlyHighlight=1`。 | ||
| 13 | +- WebScreen 只生成本地文件,服务器原任务负责搬运到 OSS。 | ||
| 14 | +- 暂不启用 CrazyTalk。 | ||
| 15 | + | ||
| 16 | +不要直接覆盖现有正式录制服务器。 | ||
| 17 | + | ||
| 18 | +## 2. 交付物和外部依赖 | ||
| 19 | + | ||
| 20 | +项目包: | ||
| 21 | + | ||
| 22 | +```text | ||
| 23 | +webScreen-full-latest.zip | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +包内含源码、Git 历史、`.env`、`node_modules`、文档和测试。`node_modules` 来自 macOS,Linux 必须重新安装。 | ||
| 27 | + | ||
| 28 | +项目不包含 `web_capture_c`。需从现有录制服务器复制完整运行目录: | ||
| 29 | + | ||
| 30 | +```text | ||
| 31 | +/root/web_capture_release | ||
| 32 | +/root/web_capture_release/linux-x64/web_capture_c | ||
| 33 | +``` | ||
| 34 | + | ||
| 35 | +同时复制其动态库、字体、浏览器运行环境和显示服务配置。 | ||
| 36 | + | ||
| 37 | +## 3. 部署前检查 | ||
| 38 | + | ||
| 39 | +```bash | ||
| 40 | +date | ||
| 41 | +timedatectl | ||
| 42 | +node -v | ||
| 43 | +npm -v | ||
| 44 | +ss -lntp | grep ':3001' | ||
| 45 | +df -h /root | ||
| 46 | +test -x /root/web_capture_release/linux-x64/web_capture_c && echo CAPTURE_OK | ||
| 47 | +``` | ||
| 48 | + | ||
| 49 | +要求: | ||
| 50 | + | ||
| 51 | +- 时区为 `Asia/Shanghai`,NTP 已同步。 | ||
| 52 | +- Node.js 与现有正式服务器一致。 | ||
| 53 | +- 端口 `3001` 未被占用。 | ||
| 54 | +- 录制程序可执行,磁盘空间充足。 | ||
| 55 | + | ||
| 56 | +## 4. 解压和安装 | ||
| 57 | + | ||
| 58 | +```bash | ||
| 59 | +cd /root | ||
| 60 | +unzip webScreen-full-latest.zip | ||
| 61 | +cd /root/webScreen | ||
| 62 | +mv node_modules node_modules.macos.bak | ||
| 63 | +npm install | ||
| 64 | +npm test | ||
| 65 | +``` | ||
| 66 | + | ||
| 67 | +预期测试输出: | ||
| 68 | + | ||
| 69 | +```text | ||
| 70 | +highlightRecordingService tests passed | ||
| 71 | +highlight routes tests passed | ||
| 72 | +``` | ||
| 73 | + | ||
| 74 | +## 5. 环境变量 | ||
| 75 | + | ||
| 76 | +`.env` 需要包含: | ||
| 77 | + | ||
| 78 | +```text | ||
| 79 | +ALIBABA_CLOUD_ACCESS_KEY_ID=... | ||
| 80 | +ALIBABA_CLOUD_ACCESS_KEY_SECRET=... | ||
| 81 | +``` | ||
| 82 | + | ||
| 83 | +只检查是否存在: | ||
| 84 | + | ||
| 85 | +```bash | ||
| 86 | +grep -q '^ALIBABA_CLOUD_ACCESS_KEY_ID=' .env && echo ACCESS_KEY_ID_OK | ||
| 87 | +grep -q '^ALIBABA_CLOUD_ACCESS_KEY_SECRET=' .env && echo ACCESS_KEY_SECRET_OK | ||
| 88 | +``` | ||
| 89 | + | ||
| 90 | +这两个变量只用于查询 OSS 状态;WebScreen 不主动上传文件。 | ||
| 91 | + | ||
| 92 | +## 6. 配置 | ||
| 93 | + | ||
| 94 | +编辑 `/root/webScreen/config/config.json`。保留服务器原有: | ||
| 95 | + | ||
| 96 | +- `GETCLASSURL` | ||
| 97 | +- `GETCLASSURLPARAMETER` | ||
| 98 | +- `PROJECTWINCATALOG` | ||
| 99 | +- `PROJECTCATALOG` | ||
| 100 | +- `BACKMEDIACONFIG` | ||
| 101 | +- `classLastNumber` | ||
| 102 | + | ||
| 103 | +目录应与服务器一致: | ||
| 104 | + | ||
| 105 | +```json | ||
| 106 | +"PROJECTWINCATALOG": "/root/web_capture_release/linux-x64", | ||
| 107 | +"PROJECTCATALOG": "/root/web_capture_release" | ||
| 108 | +``` | ||
| 109 | + | ||
| 110 | +`BACKMEDIACONFIG.url` 必须指向已支持 `recBeginTime/recEndTime` 的 PCLive 测试版本。保留验证服务器已确认可用的 `devback` 或测试路径,不在代码中硬编码。 | ||
| 111 | + | ||
| 112 | +高光配置: | ||
| 113 | + | ||
| 114 | +```json | ||
| 115 | +"HIGHLIGHTCONFIG": { | ||
| 116 | + "enabled": false, | ||
| 117 | + "sourceMode": "site", | ||
| 118 | + "siteIds": ["xdyui2"], | ||
| 119 | + "apiBaseUrl": "https://saas.xuedianyun.com", | ||
| 120 | + "pageSize": 100, | ||
| 121 | + "taskPageSize": 100, | ||
| 122 | + "maxPages": 1000, | ||
| 123 | + "maxConcurrent": 2, | ||
| 124 | + "maxDurationMs": 21600000, | ||
| 125 | + "apiTimeoutMs": 10000, | ||
| 126 | + "apiRetryCount": 2, | ||
| 127 | + "apiRetryBaseDelayMs": 500, | ||
| 128 | + "loadGraceMs": 60000, | ||
| 129 | + "endGraceMs": 10000, | ||
| 130 | + "taskRetentionMs": 86400000, | ||
| 131 | + "outputNamespace": "", | ||
| 132 | + "outputBaseUrl": "https://xdymp4.xuedianyun.com" | ||
| 133 | +} | ||
| 134 | +``` | ||
| 135 | + | ||
| 136 | +首次启动保持 `enabled=false`。验证 JSON: | ||
| 137 | + | ||
| 138 | +```bash | ||
| 139 | +node -e "JSON.parse(require('fs').readFileSync('config/config.json')); console.log('config ok')" | ||
| 140 | +``` | ||
| 141 | + | ||
| 142 | +## 7. 启动服务 | ||
| 143 | + | ||
| 144 | +测试期间先不要配置 cron。 | ||
| 145 | + | ||
| 146 | +```bash | ||
| 147 | +npm run pm2 | ||
| 148 | +pm2 show webScreen | ||
| 149 | +curl http://127.0.0.1:3001/highlight/status | ||
| 150 | +``` | ||
| 151 | + | ||
| 152 | +若 PM2 已有同名进程: | ||
| 153 | + | ||
| 154 | +```bash | ||
| 155 | +pm2 restart webScreen | ||
| 156 | +``` | ||
| 157 | + | ||
| 158 | +状态接口预期: | ||
| 159 | + | ||
| 160 | +```json | ||
| 161 | +{ | ||
| 162 | + "code": 0, | ||
| 163 | + "message": "success", | ||
| 164 | + "data": { | ||
| 165 | + "queued": 0, | ||
| 166 | + "recording": 0, | ||
| 167 | + "knownTasks": 0 | ||
| 168 | + } | ||
| 169 | +} | ||
| 170 | +``` | ||
| 171 | + | ||
| 172 | +查看日志: | ||
| 173 | + | ||
| 174 | +```bash | ||
| 175 | +pm2 logs webScreen --lines 100 | ||
| 176 | +``` | ||
| 177 | + | ||
| 178 | +## 8. 开启 xdyui2 | ||
| 179 | + | ||
| 180 | +基础服务正常后修改: | ||
| 181 | + | ||
| 182 | +```json | ||
| 183 | +"enabled": true, | ||
| 184 | +"sourceMode": "site", | ||
| 185 | +"siteIds": ["xdyui2"] | ||
| 186 | +``` | ||
| 187 | + | ||
| 188 | +```bash | ||
| 189 | +pm2 restart webScreen | ||
| 190 | +``` | ||
| 191 | + | ||
| 192 | +## 9. 准备测试课堂 | ||
| 193 | + | ||
| 194 | +选择一个 xdyui2 已结束课堂: | ||
| 195 | + | ||
| 196 | +- 至少两条高光。 | ||
| 197 | +- 回放正常。 | ||
| 198 | +- 最好含教师、学生音视频、屏幕共享和声音。 | ||
| 199 | + | ||
| 200 | +记录: | ||
| 201 | + | ||
| 202 | +```text | ||
| 203 | +siteId:xdyui2 | ||
| 204 | +classId:__________ | ||
| 205 | +高光数量:__________ | ||
| 206 | +课堂日期:__________ | ||
| 207 | +``` | ||
| 208 | + | ||
| 209 | +## 10. 只读预览 | ||
| 210 | + | ||
| 211 | +预览不会启动录制程序: | ||
| 212 | + | ||
| 213 | +```bash | ||
| 214 | +curl -X POST http://127.0.0.1:3001/highlight/preview/by-class \ | ||
| 215 | + -H 'Content-Type: application/json' \ | ||
| 216 | + -d '{"classId":"替换为课堂号"}' | ||
| 217 | +``` | ||
| 218 | + | ||
| 219 | +逐条检查: | ||
| 220 | + | ||
| 221 | +- `siteId` 是 `xdyui2`。 | ||
| 222 | +- `highlightId` 不重复。 | ||
| 223 | +- `classId` 正确。 | ||
| 224 | +- `beginTime/endTime` 是 13 位毫秒时间戳。 | ||
| 225 | +- `duration = endTime - beginTime`。 | ||
| 226 | +- `playbackUrl` 含正确的 `recBeginTime/recEndTime`。 | ||
| 227 | +- 文件名为 `{classId}_highlight_{highlightId}.mp4`。 | ||
| 228 | +- 路径位于 `/root/web_capture_release/media/xdyui2/{yyyyMMdd}/`。 | ||
| 229 | + | ||
| 230 | +返回“无高光数据”时,先让后端确认高光表确实存在记录。 | ||
| 231 | + | ||
| 232 | +## 11. 单课堂录制 | ||
| 233 | + | ||
| 234 | +```bash | ||
| 235 | +curl -X POST http://127.0.0.1:3001/highlight/recording/by-class \ | ||
| 236 | + -H 'Content-Type: application/json' \ | ||
| 237 | + -d '{"classId":"替换为课堂号"}' | ||
| 238 | +``` | ||
| 239 | + | ||
| 240 | +新任务初始状态应为 `queued`;已有文件可能返回 `uploading` 或 `generated`。 | ||
| 241 | + | ||
| 242 | +观察队列和进程: | ||
| 243 | + | ||
| 244 | +```bash | ||
| 245 | +watch -n 2 'curl -s http://127.0.0.1:3001/highlight/status' | ||
| 246 | +tail -f /root/webScreen/log/$(date +%Y%m%d).txt | ||
| 247 | +ps -ef | grep '[w]eb_capture_c' | ||
| 248 | +``` | ||
| 249 | + | ||
| 250 | +响应返回后不能立即停止 PM2;录制在后台队列继续执行。 | ||
| 251 | + | ||
| 252 | +## 12. 本地文件验证 | ||
| 253 | + | ||
| 254 | +```bash | ||
| 255 | +find /root/web_capture_release/media/xdyui2 -type f -name '课堂号_highlight_*.mp4' -ls | ||
| 256 | +``` | ||
| 257 | + | ||
| 258 | +要求: | ||
| 259 | + | ||
| 260 | +- N 条高光生成 N 个文件。 | ||
| 261 | +- 文件名中的 `highlightId` 不同。 | ||
| 262 | +- 文件大小大于 0。 | ||
| 263 | +- 不覆盖旧 `{classId}.mp4`。 | ||
| 264 | +- 日期目录包含 `download.json`。 | ||
| 265 | +- `.highlight_tmp` 无本次任务残留。 | ||
| 266 | + | ||
| 267 | +如有 ffprobe: | ||
| 268 | + | ||
| 269 | +```bash | ||
| 270 | +ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 /完整/文件路径.mp4 | ||
| 271 | +``` | ||
| 272 | + | ||
| 273 | +人工播放检查: | ||
| 274 | + | ||
| 275 | +- 开始位置接近 `beginTime`。 | ||
| 276 | +- 结束位置接近 `endTime`。 | ||
| 277 | +- 教师、学生、屏幕共享画面正常。 | ||
| 278 | +- 声音正常。 | ||
| 279 | +- 文件不是整堂课堂。 | ||
| 280 | + | ||
| 281 | +## 13. 重复录制验证 | ||
| 282 | + | ||
| 283 | +再次调用同一课堂的 `/highlight/recording/by-class`。 | ||
| 284 | + | ||
| 285 | +要求: | ||
| 286 | + | ||
| 287 | +- 不再启动新的 `web_capture_c`。 | ||
| 288 | +- 文件数量不增加。 | ||
| 289 | +- 原文件不被覆盖。 | ||
| 290 | +- OSS 已有文件时也不重复录制。 | ||
| 291 | + | ||
| 292 | +## 14. OSS 搬运和多地址查询 | ||
| 293 | + | ||
| 294 | +等待服务器原搬运任务执行。预期 OSS Key: | ||
| 295 | + | ||
| 296 | +```text | ||
| 297 | +oss/xdyui2/{yyyyMMdd}/{classId}_highlight_{highlightId}.mp4 | ||
| 298 | +``` | ||
| 299 | + | ||
| 300 | +查询: | ||
| 301 | + | ||
| 302 | +```bash | ||
| 303 | +curl -X POST http://127.0.0.1:3001/highlight/fileExists \ | ||
| 304 | + -H 'Content-Type: application/json' \ | ||
| 305 | + -d '{"siteId":"xdyui2","classId":"替换为课堂号"}' | ||
| 306 | +``` | ||
| 307 | + | ||
| 308 | +OSS 尚不可见时: | ||
| 309 | + | ||
| 310 | +```text | ||
| 311 | +status = uploading | ||
| 312 | +generated = false | ||
| 313 | +``` | ||
| 314 | + | ||
| 315 | +OSS 可见后: | ||
| 316 | + | ||
| 317 | +```text | ||
| 318 | +status = generated | ||
| 319 | +generated = true | ||
| 320 | +url = https://xdymp4.xuedianyun.com/oss/... | ||
| 321 | +``` | ||
| 322 | + | ||
| 323 | +N 条高光时,`classUrlList` 必须有 N 条记录。 | ||
| 324 | + | ||
| 325 | +## 15. 前一天全量验证 | ||
| 326 | + | ||
| 327 | +保持: | ||
| 328 | + | ||
| 329 | +```json | ||
| 330 | +"sourceMode": "site", | ||
| 331 | +"siteIds": ["xdyui2"] | ||
| 332 | +``` | ||
| 333 | + | ||
| 334 | +手工调用 cron 入口: | ||
| 335 | + | ||
| 336 | +```bash | ||
| 337 | +wget -qO- http://127.0.0.1:3001/recording | ||
| 338 | +``` | ||
| 339 | + | ||
| 340 | +检查: | ||
| 341 | + | ||
| 342 | +- `code` 为 `"0"`。 | ||
| 343 | +- `data.mode` 为 `site`。 | ||
| 344 | +- `beginTime/endTime` 是 Asia/Shanghai 前一天。 | ||
| 345 | +- 只查询 xdyui2。 | ||
| 346 | +- 前一天每条有效高光都进入队列。 | ||
| 347 | + | ||
| 348 | +## 16. 任务模式验证 | ||
| 349 | + | ||
| 350 | +全量模式通过后改为: | ||
| 351 | + | ||
| 352 | +```json | ||
| 353 | +"sourceMode": "task" | ||
| 354 | +``` | ||
| 355 | + | ||
| 356 | +```bash | ||
| 357 | +pm2 restart webScreen | ||
| 358 | +``` | ||
| 359 | + | ||
| 360 | +请后端创建四组任务: | ||
| 361 | + | ||
| 362 | +1. `status=0, onlyHighlight=1, siteId=xdyui2`:应录制。 | ||
| 363 | +2. `status!=0, onlyHighlight=1`:不录制。 | ||
| 364 | +3. `status=0, onlyHighlight=0`:不进入高光录制。 | ||
| 365 | +4. 其他站点 `status=0, onlyHighlight=1`:不录制。 | ||
| 366 | + | ||
| 367 | +```bash | ||
| 368 | +wget -qO- http://127.0.0.1:3001/recording | ||
| 369 | +``` | ||
| 370 | + | ||
| 371 | +检查: | ||
| 372 | + | ||
| 373 | +- `data.mode` 为 `task`。 | ||
| 374 | +- `pendingTasks` 只统计第一类任务。 | ||
| 375 | +- 使用 `taskList.meetingNumber` 查询课堂高光。 | ||
| 376 | + | ||
| 377 | +后端尚未确认任务状态回写接口。当前依靠内存队列、本地文件和 OSS 文件避免重复录制。 | ||
| 378 | + | ||
| 379 | +## 17. 启用每日 cron | ||
| 380 | + | ||
| 381 | +只有单课堂、重复录制、OSS 搬运和全量模式全部通过后才启用: | ||
| 382 | + | ||
| 383 | +```cron | ||
| 384 | +57 7 * * * wget -qO- http://127.0.0.1:3001/recording >/dev/null 2>&1 | ||
| 385 | +``` | ||
| 386 | + | ||
| 387 | +```bash | ||
| 388 | +crontab -l | ||
| 389 | +``` | ||
| 390 | + | ||
| 391 | +任务每天 `07:57` 执行。任务模式中新任务最多等待约 24 小时,业务已确认可接受。 | ||
| 392 | + | ||
| 393 | +## 18. 日常使用 | ||
| 394 | + | ||
| 395 | +```bash | ||
| 396 | +pm2 show webScreen | ||
| 397 | +curl http://127.0.0.1:3001/highlight/status | ||
| 398 | +pm2 logs webScreen --lines 200 | ||
| 399 | +tail -n 200 /root/webScreen/log/$(date +%Y%m%d).txt | ||
| 400 | +``` | ||
| 401 | + | ||
| 402 | +手工补录: | ||
| 403 | + | ||
| 404 | +```bash | ||
| 405 | +curl -X POST http://127.0.0.1:3001/highlight/recording/by-class \ | ||
| 406 | + -H 'Content-Type: application/json' \ | ||
| 407 | + -d '{"classId":"课堂号"}' | ||
| 408 | +``` | ||
| 409 | + | ||
| 410 | +查询地址: | ||
| 411 | + | ||
| 412 | +```bash | ||
| 413 | +curl -X POST http://127.0.0.1:3001/highlight/fileExists \ | ||
| 414 | + -H 'Content-Type: application/json' \ | ||
| 415 | + -d '{"siteId":"xdyui2","classId":"课堂号"}' | ||
| 416 | +``` | ||
| 417 | + | ||
| 418 | +## 19. 故障排查 | ||
| 419 | + | ||
| 420 | +### 高光录制功能未启用 | ||
| 421 | + | ||
| 422 | +检查 `HIGHLIGHTCONFIG.enabled=true`,修改后执行 `pm2 restart webScreen`。 | ||
| 423 | + | ||
| 424 | +### SaaS 接口 code=4 | ||
| 425 | + | ||
| 426 | +检查服务器时间、NTP、`apiBaseUrl` 和最新代码。签名时间戳必须是 13 位毫秒。 | ||
| 427 | + | ||
| 428 | +### 无高光数据 | ||
| 429 | + | ||
| 430 | +检查高光表记录、`meetingNumber`、`siteId=xdyui2`,以及全量模式时间窗是否为前一天。 | ||
| 431 | + | ||
| 432 | +### web_capture_c 启动失败 | ||
| 433 | + | ||
| 434 | +```bash | ||
| 435 | +ls -l /root/web_capture_release/linux-x64/web_capture_c | ||
| 436 | +ldd /root/web_capture_release/linux-x64/web_capture_c | ||
| 437 | +echo "$DISPLAY" | ||
| 438 | +``` | ||
| 439 | + | ||
| 440 | +比较正式服务器的显示服务、字体、浏览器依赖和 PM2 环境变量。 | ||
| 441 | + | ||
| 442 | +### 一直是 uploading | ||
| 443 | + | ||
| 444 | +检查搬运任务是否运行,是否支持 `{classId}_highlight_{highlightId}.mp4`、`download.json` 和 `oss/xdyui2/{yyyyMMdd}/`。 | ||
| 445 | + | ||
| 446 | +### OSS文件状态查询失败 | ||
| 447 | + | ||
| 448 | +检查 `.env`、AccessKey 权限、OSS 网络和 bucket `xdymp4`。OSS 查询异常不会被当作“文件不存在”。 | ||
| 449 | + | ||
| 450 | +### 视频时间错误 | ||
| 451 | + | ||
| 452 | +确认 `playbackUrl` 的 `recBeginTime/recEndTime` 与接口原值完全一致。不能传 duration,不能换算相对秒数。 | ||
| 453 | + | ||
| 454 | +## 20. 回滚 | ||
| 455 | + | ||
| 456 | +优先使用配置回滚: | ||
| 457 | + | ||
| 458 | +```json | ||
| 459 | +"HIGHLIGHTCONFIG": { | ||
| 460 | + "enabled": false | ||
| 461 | +} | ||
| 462 | +``` | ||
| 463 | + | ||
| 464 | +```bash | ||
| 465 | +pm2 restart webScreen | ||
| 466 | +``` | ||
| 467 | + | ||
| 468 | +关闭后,`GET /recording` 恢复原整课逻辑。`POST /recording`、`POST /recordingTask`、`POST /fileExists` 和实时录制接口不变。 | ||
| 469 | + | ||
| 470 | +## 21. 测试记录模板 | ||
| 471 | + | ||
| 472 | +```text | ||
| 473 | +测试服务器: | ||
| 474 | +测试日期: | ||
| 475 | +测试人员: | ||
| 476 | +Git 提交(执行 git rev-parse --short HEAD): | ||
| 477 | +站点:xdyui2 | ||
| 478 | +课堂号: | ||
| 479 | +高光记录数: | ||
| 480 | +本地 MP4 数量: | ||
| 481 | +OSS MP4 数量: | ||
| 482 | +预览接口:通过 / 失败 | ||
| 483 | +单课堂录制:通过 / 失败 | ||
| 484 | +时间范围:通过 / 失败 | ||
| 485 | +音频:通过 / 失败 | ||
| 486 | +教师视频:通过 / 失败 | ||
| 487 | +学生视频:通过 / 失败 | ||
| 488 | +屏幕共享:通过 / 失败 | ||
| 489 | +重复录制:通过 / 失败 | ||
| 490 | +OSS 搬运:通过 / 失败 | ||
| 491 | +多地址查询:通过 / 失败 | ||
| 492 | +前一天全量:通过 / 失败 | ||
| 493 | +任务模式:通过 / 失败 / 未测试 | ||
| 494 | +问题记录: | ||
| 495 | +结论:可继续验证 / 需要修复 | ||
| 496 | +``` |
-
请 注册 或 登录 后发表评论