# N-021 Sequencer 与音频 状态:`BLOCKED`(strip schema、真实 Main reader、确定性时间编辑、长媒体有界索引/seek/cache、 三类实际 runtime codec probe、source/decode-bound 首帧 proxy cache、三类迟到结果 revision gate、最终编码 server-export 路由、实时 AudioContext 恢复门和媒体故障生命周期闭环已落地; Main 写回、完整媒体解码/渲染、音频波形、A/V sync、实际混音和真正服务端编码 job 仍未实现) ## 已验证切片 1. N-021-A(部分):版本化 `SequencerTimelineIR` 覆盖 Scene、Movie、Image、Sound、 Effect、Meta strip、channel、帧范围、source range、speed、proxy 和依赖;strip、 image、dependency 数量以及帧范围都有预算,资源路径经过项目沙箱规范化。 2. N-021-B(部分):`MOVE`、`TRIM`、`SPLIT` 以 revision 乐观并发控制作用于内存 timeline;编辑后重新解析依赖和预算,锁定 strip 与 stale revision 会拒绝。 3. N-021-B/C:`sequencerSourceFrame` 对 speed、trim、split 使用确定性的 source-frame 映射,避免左右片段复用越界源帧。 4. N-021-B/C(部分):`resolveSequencerFrame` 在切分边界解析当前顶层 strip、source frame 与依赖;META 覆盖的子 strip 和 inactive dependency 不会泄漏到渲染帧。 5. N-021-C/D(门):运行时 inventory 只报告 WebCodecs/HTMLMedia 需要精确 probe;旧的 MIME 集合不能作为 READY receipt,本地编码固定为 `BLOCKED`。 6. N-021-A(部分):Blender 5.2 `Scene.ed/Editing.seqbase` 读取 Scene、Movie、Image、Sound、 Meta 和协议支持的 Effect;显示范围由持久 `start/startofs/endofs/len` 计算,保留 channel、 mute/lock、相对媒体路径、24/1.001 FPS 和 effect input stable ID。绝对路径、未知类型、 坏依赖或超预算将 Scene sequencer 标为 `BLOCKED`。 7. N-021-B(transition 子集):CROSS/GAMMA_CROSS 可按半开显示区间确定性解析 `[0,1)` 进度, 保持 Blender `input1,input2` 顺序,并为两个活动依赖返回各自 source frame;越界、依赖缺失、 muted 输入和非 cross effect 拒绝。 8. 桌面 Blender 5.2 fixture 经 WASM/Worker 后,在真实 CROSS 中间帧得到 factor 0.5;两个单张 Image strip 的 source range 为 `0..1`,显示 20 帧仍固定到 source frame 1,不伪造成图像序列。 9. V1 long-media 门使用本地 261-byte PNG 与 16,044-byte WAV 建立 1,000,000 帧、10,001 strips 时间线;1,024-frame bucket index 仅产生 11,914 references,不按总帧数展开 JSON。 起点/中点/终点、64 次确定性随机 seek、连续 scrub 最新请求胜出和 index/seek/decode 取消均通过。 10. preview cache 使用 20 KiB 显式 byte budget/LRU,随机 seek 发生真实淘汰且当前 audio/image key 仍 resident;timeline/current frame/asset hashes 作为内容寻址 session manifest 写入 OPFS,终止 StorageWorker 与 media Worker 后在 frame 765432 恢复。session SHA-256 固定为 `d2e7e3c5ed9ae4fda6fe358cebb474f5774f1d2037dff3df9b6dfde9e0bebd2d`。 11. 上述 V1 长媒体门只放行 fixture 的 IMAGE/SOUND 原始本地资源读取,不声称 WebCodecs MOVIE seek、waveform/proxy 生成或最终编码完成;local encoding 仍结构化阻断。 12. M11-09 runtime codec probe:schema 1 request/result 绑定 IMAGE/SOUND/MOVIE family、规范 MIME、 byte length 和 source SHA-256,且不接收 source path/扩展名字段。Chromium 用 ImageBitmap 解码 8×8 PNG,用固定 48 kHz OfflineAudioContext 解码 1 秒 WAV,用 HTMLMedia 加载、seek 并绘制 16×16 两帧 H.264 MP4;三类均 READY。错误扩展名不影响结果,损坏 bytes、hash drift、MIME/family 和 backend 伪造均返回 `SEQUENCER_CODEC_UNSUPPORTED`。 13. M11-10 proxy cache:schema 1 identity 绑定 MOVIE source family/MIME/bytes/SHA-256、当前 READY HTMLMedia receipt、SRGB8/STRAIGHT RGBA8 profile 和 source frame;payload 再独立绑定 byte length/SHA-256。Chromium 从真实 H.264 初始 decoded frame 生成 8x8/256-byte proxy, 一帧预算 LRU 发生确定性淘汰,content-addressed payload/manifest 经新 Storage Worker 重开 后复验。source、decode receipt、identity 或 payload 漂移均在消费前稳定阻断。 14. M11-11 media revision gate:SEEK/SCRUB/DECODE 使用同一 schema 1 request,绑定 timeline ID/revision、单调 request revision、operation 和 frame;completed result 必须逐字段回显并绑定 source frame/payload hash。Chromium 中旧 SEEK 晚于新 SCRUB 返回、真实 H.264 DECODE 跨 timeline replacement 返回及伪造 result 全部在 publish/cache callback 前成为 `STALE/REVISION_CONFLICT`;只有当前 SCRUB 与当前 DECODE 发布。 15. M11-12 final export route:schema 1 将真实 Main timeline ID/revision、source `.blend` SHA-256、帧范围/帧率、分辨率和 container/video/audio codec 绑定到 settings/request SHA-256。 无 endpoint 时返回 `SERVER_EXPORT/BLOCKED/SEQUENCER_EXPORT_SERVER_UNAVAILABLE`;有 endpoint 时只返回 `SERVER_EXPORT_REQUIRED`。Chromium 中注入和实际探测到的 `VideoEncoder` 都不能 把 `localEncoding` 从 `BLOCKED` 提升为本地完成。 16. M11-13 audio session recovery:schema 1 分开报告 `UNAVAILABLE/SUSPENDED/RUNNING/CLOSED` context 与 `BLOCKED/SILENT/ENABLED` output, revision 随 initialize/mute/resume/suspend/close 单调推进。Chromium 在真实用户手势内创建 `AudioContext`,通过 suspend、mute、muted resume、unmute、二次 suspend/resume 和 close; mute 将 gain 归零,unmute 恢复 0.75,close 再归零并断开节点。API/构造器缺失与 resume failure 分别稳定返回 `SEQUENCER_AUDIO_DEVICE_UNAVAILABLE` 和 `SEQUENCER_AUDIO_RESUME_FAILED`,不会误报输出启用。 17. M11-14 Media fault lifecycle:真实 H.264 先通过 HTMLMedia probe 并解出 8x8 RGBA8 frame; 预取消 proxy decode 返回 `SEQUENCER_CANCELLED` 且不发布 payload。低于一帧的 cache budget 返回 `SEQUENCER_BUDGET_EXCEEDED` 且 entries/bytes 保持 0;首会话 clear 返回正数释放字节, 重建会话后 source/decode/profile identity 和 payload SHA-256 保持不变。 ## 仍然阻断 - N-021-A/B:Main strip 写回、非 CROSS transition/modifier 完整参数、undo/redo 和 save/reopen; 基础真实 reader 与 CROSS/GAMMA_CROSS 帧描述已完成。 - N-021-C:M11-09/10/11/13 完成三类短 fixture 的初始实际解码门、MOVIE 初始帧 RGBA8 proxy cache identity、迟到结果 publish/cache gate 和实时 AudioContext 生命周期;WebCodecs 帧精确 seek/decode、多帧 proxy、音频 waveform、A/V sync、实际混音、丢帧和长媒体损坏恢复仍阻断。 - N-021-D:M11-12 已冻结最终编码的 server-export 路由与请求 identity;真正服务端 Blender encode job、进度/取消、混音和输出结果校验仍阻断。 - N-021-E:V1 有界 Chromium/OPFS 长媒体门已完成;完整桌面/Chromium 解码/渲染 golden 仍阻断。 ## 验收 ```bash WEB_TEST_PORT=5321 npm --prefix web run test:e2e -- --grep "N-021 sequencer" npm --prefix web run test:sequencer-main-reader npm --prefix web run test:long-media-performance WEB_TEST_PORT=5570 npm --prefix web run test:sequencer-codec-probe WEB_TEST_PORT=5573 npm --prefix web run test:sequencer-media-cache WEB_TEST_PORT=5576 npm --prefix web run test:sequencer-media-revision WEB_TEST_PORT=5579 npm --prefix web run test:sequencer-final-export WEB_TEST_PORT=5586 npm --prefix web run test:sequencer-audio-recovery WEB_TEST_PORT=5592 npm --prefix web run test:render-compositor-media-recovery ```