# Tennis Training Hub - 变更日志 ## 2026.03.17-live-camera-relay-buffer (2026-03-17) ### 功能更新 - `/live-camera` 的同步观看改为播放 media 服务生成的滚动缓存视频,不再轮询 `live-frame.jpg` 单帧图片,因此观看端的画面会按最近 60 秒缓存视频平滑播放 - owner 端每个 60 秒的合成录像分段现在会额外上传到 `relay` 会话,worker 会在收到新分段后自动重建最近窗口的 `preview.webm` - `relay` 会话只保留最近 60 秒视频分段,旧分段会从会话元数据和磁盘同步清理,避免观看端继续读到旧一分钟之前的缓存 - media worker 会自动清理超过 30 分钟无活动的 relay 会话、分段目录和公开缓存文件,降低磁盘堆积风险 - viewer 页面文案、加载提示和按钮文案已同步更新为“缓存视频 / 缓存回放”语义;预览阶段跳过 mp4 转码,Chrome 直接使用 webm,降低处理时延 ### 测试 - `cd media && go test ./...` - `pnpm vitest run client/src/lib/liveCamera.test.ts` - `pnpm exec playwright test tests/e2e/app.spec.ts --grep "live camera page exposes camera startup controls|live camera starts analysis and produces scores|live camera switches into viewer mode when another device already owns analysis|live camera recovers mojibake viewer titles before rendering|live camera no longer opens viewer peer retries when server relay is active"` - `pnpm check` - `pnpm build` - 线上 smoke:部署后确认 `https://te.hao.work/` 已提供新构建而不是旧资源版本,`/live-camera` viewer 端进入“服务端缓存同步”路径,首页与资源文件返回正确 MIME ### 线上 smoke - 部署完成后已确认 `https://te.hao.work/` 提供的是本次新构建,而不是旧资源版本 - `https://te.hao.work/live-camera` 的 viewer 端会走“服务端缓存同步”路径,不再请求旧的 `live-frame.jpg` 单帧同步 - 首页、主 JS、主 CSS 与 `pose` 模块均返回 `200` 和正确 MIME,未再出现脚本/样式被回退成 `text/html` 的问题 ### 仓库版本 - `63dbfd2+relay-buffer` ## 2026.03.17-live-camera-preview-recovery (2026-03-17) ### 功能更新 - `/live-camera` 的 runtime 标题恢复逻辑新增更严格的乱码筛除与二次 UTF-8 解码兜底,`服...` 这类异常标题会优先恢复为正常中文;无法恢复时会自动回退到稳定默认标题,避免继续显示脏字符串 - 同步观看退出时会完整重置 viewer 轮询、连接标记和帧版本,不再把旧的 viewer 状态带回 owner 或空闲态,修复退出同步后仍黑屏、仍显示“等待同步画面”的问题 - 本地摄像头预览增加独立重绑流程和多次 watchdog 重试,即使浏览器首帧没有及时绑定 `srcObject` 或 `play()` 被短暂中断,也会继续自动恢复本地预览 - 视频区域是否显示画面改为按当前 runtime 角色分别判断,避免 viewer 旧连接状态误导 owner 模式,导致本地没有预览时仍错误隐藏占位提示 ### 测试 - `pnpm check` - `pnpm vitest run client/src/lib/liveCamera.test.ts` - `pnpm exec playwright test tests/e2e/app.spec.ts --grep "live camera"` - `pnpm build` - 线上 smoke:`curl -I https://te.hao.work/` - 线上 smoke:`curl -I https://te.hao.work/assets/index-BJ7rV3xe.js` - 线上 smoke:`curl -I https://te.hao.work/assets/index-tNGuStgv.css` - 线上 smoke:`curl -I https://te.hao.work/assets/pose-CZKsH31a.js` ### 线上 smoke - `https://te.hao.work/` 已切换到本次新构建 - 当前公开站点前端资源 revision:`assets/index-BJ7rV3xe.js`、`assets/index-tNGuStgv.css`、`assets/pose-CZKsH31a.js` - 已确认 `index`、`css` 与 `pose` 模块均返回 `200`,且 MIME 分别为 `application/javascript`、`text/css`、`application/javascript`,不再出现此前的模块脚本和样式被当成 `text/html` 返回的问题 ### 仓库版本 - `06b9701` ## 2026.03.16-live-camera-runtime-refresh (2026-03-16) ### 功能更新 - `/live-camera` 在打开拍摄引导、启用摄像头、开始分析前,都会先向服务端强制刷新 runtime 状态,避免旧的同步观看锁残留导致本机明明已释放却仍无法启动 - 新增 runtime 标题乱码恢复逻辑,可自动把 UTF-8 被误按 Latin-1 显示的标题恢复成正常中文,避免出现 `服...` 一类异常标题 - 摄像头启动链路改为以 `getUserMedia` 成功为准;即使本地预览 `