fix(canvas): [PKG-CANVAS-SUBTITLE-01] attach native subtitle tracks

This commit is contained in:
Harvey Zhao committed 2026-09-14 18:51:57 +08:00
1 parent d89728c0a6
commit c3967bcbf4
23 files changed
+1459 -11

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,60 @@
# PKG-CANVAS-SUBTITLE-01 Canvas 原生字幕轨道
Canvas-05 的组合检查在三引擎、新旧核心均复现字幕 cues 为零。
核心初始化会检查 textTracks[0];Canvas 底层 video 没有模板的初始 track,所以
字幕初始化直接返回。仅将后续 appendChild(track) 转给 video 仍是六项失败,
已保留两轮报告,不能把插入路由单独视为修复。
最终方案:底层 video 先创建无 URL 的 metadata 占位轨道以提供原有能力探测;
核心实际 appendChild(HTML track) 时移除占位轨道,把真实字幕交给原生 video。
普通 Canvas 节点操作保持原路径;销毁后不再向底层 video 插入轨道。
新 subtitles.ts 只负责此适配,入口负责初始化失败回滚和整体资源释放。
这是修复原本不可工作的字幕路径。原生 Canvas 返回值、绘制方法、公开类型和
媒体事件不变;实际字幕 track 的 parent 变成 video,已在 README/ARCHITECTURE
明确。仅 active 的 HTML track 插入进入媒体路径,普通节点继续使用绑定 Canvas
接收者的原方法。并未把所有 DOM 方法改为 video 方法,也没有修改消费者配置。
核心负责真实轨道替换、cuechange 订阅和 Blob URL;代理负责底层 video 的释放。
初始轨道创建/插入位于现有初始化 try/catch 内,失败回滚所有私有资源。
## 验证与历史对照
详情、浏览器版本、报告 SHA、加载包入口及摘要在
[canvas-subtitles-validation.json](../baselines/canvas-subtitles-validation.json)。
- 最初源码和仅插入路由两轮各 6 失败;初始轨道修正后 6 通过。
- 扩展原生字幕/Canvas 生命周期 24 通过,覆盖真实 VTT 加载、暂停寻址、字幕
替换、旧节点断开且只留一个原生轨道、普通 span 插入/移除、Canvas 方法和销毁。
- 仓库外构建/打包/离线安装/冻结重装后,main/legacy 各 33 通过,另含 Ambilight
组合播放/取色/双 RAF 清理。最后加入历史模式后再次定向 6 通过。
- 真正 npm 1.1.0 同一字幕用例三引擎共 6 失败。设置
`ARTPLAYER_CANVAS_SUBTITLE_BASELINE=1.1.0` 可重跑;它不允许与 installed map
混用,且失败不被改写为通过。首次失败的 $track 仍在被替换掉的模板 video 内;
不能误称它已经被 append 到 Canvas,根因首先是同步能力检查返回空。
- 58 项 Canvas Node 回归,包括初始轨道插入异常后的回滚;17 项实际安装旧/新
TypeScript 消费者;严格分包 TS、专项 ESLint、根 lint(0 错误/1 既有 warning)、
6 项风险/runner 测试及固定工具链通过。所有公开声明未变。
- `yarn build artplayer-proxy-canvas` 生成三种 dist 并同步 docs/compiled。四包
`test:package --include=artplayer-plugin-ambilight,artplayer-proxy-canvas` 的
36 个运行时/5+8 类型模式仍只针对 core/chapter;不将它们虚报为 Canvas 验收。
本地 Canvas 示例增加现有 subtitle.srt 配置。内置浏览器显示一个 Canvas、底层
video 的 34 条原生 cues,实际播放并显示“星星降落的日子 / 星が降った日”。
UA 报 Chrome/152.0.0.0;该后端不支持完整版本查询或内容导出,截图在会话中。
一次直接诊断 seek 返回 0,未计为 demo 寻址成功;正式寻址证据来自安装测试。
临时标签页已关闭。对示例单独使用普通 Node ESLint 会报页面提供的 Artplayer/
插件全局与编辑器消费的 art 未使用;没有为此改动全局 lint 规则。示例语法和
实际页面验证通过,测试文件自身的 if 样式诊断已修复。
## 兼容、接续和回退
API-07/08 的修复限于原先无法工作的字幕能力与轨道父节点;原接口、样式类、
Canvas 绘制、工厂同步返回和 main/module/legacy/types 入口均保留。没有新增依赖。
后续字幕工作从 subtitles.ts 开始,调度仍归 scheduler/renderer,避免依赖核心私有
实现。运行 `yarn test:browser:installed test/browser/canvas-subtitles.spec.js
test/browser/canvas-lifecycle.spec.js test/browser/ambilight-proxy.spec.js --workers=2`
前提供已验证的四包 map;普通源码模式用 test:browser:source。
Canvas-05/06、Document PiP、真机及完整发布门槛仍未完成;Auto Thumbnail 首帧
问题也未改变。没有远端 CI、推送、部署或 npm 发布。本任务独立本地提交。
回退需一起还原 source、测试、架构/示例、生成产物和任务/风险状态,保留历史报告。
+6 -4
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 258 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 259 项,范围 22 个包及工作区/示例。
状态:todo 50 / doing 19 / blocked 0 / done 189 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 50 / doing 19 / blocked 0 / done 190 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -31,7 +31,7 @@
| artplayer-plugin-multiple-subtitles | 1.2.0 | PKG-MULTI-SUB-01, PKG-MULTI-SUB-02, PKG-MULTI-SUB-03, PKG-MULTI-SUB-04, PKG-MULTI-SUB-07, PKG-MULTI-SUB-08, PKG-MULTI-SUB-05, PKG-MULTI-SUB-06, PKG-MULTI-SUB-09, PKG-MULTI-SUB-10, PKG-MULTI-SUB-11 |
| artplayer-plugin-vast | 1.2.0 | PKG-VAST-01, PKG-VAST-02, PKG-VAST-03, PKG-VAST-04, PKG-VAST-05, PKG-VAST-06, PKG-VAST-07 |
| artplayer-plugin-vtt-thumbnail | 1.1.0 | PKG-VTT-THUMB-01, PKG-VTT-THUMB-02, PKG-VTT-THUMB-03, PKG-VTT-THUMB-04, PKG-VTT-THUMB-05, PKG-VTT-THUMB-06 |
| artplayer-proxy-canvas | 1.1.0 | PKG-AMBILIGHT-PROXY-01, PKG-CANVAS-01, PKG-CANVAS-02, PKG-CANVAS-03, PKG-CANVAS-04, PKG-CANVAS-05, PKG-CANVAS-06, PKG-FACTORY-01 |
| artplayer-proxy-canvas | 1.1.0 | PKG-AMBILIGHT-PROXY-01, PKG-CANVAS-01, PKG-CANVAS-02, PKG-CANVAS-03, PKG-CANVAS-04, PKG-CANVAS-05, PKG-CANVAS-06, PKG-FACTORY-01, PKG-CANVAS-SUBTITLE-01 |
| artplayer-proxy-mediabunny | 1.2.0 | PKG-MB-01, PKG-MB-02, PKG-MB-03, PKG-MB-04, PKG-MB-05, PKG-MB-06, PKG-MB-07, PKG-MB-08, PKG-MB-09, PKG-MB-10 |
| artplayer-tool-iframe | 1.1.0 | PKG-IFRAME-01, PKG-IFRAME-02, PKG-IFRAME-03, PKG-IFRAME-04, PKG-IFRAME-05, PKG-IFRAME-06 |
| artplayer-tool-thumbnail | 4.4.0 | PKG-TOOL-THUMB-01, PKG-TOOL-THUMB-02, PKG-TOOL-THUMB-03, PKG-TOOL-THUMB-04, PKG-TOOL-THUMB-05, PKG-TOOL-THUMB-06 |
@@ -347,8 +347,9 @@
| PKG-CANVAS-02 | artplayer-proxy-canvas<br>建立特有行为与错误测试 | PKG-CANVAS-01, ENG-03, ENG-05 | ready/loadeddata/canplay、play/seek、回调、resize 与销毁 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-CANVAS-03 | artplayer-proxy-canvas<br>整理内部职责与资源 | PKG-CANVAS-02, CORE-06, CORE-11, CORE-16 | video adapter/原 canvas 方法/RAF 绘制/事件订阅分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-CANVAS-04 | artplayer-proxy-canvas<br>迁移自有源码和公开类型 | PKG-CANVAS-03, ENG-04, ENG-06, CORE-07 | canvas 与媒体能力的精确组合类型,保持 Result | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
| PKG-CANVAS-05 | artplayer-proxy-canvas<br>验证新旧核心和组合 | PKG-CANVAS-04, CORE-22, PKG-DPIP-04, PKG-FACTORY-01 | 真实 video/canvas 绘制、字幕和 document PiP 恢复 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-CANVAS-05 | artplayer-proxy-canvas<br>验证新旧核心和组合 | PKG-CANVAS-04, CORE-22, PKG-DPIP-04, PKG-FACTORY-01, PKG-CANVAS-SUBTITLE-01 | 真实 video/canvas 绘制、字幕和 document PiP 恢复 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-CANVAS-06 | artplayer-proxy-canvas<br>验证分发并同步文档 | PKG-CANVAS-05, ENG-07 | canvas.js、三种产物、调用兼容与资源证据 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
| PKG-CANVAS-SUBTITLE-01 | artplayer-proxy-canvas<br>修复 Canvas 代理原生字幕轨道挂载 | PKG-CANVAS-04 | 初始字幕能力、原生轨道挂载与资源生命周期适配及新旧核心回归 | 复现旧字幕 cues 为空;新旧核心加载、寻址、切换、销毁通过;普通 Canvas 节点行为和分发入口保持兼容 | M | done |
## 5 包迁移:artplayer-proxy-mediabunny
@@ -670,3 +671,4 @@
- SITE-VCONSOLE-01: [记录](changes/2026-09-14-SITE-VCONSOLE-01-lifecycle.md) [记录](baselines/vconsole-lifecycle-validation.json)
- CI-BROWSER-01: [记录](changes/2026-09-14-CI-BROWSER-01-scopes.md) [记录](baselines/browser-scope-validation.json)
- PKG-CHAPTER-HOVER-01: [记录](changes/2026-09-14-PKG-CHAPTER-HOVER-01-geometry.md) [记录](baselines/chapter-hover-validation.json)
- PKG-CANVAS-SUBTITLE-01: [记录](changes/2026-09-14-PKG-CANVAS-SUBTITLE-01-track.md) [记录](baselines/canvas-subtitles-validation.json)
+15
View File
@@ -1,5 +1,20 @@
# 进度与证据
## PKG-CANVAS-SUBTITLE-01 原生字幕轨道修复完成
新旧核心三引擎复现 Canvas 字幕为空。先前说明需修正:初始失败中的 $track
仍在旧模板的 detached video;底层 video 没有初始轨道,核心能力检查直接返回。
仅路由 appendChild 的尝试仍六项失败;增加无 URL metadata 占位轨道并在首次
真实轨道插入时替换后,原生字幕正常加载。模块、普通 Canvas 路径、失败回滚、
销毁边界与包内文档一起更新。实际 npm 1.1.0 对照六项失败,保留旧红新绿。
源码扩展24通过,安装main/legacy各33通过,最终定向6通过;Node58、安装类型17、
风险/runner6、严格TS/lint/工具链通过。示例更新且内置浏览器实际显示双语字幕。
见[变更](changes/2026-09-14-PKG-CANVAS-SUBTITLE-01-track.md)与
[证据](baselines/canvas-subtitles-validation.json)。259项:190 done、19 doing、50 todo。
Canvas-05/06及Document PiP/真机未关闭;Auto Thumbnail原生首帧仍待另一后端或
准确解码路径证据。本机WSL无已安装发行版,未安装系统环境或更改原像素门槛。
没有push/部署/发布;本任务独立提交后必须通过提交审计再开始下一任务。
## PKG-CHAPTER-HOVER-01 全屏悬停测试同步完成
原始 installed 224/1 失败保持归档。受控原生进度条移动实验确认立即读取坐标
+1
View File
@@ -272,3 +272,4 @@
| ENG-PERF-OBS-01 | resolved / 已复现 | A nominal 350 ms resource observation can record only 349 ms and fail the required minimum | ENG-13 |
| VCONSOLE-LIFECYCLE-01 | resolved / 已复现 | vConsole delayed log, panel and scroller work outlives its owner | SITE-07, SITE-05, SITE-VCONSOLE-01 |
| CHAPTER-FULLSCREEN-GEOMETRY-01 | resolved / 已复现 | Chromium 原生全屏后章节 hover 标题曾出现后又隐藏 | PKG-CHAPTER-05, PKG-CHAPTER-HOVER-01 |
| CANVAS-SUBTITLE-01 | resolved / 已复现 | Canvas底层video缺初始字幕轨道且普通Canvas挂载不能加载原生字幕 | PKG-CANVAS-SUBTITLE-01, PKG-CANVAS-05 |
+23
View File
@@ -6218,6 +6218,29 @@
"test/browser/chapter-hover.spec.js"
],
"resolutionRationale": "The immediate bounding-box read permits stale pointer coordinates while progress transforms move. Initial hit-test control gives 4 failures/2 passes before and 6 passes after waiting for locator stability. WebKit hit tests disagree with the final rectangle, so additional explicit bounds assertions were added: baseline 6 failures, stable main/legacy 6 passes each. Complete main/legacy chapter combination suites retain title, opacity, thumbnails and fullscreen assertions (66 passes each). This closes the identified test synchronization race, not all possible production fullscreen defects or CHAPTER-TIMING-01. Original 224/1 failure remains archived; its exact scheduler cannot be replayed."
},
{
"id": "CANVAS-SUBTITLE-01",
"title": "Canvas底层video缺初始字幕轨道且普通Canvas挂载不能加载原生字幕",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"PKG-CANVAS-SUBTITLE-01",
"PKG-CANVAS-05"
],
"evidence": [
"refactor/changes/2026-09-14-PKG-CANVAS-SUBTITLE-01-track.md",
"test/browser/canvas-subtitles.spec.js"
],
"compatibleResolution": "适配原生track能力和插入,同时保留普通Canvas操作;不得要求旧核心消费者更改调用。",
"closureCriteria": "新旧核心三引擎字幕加载/寻址/切换/清理、普通节点与分发回归,有旧红新绿证据。",
"workspaceState": "Native subtitle bootstrap and track insertion are isolated in subtitles.ts. Old/new core source and installed main/legacy pass real subtitle load/seek/replacement/cleanup and normal Canvas-node checks. Public declaration shape is unchanged.",
"resolutionEvidence": [
"refactor/changes/2026-09-14-PKG-CANVAS-SUBTITLE-01-track.md",
"refactor/baselines/canvas-subtitles-validation.json",
"test/browser/canvas-subtitles.spec.js"
],
"resolutionRationale": "Initial candidate and routing-only controls each fail all six subtitle cases. Bootstrap + insertion adaptation passes; npm 1.1.0 independently fails all six. Expanded native source tests pass 24; installed main and legacy pass 33 each; final six pass after adding baseline selection. Captions also visibly render in the local demo. This fixes subtitle capability/insertion only; broader Canvas integration remains open."
}
]
}
+21 -1
View File
@@ -3635,7 +3635,8 @@
"PKG-CANVAS-04",
"CORE-22",
"PKG-DPIP-04",
"PKG-FACTORY-01"
"PKG-FACTORY-01",
"PKG-CANVAS-SUBTITLE-01"
],
"status": "todo",
"risk": "H",
@@ -5389,6 +5390,25 @@
"changes/2026-09-14-PKG-CHAPTER-HOVER-01-geometry.md",
"baselines/chapter-hover-validation.json"
]
},
{
"id": "PKG-CANVAS-SUBTITLE-01",
"phase": "5 包迁移:artplayer-proxy-canvas",
"title": "修复 Canvas 代理原生字幕轨道挂载",
"scope": [
"artplayer-proxy-canvas"
],
"dependsOn": [
"PKG-CANVAS-04"
],
"status": "done",
"risk": "M",
"deliverable": "初始字幕能力、原生轨道挂载与资源生命周期适配及新旧核心回归",
"acceptance": "复现旧字幕 cues 为空;新旧核心加载、寻址、切换、销毁通过;普通 Canvas 节点行为和分发入口保持兼容",
"evidence": [
"changes/2026-09-14-PKG-CANVAS-SUBTITLE-01-track.md",
"baselines/canvas-subtitles-validation.json"
]
}
]
}