fix(auto-thumbnail): [PKG-AUTO-THUMB-12] release stalled metadata loads

This commit is contained in:
Harvey Zhao committed 2026-09-15 12:31:32 +08:00
1 parent d3aa4bbfe4
commit 42ddead0cd
20 files changed
+6048 -20

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,69 @@
# PKG-AUTO-THUMB-12: bound the private decoder metadata wait
Implementation baseline: d3aa4bbfe4d9931249dce5e6a43afbe54b39800f.
## Defect and implementation
The private video could remain attached indefinitely if its request produced
neither loadedmetadata nor error. Frame and JPEG deadlines start later, so they
did not cover this phase. The seven final regression cases fail against the
prechange committed main artifact and pass against the changed implementation.
An earlier test draft omitted the required options object in one case; that draft
is not used as the final seven-case reproduction evidence.
`src/extraction.ts` now owns a 30-second metadata timer from immediately before
URL assignment until loadedmetadata or job disposal. Its callback becomes inert
when the phase ends, including if already queued before cancellation. The job's
existing disposal releases the handlers, resets and removes the decoder. Timer
registration that synchronously destroys the session cannot resume URL loading.
No extra module or dependency is needed: extraction already owns this phase.
This intentionally replaces an unbounded failed-load wait with the same warning
and cleanup policy used for frames and encoding. A slow load may now stop after
30 seconds. The last usable sheet remains available until replacement or destroy.
The public factory, Promise timing/result, options, ten-column sheet layout, frame
time formula, declarations, package entrypoints and dependency versions are
unchanged. Timers remain subject to browser/background scheduling; this is not a
guarantee of immediate network/GPU reclamation or an aggregate extraction timeout.
## Verification
The new unit cases cover no metadata, late metadata/timer callbacks, success,
native errors, destroy/restart, retained previous sheets and synchronous timer
registration reentry. They are part of `test:auto-thumbnail` and `test:unit`.
The existing native lifecycle file adds pending-metadata cases for timeout,
destroy and restart and remains in both source and installed CI collections.
The first browser harness used Playwright interception; Chromium/Firefox passed,
but three WebKit cases timed out waiting for `page.waitForRequest` before testing
cleanup. This is retained as failed harness evidence, not a plugin pass. The final
fixture uses a real server response that sends no metadata and confirms requests
through the server log. Its 10-second socket inactivity bound prevents failed
tests from leaving permanent connections. The test explicitly invokes the captured
30-second callback; it verifies native video cleanup, not 30 seconds of wall time.
Existing successful decoding/encoding tests continue to use real media events.
Commands and exact counts/artifact hashes are in the
[validation record](../baselines/auto-thumbnail-metadata-validation.json).
Source tests pass 189/189; rebuilt main and legacy each pass 82 targeted unit
cases and 36 browser cases across Chromium, Firefox and Windows WebKit. The latter
includes nine pending-metadata cases per artifact. Neither final browser run has
unhandled page errors. Failed-request observations (14 main, 16 legacy) remain in
the record, including deliberately canceled pending loads; these are not reports
of zero network failures. Package strict types, scoped lint and strict toolchain
checks pass. Existing WebKit pixel assertions still exclude the unresolved first
two cells when presentation callbacks are unavailable, as before this fix.
Normal `yarn build artplayer-plugin-auto-thumbnail` regenerates main, legacy and
ESM plus matching docs copies. There are no hand-edited bundles.
## Maintenance and remaining gates
The package README and ARCHITECTURE explain the independent metadata/frame/encode
deadlines and failure policy. The Windows WebKit first-frame pixel issue remains
open: existing pixel tests retain their documented fallback limitations. This
fix does not complete task03, the package combination matrix, remote CI, device
validation, or release reviews. No publishing, pushing or deployment is included.
Revert this task's dedicated commit to restore source/tests/docs and generated
artifacts together. Future changes to metadata loading should rerun the unit
suite and native lifecycle/pixel tests against rebuilt main and legacy outputs.
+6 -4
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 265 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 266 项,范围 22 个包及工作区/示例。
状态:todo 44 / doing 22 / blocked 0 / done 199 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 44 / doing 22 / blocked 0 / done 200 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -19,7 +19,7 @@
| artplayer-plugin-ambilight | 1.1.0 | PKG-AMBILIGHT-01, PKG-AMBILIGHT-02, PKG-AMBILIGHT-03, PKG-AMBILIGHT-04, PKG-AMBILIGHT-PROXY-01, PKG-AMBILIGHT-05, PKG-AMBILIGHT-06, PKG-FACTORY-01 |
| artplayer-plugin-asr | 2.1.0 | PKG-ASR-01, PKG-ASR-02, PKG-ASR-03, PKG-ASR-04, PKG-ASR-05, PKG-ASR-06, PKG-ASR-07, PKG-ASR-08, PKG-ASR-09 |
| artplayer-plugin-audio-track | 1.1.0 | PKG-AUDIO-01, PKG-AUDIO-02, PKG-AUDIO-03, PKG-AUDIO-04, PKG-AUDIO-05, PKG-AUDIO-06 |
| artplayer-plugin-auto-thumbnail | 1.1.0 | PKG-AUTO-THUMB-01, PKG-AUTO-THUMB-02, PKG-AUTO-THUMB-03, PKG-AUTO-THUMB-04, PKG-AUTO-THUMB-05, PKG-AUTO-THUMB-06, PKG-AUTO-THUMB-07, PKG-AUTO-THUMB-08, PKG-AUTO-THUMB-09, PKG-AUTO-THUMB-10, PKG-AUTO-THUMB-11 |
| artplayer-plugin-auto-thumbnail | 1.1.0 | PKG-AUTO-THUMB-01, PKG-AUTO-THUMB-02, PKG-AUTO-THUMB-03, PKG-AUTO-THUMB-04, PKG-AUTO-THUMB-05, PKG-AUTO-THUMB-06, PKG-AUTO-THUMB-07, PKG-AUTO-THUMB-08, PKG-AUTO-THUMB-09, PKG-AUTO-THUMB-10, PKG-AUTO-THUMB-11, PKG-AUTO-THUMB-12 |
| artplayer-plugin-chapter | 1.1.0 | PILOT-01, PKG-CHAPTER-01, PKG-CHAPTER-02, PKG-CHAPTER-03, PKG-CHAPTER-04, PKG-CHAPTER-05, PKG-CHAPTER-06, PKG-CHAPTER-HOVER-01 |
| artplayer-plugin-chromecast | 1.1.0 | PKG-CAST-01, PKG-CAST-02, PKG-CAST-03, PKG-CAST-04, PKG-CAST-05, PKG-CAST-06 |
| artplayer-plugin-danmuku | 5.3.0 | PKG-DANMUKU-01, PKG-DANMUKU-02, PKG-DANMUKU-03, PKG-DANMUKU-04, PKG-DANMUKU-05, PKG-DANMUKU-06, PKG-DANMUKU-07, PKG-DANMUKU-08, PKG-DANMUKU-09, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12, PKG-DANMUKU-MASK-LOAD-01 |
@@ -179,13 +179,14 @@
| PKG-AUTO-THUMB-02 | artplayer-plugin-auto-thumbnail<br>建立特有行为与错误测试 | PKG-AUTO-THUMB-01, ENG-03, ENG-05 | 抽帧边界、短视频、失败、连续来源和销毁中的抽帧 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-AUTO-THUMB-03 | artplayer-plugin-auto-thumbnail<br>整理内部职责与资源 | PKG-AUTO-THUMB-02, CORE-09, CORE-19, PKG-AUTO-THUMB-07 | 隐藏 video、seek 队列、canvas 编码与 Blob URL 清理 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | doing |
| PKG-AUTO-THUMB-04 | artplayer-plugin-auto-thumbnail<br>迁移自有源码和公开类型 | PKG-AUTO-THUMB-03, ENG-04, ENG-06, CORE-07, PKG-AUTO-THUMB-08, PKG-AUTO-THUMB-09, PKG-AUTO-THUMB-10, PKG-AUTO-THUMB-11 | 抽帧结果和真实异步插件返回类型兼容 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | todo |
| PKG-AUTO-THUMB-05 | artplayer-plugin-auto-thumbnail<br>验证新旧核心和组合 | PKG-AUTO-THUMB-04, CORE-22 | 旧核心/候选核心预览、多次加载无过期缩略图覆盖 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-AUTO-THUMB-05 | artplayer-plugin-auto-thumbnail<br>验证新旧核心和组合 | PKG-AUTO-THUMB-04, CORE-22, PKG-AUTO-THUMB-12 | 旧核心/候选核心预览、多次加载无过期缩略图覆盖 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-AUTO-THUMB-06 | artplayer-plugin-auto-thumbnail<br>验证分发并同步文档 | PKG-AUTO-THUMB-05, ENG-07 | auto.thumbnail.js、三种产物和内存/URL 证据 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
| PKG-AUTO-THUMB-07 | artplayer-plugin-auto-thumbnail<br>终止抽帧时清空私有画布像素尺寸 | PKG-AUTO-THUMB-02, CORE-09, CORE-19 | 将私有 canvas 尺寸归入 job 清理;完成、取消、失败及分配重入均有回归,保留已编码 JPEG | 旧红新绿证明保留回调时画布归零,单项清理失败不阻断其他资源;原生取消和完成后 JPEG 仍可解码,原 API/时间公式/类型不变 | M | done |
| PKG-AUTO-THUMB-08 | artplayer-plugin-auto-thumbnail<br>保留旧声明并提供准确异步类型入口 | PKG-AUTO-THUMB-02, ENG-04, ENG-06, CORE-07 | 保留实际 npm 1.1.0 根声明;新增同实现 /runtime 类型、编辑器声明及隔离安装消费者 | 原 Parameters/ReturnType/替代函数不变;准确 Promise 类型正反例、CJS/ESM 条件入口和声明解析通过;不把像素与设备缺口计为通过 | M | done |
| PKG-AUTO-THUMB-09 | artplayer-plugin-auto-thumbnail<br>兼容旧 CommonJS default 与直接工厂调用 | PKG-AUTO-THUMB-02, PKG-AUTO-THUMB-08 | 同一 callable 上的 default 自别名,保留最新根声明并补准确 runtime 别名类型;旧/新实际包入口证据 | 旧红新绿、直接/default/ESM/legacy/global 调用一致;旧根类型提取不变,公开准确类型与实际别名匹配;不关闭抽帧像素和设备缺口 | M | done |
| PKG-AUTO-THUMB-10 | artplayer-plugin-auto-thumbnail<br>为渐进 JPEG 编码建立取消时限与独立资源归属 | PKG-AUTO-THUMB-02, PKG-AUTO-THUMB-07 | 拆分私有 canvas 编码模块,一次一帧的30秒编码时限,完成/失败/切源/销毁取消;迟到和重复回调无副作用 | 受控回调未返回的旧红新绿、正常JPEG和前一预览保持、同步重入/清理失败有回归;真实三浏览器编码/取消通过,公开时间公式与入口不变,首帧风险独立保留 | M | done |
| PKG-AUTO-THUMB-11 | artplayer-plugin-auto-thumbnail<br>保证抽帧事件属性清理异常不截断其他资源释放 | PKG-AUTO-THUMB-02, PKG-AUTO-THUMB-07, PKG-AUTO-THUMB-10 | 独立清除事件属性、抽帧时限和原生帧回调;首个异常保留,过期回调失效,替换任务可继续 | 八个故障注入用例旧红新绿,实际main/legacy抽帧与三浏览器生命周期回归通过;文档和构建同步,首帧及整体资源验收不冒充完成 | M | done |
| PKG-AUTO-THUMB-12 | artplayer-plugin-auto-thumbnail<br>终止隐藏视频元数据永久等待并释放资源 | PKG-AUTO-THUMB-02, CORE-09, CORE-19 | 元数据独立 30 秒期限、迟到回调失效、取消和错误清理、保留前一张可用预览;源码/重建产物及浏览器证据 | 旧红新绿、正常加载与阶段交接通过;实际挂起 HTTP 下销毁/切源/超时清理通过,不改变公开注册或帧时间公式,不关闭既有首帧风险 | M | done |
## 5 包迁移:artplayer-plugin-vtt-thumbnail
@@ -695,3 +696,4 @@
- PKG-HLS-PACK-01: [记录](changes/2026-09-15-PKG-HLS-PACK-01-config.md) [记录](baselines/hls-pack-config-validation.json)
- ENG-LINT-02: [记录](changes/2026-09-15-ENG-LINT-02-clean-checks.md) [记录](baselines/eng-lint02-validation.json)
- SITE-CONSOLE-01: [记录](console-modernization.md) [记录](changes/2026-09-15-SITE-CONSOLE-01-typescript.md) [记录](baselines/site-console01-validation.json)
- PKG-AUTO-THUMB-12: [记录](changes/2026-09-15-PKG-AUTO-THUMB-12-metadata.md) [记录](baselines/auto-thumbnail-metadata-validation.json)
+7
View File
@@ -1,5 +1,12 @@
# 进度与证据
## PKG-AUTO-THUMB-12 元数据加载超时与资源回收
修复隐藏视频在未收到 metadata/error 时永久等待:独立 30 秒期限归 extraction/job 所有,成功/取消后旧期限失效,超时保留上一张可用图。旧 main 的 7 项回归全红;源码 189/189、main/legacy 各 82/82,重建后三引擎各 36/36。首版 WebKit 请求拦截等待失败已保留,最终用真实 HTTP 挂起端点及服务端到达证据验证。期限回调由测试显式触发,不声称等待了真实 30 秒。见[变更](changes/2026-09-15-PKG-AUTO-THUMB-12-metadata.md)与[证据](baselines/auto-thumbnail-metadata-validation.json)。
本任务完成后 200/266;AUTO-THUMB-PIXEL-01、03/04/05 及设备/远端 CI/发布复盘仍未完成。SITE-07 的 Node 路径检查点已提交 d3aa4bbfe,后续来源审查仍开放。下一步继续关闭实际插件兼容/生命周期问题,不重复已定位的本机原生首帧对照。
## SITE-07 Monaco Node 路径来源与完整模块
核实 Node v14.16.0 固定源码及 VS Code 移植。原 notice 已含完整相同条款,新增
+1
View File
@@ -279,3 +279,4 @@
| CONSOLE-SCROLL-01 | resolved / 已复现 | 控制台卸载后仍执行滚动回调 | SITE-CONSOLE-01, SITE-07 |
| CONSOLE-OWNERSHIP-01 | resolved / 已复现 | 多个控制台的全局 hook 所有权冲突 | SITE-CONSOLE-01, SITE-07 |
| CONSOLE-ERROR-01 | resolved / 已复现 | Firefox/WebKit 控制台丢失原生 Error 消息 | SITE-CONSOLE-01, SITE-07 |
| AUTO-THUMB-METADATA-01 | resolved / 已复现 | Private metadata loading can retain its decoder indefinitely without metadata or media errors | PKG-AUTO-THUMB-12 |
+19
View File
@@ -6552,6 +6552,25 @@
"scripts/site-vendor/console/README.md"
],
"resolutionRationale": "Candidate behavior failed on the original bundle (11 failed/1 passed); final browser/editor matrix 63 passed plus shared parser 3 passed across Chromium/Firefox/WebKit. Units, strict types and generation checks pass. Preserves React17, old component return, raw objects, exact CSS and 100 vendor module bodies. Physical BFCache and complete third-party provenance remain separate."
},
{
"id": "AUTO-THUMB-METADATA-01",
"title": "Private metadata loading can retain its decoder indefinitely without metadata or media errors",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"PKG-AUTO-THUMB-12"
],
"evidence": [
"refactor/changes/2026-09-15-PKG-AUTO-THUMB-12-metadata.md",
"refactor/baselines/auto-thumbnail-metadata-validation.json"
],
"compatibleResolution": "Bound only the private metadata phase, dispose through existing ownership, preserve usable previews and public registration timing.",
"closureCriteria": "Prechange failure and candidate unit/artifact/browser evidence cover stale deadlines, no metadata, cancellation, success and decoder cleanup.",
"resolutionEvidence": [
"refactor/baselines/auto-thumbnail-metadata-validation.json"
],
"resolutionRationale": "Seven regressions fail on prechange main; source 189/189, main and legacy 82/82, native main and legacy 36/36 each. Final pending-response tests observe the HTTP server directly. Existing first-frame risk stays open."
}
]
}
+23 -1
View File
@@ -1872,7 +1872,8 @@
],
"dependsOn": [
"PKG-AUTO-THUMB-04",
"CORE-22"
"CORE-22",
"PKG-AUTO-THUMB-12"
],
"status": "todo",
"risk": "H",
@@ -5676,6 +5677,27 @@
"changes/2026-09-15-SITE-CONSOLE-01-typescript.md",
"baselines/site-console01-validation.json"
]
},
{
"id": "PKG-AUTO-THUMB-12",
"phase": "5 包迁移:artplayer-plugin-auto-thumbnail",
"title": "终止隐藏视频元数据永久等待并释放资源",
"scope": [
"artplayer-plugin-auto-thumbnail"
],
"dependsOn": [
"PKG-AUTO-THUMB-02",
"CORE-09",
"CORE-19"
],
"status": "done",
"risk": "M",
"deliverable": "元数据独立 30 秒期限、迟到回调失效、取消和错误清理、保留前一张可用预览;源码/重建产物及浏览器证据",
"acceptance": "旧红新绿、正常加载与阶段交接通过;实际挂起 HTTP 下销毁/切源/超时清理通过,不改变公开注册或帧时间公式,不关闭既有首帧风险",
"evidence": [
"changes/2026-09-15-PKG-AUTO-THUMB-12-metadata.md",
"baselines/auto-thumbnail-metadata-validation.json"
]
}
]
}