fix(asr): [PKG-ASR-08] keep captured fallback off the audible route

This commit is contained in:
Harvey Zhao committed 2026-09-13 15:40:27 +08:00
1 parent 3e3bed2b93
commit 6d7b9292f8
19 files changed
+5104 -25

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,43 @@
# PKG-ASR-08:阻止捕获回退额外播放声音
子代理复核指出 captureStream 回退不拥有原播放路由,源码却把原始捕获音轨
接到 gain=1 和 destination。主代理用外部原生 AudioContext 先绑定同一 video,
保持其播放图运行,让 Chromium 自然拒绝 ASR 的第二次媒体源绑定并进入回退。
原生测试证明 2.1.0 和 ASR-07 候选都产生额外输出,视频静音后该分支仍非零。
修复前两个候选核心组合在“ASR 输出必须为零”的断言失败,保留报告与 trace。
## 实现与契约
回退改为 `capture source -> recorder -> gain(0) -> destination`,保持 Worklet
处理活跃而不输出声音;直接绑定仍是自己的播放路由,使用 gain=1。暂停、停止、
切源和销毁复用现有归属模型。回调继续收到非零 PCM,不靠静音输入掩盖问题。
不改变媒体元素 muted/volume,不关闭外部 owner context,不修改公开 API、类型或版本。
captureStream 的 PCM 可不受媒体静音/音量影响,而直接路径跟随主 video。文档现在
明确区分两者;此前未限定路径的概括已修正。这个修复阻止额外可听分支,不能解释为
“视频静音后停止识别”;调用方仍使用 stop/pause 控制采集生命周期。
五项新单测由子代理独立编写并先得到全红;主代理集成后,检测出测试 helper 把
Worklet 浅拷贝为两个对象,导致节点清理列表观察到旧连接。已修正 helper 登记真实
对象身份,完整历史/候选测试重新验证,不以删除清理断言通过。
## 原生验证的边界
Firefox 实际允许重复创建 MediaElementAudioSource,两条原生播放分支都有信号,
因此它不会自然进入本回退。这一探测结果与四个失败报告保留,单独登记未闭环的
ASR-FOREIGN-01。Firefox 的回退验证显式强制绑定拒绝,其余 captureStream、轨道、
采样、Worklet 和音频 analyser 全为原生,报告标记 forcedException=true。
不能把受控拒绝说成 Firefox 自动识别外部音频图,也不能改成 skip 后宣称通过。
测试覆盖采集非零、ASR 输出零、原播放图静音、stop 只关闭自己、恢复时新轨道、
切源后旧轨道结束且新源重新输出 PCM、destroy 最终关闭自己的 context。
Firefox close 是异步的,校验使用有界轮询等待 state=closed,保持同步 destroy API。
验证记录见 [捕获回退证据](../baselines/asr-fallback-validation.json)。正常三格式
构建与副本、strict/lint、213 项定向、main/legacy 各 30 项、实际隔离安装声明矩阵
以及 source/main/legacy 原生组均记录确切输入。原生组还重跑直接路径音量和已有
采集生命周期。Windows WebKit 无 WebAudio 的结果仍为能力跳过,不代表 Safari。
本项只关闭“已进入捕获回退后额外输出”的缺陷,ASR-05 的外部双 owner、CORS、
audio-track 组合、更多核心和设备门槛继续保留。离线 demo 与 5.3.0 对照基线也由
ASR-05 独立验收。本次未做整仓 CI、推送或发布;回退会恢复静音仍有额外输出的缺陷。
+7 -4
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 226 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 227 项,范围 22 个包及工作区/示例。
状态:todo 82 / doing 16 / blocked 0 / done 128 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 81 / doing 17 / blocked 0 / done 129 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -17,7 +17,7 @@
| artplayer | 5.4.1 | CORE-01, CORE-02, CORE-03, CORE-04, CORE-05, CORE-06, CORE-07, CORE-08, CORE-09, CORE-10, CORE-11, CORE-12, CORE-13, CORE-14, CORE-15, CORE-16, CORE-17, CORE-18, CORE-19, CORE-20, CORE-21, CORE-23, CORE-22, CORE-24, CORE-25, ENG-12 |
| artplayer-plugin-ads | 2.1.0 | PKG-ADS-01, PKG-ADS-02, PKG-ADS-03, PKG-ADS-04, PKG-ADS-05, PKG-ADS-06 |
| 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 |
| 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 |
| 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 |
| 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 |
@@ -255,9 +255,10 @@
| PKG-ASR-02 | artplayer-plugin-asr<br>建立特有行为与错误测试 | PKG-ASR-01, ENG-03, ENG-05 | PCM/WAV、chunk 时序、回调慢/拒绝、重复初始化与停止 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-ASR-03 | artplayer-plugin-asr<br>整理内部职责与资源 | PKG-ASR-02, CORE-10, CORE-18 | AudioContext/Worklet/Stream 生命周期和背压分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-ASR-04 | artplayer-plugin-asr<br>迁移自有源码和公开类型 | PKG-ASR-03, ENG-04, ENG-06, CORE-07 | 主线程/Worklet/音频 buffer 与异步回调类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
| PKG-ASR-05 | artplayer-plugin-asr<br>验证新旧核心和组合 | PKG-ASR-04, CORE-22, PKG-ASR-07 | 真实 WebAudio 分块、播放暂停/切源/销毁,不引入网络 ASR | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-ASR-05 | artplayer-plugin-asr<br>验证新旧核心和组合 | PKG-ASR-04, CORE-22, PKG-ASR-07, PKG-ASR-08 | 真实 WebAudio 分块、播放暂停/切源/销毁,不引入网络 ASR | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | doing |
| PKG-ASR-06 | artplayer-plugin-asr<br>验证分发并同步文档 | PKG-ASR-05, ENG-07 | asr.js、Worklet 资源、输出格式与声明证据 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
| PKG-ASR-07 | artplayer-plugin-asr<br>修复原生播放音量二次衰减 | PKG-ASR-04 | 移除重复音量应用;保留新旧原生音频振幅对照及正式产物验收 | Chromium/Firefox 两核心和 source/main/legacy 输出音量线性、静音和 stop/restart 正确;旧版平方衰减单独保留;单元/类型/真实安装通过,不代替设备验收 | H | done |
| PKG-ASR-08 | artplayer-plugin-asr<br>修复捕获回退重复播放与静音漏声 | PKG-ASR-07 | 捕获回退静音输出图、非零PCM与外部播放归属;真实红绿证据及产物验证 | 已进入回退后不产生额外输出、静音不漏声、外部播放图不被关闭、stop/restart/换源清理正确;明确Firefox受控拒绝不代表自然选择回退 | H | done |
## 5 包迁移:artplayer-plugin-ads
@@ -531,6 +532,7 @@
- PKG-ASR-02: [记录](changes/2026-09-13-PKG-ASR-02-audio-baseline.md) [记录](baselines/asr-audio-validation.json)
- PKG-ASR-03: [记录](changes/2026-09-13-PKG-ASR-03-audio-ownership.md) [记录](baselines/asr-ownership-validation.json)
- PKG-ASR-04: [记录](changes/2026-09-13-PKG-ASR-04-public-types.md) [记录](baselines/asr-types-validation.json) [记录](baselines/asr-type-diagnostics.json)
- PKG-ASR-05: [记录](baselines/asr-volume-validation.json) [记录](baselines/asr-fallback-validation.json)
- PKG-ADS-01: [记录](baselines/ads-release.json) [记录](baselines/ads-contract.md) [记录](baselines/ads-contract-validation.json) [记录](changes/2026-09-12-PKG-ADS-01-contract.md) [记录](scripts/ads-contract.test.mjs)
- PKG-ADS-02: [记录](changes/2026-09-12-PKG-ADS-02-tests.md) [记录](ads-validation.md) [记录](baselines/ads-validation.json)
- PKG-ADS-03: [记录](changes/2026-09-12-PKG-ADS-03-lifecycle.md) [记录](ads-validation.md) [记录](baselines/ads-lifecycle-validation.json)
@@ -570,3 +572,4 @@
- CORE-25: [记录](changes/2026-09-13-CORE-25-defaults-ssr.md) [记录](baselines/defaults-ssr-validation.json)
- ENG-12: [记录](changes/2026-09-13-ENG-12-library-public.md) [记录](baselines/library-public-validation.json)
- PKG-ASR-07: [记录](changes/2026-09-13-PKG-ASR-07-playback-volume.md) [记录](baselines/asr-volume-validation.json)
- PKG-ASR-08: [记录](changes/2026-09-13-PKG-ASR-08-capture-output.md) [记录](baselines/asr-fallback-validation.json)
+15
View File
@@ -1,5 +1,20 @@
# 进度与证据
## PKG-ASR-08 回退漏声修复完成,ASR-05 继续
独立审查指出 captureStream 回退额外接扬声器;Chromium 原生两个候选核心确实在
视频静音后仍有该分支输出。已改 recorder -> gain(0) 静音 sink,非零PCM与外部
播放图保留;五项先红后绿单测覆盖清理/恢复/换源。最终 source/main/legacy 原生
52过、26能力跳过,含直接音量与既有采集回归;213定向及两产物各30通过,正常
构建、strict/lint、重新隔离安装17配置通过。见[变更](changes/2026-09-13-PKG-ASR-08-capture-output.md)
与[证据](baselines/asr-fallback-validation.json)。
Firefox自然允许重复源绑定;受控拒绝验证了原生回退,但自动外部归属仍登记为
ASR-FOREIGN-01 open。不得把它隐藏成回退通过,也不等于 Safari/设备验收完成。
227项:129 done、17 doing、81 todo;208风险。ASR-05已进入doing,继续真实示例、
相邻稳定核心、CORS与插件组合/设备。子代理负责独立测试和8082示例验收,主代理
整合源码、浏览器与提交;没有推送或发布。
## PKG-ASR-07 原生音量修复完成
ASR-05 原生验证发现旧版与候选都重复应用音量:50% 设置只有约25%输出振幅。
+2
View File
@@ -210,3 +210,5 @@
| ASR-CHUNK-01 | resolved / 已复现 | ASR tick discards underfilled chunks and overrun samples in source | PKG-ASR-02, PKG-ASR-03 |
| ASR-LIFE-01 | resolved / 已复现 | ASR partial initialization, pause resume and stale callback cleanup need controlled evidence | PKG-ASR-02, PKG-ASR-03, PKG-ASR-05 |
| ASR-VOLUME-01 | resolved / 已复现 | ASR applies media volume twice and squares playback amplitude | PKG-ASR-07 |
| ASR-FALLBACK-01 | resolved / 已复现 | Captured fallback produces a second audible route even when the video is muted | PKG-ASR-08 |
| ASR-FOREIGN-01 | open / 已复现 | Firefox permits parallel native media-element owners instead of selecting capture fallback | PKG-ASR-05 |
+35
View File
@@ -4637,6 +4637,41 @@
"refactor/baselines/asr-volume-validation.json"
],
"resolutionRationale": "Native Chromium/Firefox source/main/legacy on published and candidate core pass relative-amplitude assertions. Formal 2.1 baseline retains squared amplitude. The fix does not establish physical device or captured-fallback acceptance."
},
{
"id": "ASR-FALLBACK-01",
"title": "Captured fallback produces a second audible route even when the video is muted",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"PKG-ASR-08"
],
"evidence": [
"test/browser/asr-fallback.spec.js",
"refactor/baselines/asr-fallback-validation.json"
],
"compatibleResolution": "Keep recognition PCM and external media ownership; remove only the extra ASR speaker output.",
"closureCriteria": "Native fallback has zero speaker output and nonzero PCM before/after stop and source change; owned tracks/contexts close without closing the external owner.",
"resolutionEvidence": [
"refactor/changes/2026-09-13-PKG-ASR-08-capture-output.md",
"refactor/baselines/asr-fallback-validation.json"
],
"resolutionRationale": "Native Chromium and controlled-rejection Firefox source/main/legacy with both cores pass. Firefox natural branch selection remains separate ASR-FOREIGN-01."
},
{
"id": "ASR-FOREIGN-01",
"title": "Firefox permits parallel native media-element owners instead of selecting capture fallback",
"confirmation": "reproduced",
"status": "open",
"owners": [
"PKG-ASR-05"
],
"evidence": [
"refactor/baselines/asr-fallback-validation.json",
"refactor/changes/2026-09-13-PKG-ASR-08-capture-output.md"
],
"compatibleResolution": "Establish an explicit compatible ownership contract for external audio graphs without silently changing default direct-path PCM/mute semantics.",
"closureCriteria": "Natural Firefox external-owner integration has no duplicate output or has a documented, validated explicit ownership mode; controlled binding rejection alone cannot close this finding."
}
]
}
+26 -3
View File
@@ -2702,13 +2702,17 @@
"dependsOn": [
"PKG-ASR-04",
"CORE-22",
"PKG-ASR-07"
"PKG-ASR-07",
"PKG-ASR-08"
],
"status": "todo",
"status": "doing",
"risk": "H",
"deliverable": "真实 WebAudio 分块、播放暂停/切源/销毁,不引入网络 ASR",
"acceptance": "最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成",
"evidence": []
"evidence": [
"baselines/asr-volume-validation.json",
"baselines/asr-fallback-validation.json"
]
},
{
"id": "PKG-ASR-06",
@@ -4556,6 +4560,25 @@
"changes/2026-09-13-PKG-ASR-07-playback-volume.md",
"baselines/asr-volume-validation.json"
]
},
{
"id": "PKG-ASR-08",
"phase": "5 包迁移:artplayer-plugin-asr",
"title": "修复捕获回退重复播放与静音漏声",
"scope": [
"artplayer-plugin-asr"
],
"dependsOn": [
"PKG-ASR-07"
],
"status": "done",
"risk": "H",
"deliverable": "捕获回退静音输出图、非零PCM与外部播放归属;真实红绿证据及产物验证",
"acceptance": "已进入回退后不产生额外输出、静音不漏声、外部播放图不被关闭、stop/restart/换源清理正确;明确Firefox受控拒绝不代表自然选择回退",
"evidence": [
"changes/2026-09-13-PKG-ASR-08-capture-output.md",
"baselines/asr-fallback-validation.json"
]
}
]
}