Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. Walkthrough
ChangesAudio resume behavior
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to Audio can retry native resume after autoplay blocks an earlier attempt, allowing playback to recover on a later user gesture. The updated behavior is covered by audio lifecycle tests and presents no remaining merge-blocking risk. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. A rabbit taps the audio gate Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev/2.0 #3112 +/- ##
===========================================
- Coverage 85.94% 85.75% -0.19%
===========================================
Files 811 811
Lines 94826 94745 -81
Branches 11620 11623 +3
===========================================
- Hits 81497 81249 -248
- Misses 13239 13404 +165
- Partials 90 92 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
GuoLei1990
left a comment
There was a problem hiding this comment.
🫧 尘小沫
结论
阻塞级别:P1。实际 review 动作:REQUEST_CHANGES(未批准)。目标 HEAD:052910f1ed9d2ffa8e411e79795b04e69741aa46。
自动 CR 不替代人工 Reviewer 的合入门禁。
问题
- P1 — 首次 autoplay 的 pending 恢复不会被后续手势重新提交
- 位置:
packages/core/src/audio/AudioManager.ts:34 AudioSource.play()在非 running context 中把自身置为_pendingPlay后只调用一次AudioManager.resume()(AudioSource.ts:150-165);若该原生调用因缺少 activation 而长期 pending,后续play()会被_pendingPlay早退。- 虽然
getContext()已注册 document 的 click/touch fallback,但_resumeAfterInterruption()只有_needsUserGestureResume为 true 才会再次调用resume()(AudioManager.ts:129-137)。这个 flag 目前仅由前后台恢复路径写入(AudioManager.ts:107-119),首次 autoplay 路径没有写入它。因此普通后续手势不会发起新的 nativecontext.resume();删除_resumePromise仅在业务侧恰好再次直接调用AudioManager.resume()时才生效,无法独立修复 PR 所述的 pendingAudioSource场景。 - 请让
AudioManager保持唯一 owner:将“有一次尚未成功、需要手势重试的 resume”收口到现有_needsUserGestureResume,在非 running context 发起 resume 时同步 arm、成功时清除,并继续由_suspendedByCaller/_recovering约束该 fallback。不要在每个AudioSource上再挂监听器、镜像 pending 状态或恢复旧的共享 Promise。 - 补一条用户链路回归:非手势
AudioSource.play()的第一次 resume 保持 pending,随后 dispatch 真实 document gesture,断言 nativeresume()的调用数增加,并在首次 Promise 落定后断言原 AudioSource 开始播放。该用例应在当前提交失败,同时保留“明确 reject 的 one-shot playback 不回放”的既有契约。
- 位置:
架构、熵增与测试治理
- 浏览器
AudioContext是实际运行状态与 activation 的权威 owner;AudioManager应独占全局 resume 意图和手势 fallback,AudioSource只拥有单个播放请求的_pendingPlay。本 PR 删除_resumePromise、其 finally 和对应测试清理,方向上消除了把浏览器调用资格镜像为全局 Promise 的重复 owner;不应把它加回。 - 但目前
AudioSource的 pending 请求与AudioManager的手势重试 flag 没有在首次 autoplay 控制流上接通,形成两段平行状态。应在 Manager 内复用并统一该 flag 的语义,而非把重试责任转移到业务或新增第二条同步路径。 - 更新后的测试覆盖了两次直接
AudioManager.resume()以及既有前后台恢复已 arm flag 的场景,未覆盖上述AudioSource.play() -> pending -> 后续真实手势路径。GitHub CI 的 lint、三平台 build、codecov 与四组 e2e 均通过;codecov/project仅报告整体覆盖率下降,不能证明这条控制流已经闭合。
背景与实际影响
在 Cocos → Galacean 的「跳跃英雄漫威皮肤」中,用户在正常 Chrome 页面多次点击后,背景音乐和音效仍全部无声。独立无头浏览器先前报告播放成功,未能覆盖严格 autoplay 策略。
直接检查用户受影响页面确认:音乐/音效开关均为 1,AudioClip 已加载、volume=1,但多个 AudioSource 的 pendingPlay=true;AudioContext.state=suspended、currentTime=0、playingCount=0,AudioManager 缓存的恢复 Promise 长期未结束。
根因
AudioManager.resume() 使用
_resumePromise ??=合并恢复请求。浏览器可以让缺少用户激活的 AudioContext.resume() 一直 pending,而不是 reject。后续可信点击虽然再次调用 AudioManager.resume(),却只获得旧 Promise,原生 resume() 没有在新的手势调用栈中执行,因而无法利用新的激活机会。在同一受影响标签页,下一次真实点击直接调用原生 resume() 后,context 恢复 running、currentTime 开始推进,旧等待中的播放也恢复。这确认问题位于恢复请求去重,而不是资源、音量或渲染。
修复
_resumePromise缓存,每次显式 resume() 都调用原生 AudioContext.resume()。验证
pnpm b:module通过。pnpm exec vitest run --browser.enabled=true --browser.headless=true tests/src/core/audio:2 文件、36 项通过。--autoplay-policy=document-user-activation-required浏览器复现:先用无 userGesture 的 CDP 调用发起 resume,再真实鼠标点击。旧缓存逻辑仍 suspended/time=0/pendingPlay=true;修复后 running、BGM 播放,输出 RMS=0.00555,页面错误为 0。边界
Summary by CodeRabbit