Skip to content

fix(calls): スピーカー追加・交代時の音声断と再生再開要求を修正 - #83

Merged
mattyatea merged 1 commit into
developfrom
codex/fix-calls-speaker-audio
Oct 9, 2026
Merged

mattyatea merged 1 commit into
developfrom
codex/fix-calls-speaker-audio

Conversation

@mattyatea

Copy link
Copy Markdown

What

Callsのスピーカー追加・交代時に音声を維持する修正です。

  • 購読終了時に受信トラックをstop()せず、次のpublicationへの受信口の再利用を妨げないようにしました。
  • 古いトラックのended通知が、置き換え後の音声・映像を削除しないようにしました。
  • 受信音声をWeb Audioで混ぜ、一つの音声要素と出力ストリームを通話中維持します。話者追加時のnew Audio()/play()をなくし、ユーザー別・画面共有別の音量と出力デバイス選択を保ちました。

Why

「スピーカーが増えると誰かが聞こえなくなる」「iPhoneで話者追加ごとに音声再生の再開が必要になる」という報告への対応です。受信トラックの停止と古いended通知による削除は、修正前ソースで回帰テストが失敗することを確認しました。

iPhoneの症状は、非同期の受信処理で再生先を毎回新しく作り、要素単位の再生許可を引き継げない経路と整合します。実機ログはないため、報告された全事例の原因を断定していません。

Additional info (optional)

原因・再現・検証レポート

flowchart LR
    A["既存話者の音声"] --> GA["個別音量"]
    B["追加話者の音声"] --> GB["個別音量"]
    GA --> M["固定の出力ストリーム"]
    GB --> M
    M --> E["一つの音声要素"]
    R["再開操作"] --> C["AudioContext.resume() と play()"]
    C --> E
Loading

検証は通話関連unit test 3ファイル118件、frontendのvue-tsc、変更実装3ファイルのESLint、SPDX、locale safetyが成功しています。実ブラウザのスモークではChromium 153.0.8010.12で二人の信号が混ざること、一人の音量をゼロにしても他方が残ること、全音源を外した後の追加でも同じ出力が再生を続けることを確認しました。スモークの再実行コードも含めています。

iPhone/Safari実機とCloudflare SFU経由の複数端末E2Eは未実施です。初回の再生許可やOSによる中断後には、再開操作が必要になり得ます。DB・API・localeの変更はありません。CHANGELOGは明示依頼がないため変更せず、候補をレポートに記載しました。関連Issueは検索で見つからず、今回の報告を起点にしています。

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

Copilot AI balanced review requested due to automatic review settings October 7, 2026 15:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: Type4ny-Project/Misskey/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 429f4400-7b55-4be9-801b-1702eeb383da
📥 Commits

Reviewing files that changed from the base of the PR and between 5d23778 and bf8db91.

📒 Files selected for processing (7)
  • docs/calls-speaker-audio-investigation.md
  • packages/frontend/src/utility/calls-audio-output.ts
  • packages/frontend/src/utility/calls-media.ts
  • packages/frontend/src/utility/calls-session.ts
  • packages/frontend/test/calls-audio-output.smoke.mjs
  • packages/frontend/test/unit/calls-media-controller.test.ts
  • packages/frontend/test/unit/calls-session.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Callsの音声出力を、個別の音声要素から共有出力コントローラーへ移行しました。受信トラックの再利用、トラック置換時の削除判定、音量設定、再生再開、終了処理を更新し、関連するテストと調査報告を追加しました。

Changes

通話音声出力

Layer / File(s) Summary
受信トラックの再利用
packages/frontend/src/utility/calls-media.ts, packages/frontend/test/unit/calls-media-controller.test.ts
公開が解除されても受信トラックを停止しないよう変更しました。同じ受信トラックを次の話者に再利用するテストを追加しました。
共有音声出力の実装
packages/frontend/src/utility/calls-audio-output.ts, packages/frontend/test/calls-audio-output.smoke.mjs
CallsAudioOutputが入力ごとのゲインを適用し、複数トラックを単一の出力ストリームへ接続します。Chromiumのスモークテストでミックス、個別ミュート、全入力削除後の再追加、終了処理を検証します。
セッションへの音声出力統合
packages/frontend/src/utility/calls-session.ts, packages/frontend/test/unit/calls-session.test.ts, docs/calls-speaker-audio-investigation.md
セッションが共有出力を使って音声の追加、音量と出力デバイスの設定、再生再開、終了を行います。古いトラックの終了時に置換後の公開データを削除しない処理と関連テストを追加しました。調査報告には、テスト結果と未実施の実機確認を記載しています。

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant CallsSession
  participant CallsAudioOutput
  participant AudioContext
  participant HTMLAudioElement
  CallsSession->>CallsAudioOutput: add(id, track)
  CallsAudioOutput->>AudioContext: 入力ソースとゲインを出力ストリームへ接続
  CallsSession->>CallsAudioOutput: play()
  CallsAudioOutput->>AudioContext: resume()
  CallsAudioOutput->>HTMLAudioElement: 出力ストリームを設定してplay()
Loading

Merge Risk: ⚪ Minimal · up to bf8db

The audio changes are ready for normal merge checks; Safari and multi-device testing remain useful follow-up validation.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 6 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed タイトルは、話者の追加・交代時の音声断と再生再開要求の修正という主要な変更を具体的に示しています。
Description check ✅ Passed 説明にはWhat、Why、Additional info、Checklistの各項目があり、変更内容、背景、検証結果、未実施の確認事項を具体的に記載しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 6 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/frontend/src/utility/calls-audio-output.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

packages/frontend/src/utility/calls-media.ts

ESLint skipped: the matched ESLint configuration already failed (missing-dependency).

packages/frontend/src/utility/calls-session.ts

ESLint skipped: the matched ESLint configuration already failed (missing-dependency).

  • 3 others

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.

❤️ Share

話者の声が集まります
音量はゲインで調整します
ひとつの出力に音が重なります
再開の合図でまた響きます
終わると音声資源を閉じます

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

🖥 Frontend Diagnostics Report

(No significant changes)

View details

Requests by resource type
Type Requests Encoded bytes
Base Head Δ Base Head Δ
Document 2 2 0 34 KB 34 KB 0 B
Script 152 152 0 2.4 MB 2.4 MB $\color{orange}{\text{+1.8 KB}}$
Stylesheet 63 63 0 320 KB 320 KB 0 B
Fetch 28 28 0 47 KB 47 KB 0 B
Image 9 9 0 238 KB 238 KB 0 B
Font 2 2 0 129 KB 129 KB 0 B
Other 9 9 0 421 KB 421 KB $\color{orange}{\text{+3 B}}$
V8 heap snapshot statistics
Metric @ Base @ Head Δ MAD
$\color{gray}{\rule{8pt}{8pt}}$ Total 12 MB
± 11 KB
12 MB
± 65 KB
$\text{+56 KB}$
$\text{+0.5\%}$
66 KB
$\color{orange}{\rule{8pt}{8pt}}$ Code 3 MB 3 MB $\text{+688 B}$ 2.4 KB
$\color{red}{\rule{8pt}{8pt}}$ Strings 1.3 MB 1.3 MB $\text{+96 B}$ 32 B
$\color{cyan}{\rule{8pt}{8pt}}$ JS arrays 122 KB 122 KB 0 B 0 B
$\color{green}{\rule{8pt}{8pt}}$ Typed arrays 0 B 0 B 0 B 0 B
$\color{yellow}{\rule{8pt}{8pt}}$ System objects 0 B 0 B 0 B 0 B
$\color{violet}{\rule{8pt}{8pt}}$ Other JS objs 2.2 MB 2.2 MB $\text{+712 B}$ 119 B
$\color{pink}{\rule{8pt}{8pt}}$ Other non-JS objs 5.5 MB 5.5 MB $\text{+50 KB}$ 64 KB

Download representative heap snapshot: base / head

📦 Bundle Stats

Chunk size diff (0 updated, 0 added, 0 removed)
Chunk Base Head Δ Δ (%)
(total) 6.1 MB 6.1 MB $\text{+912 B}$ $\text{+0\%}$
(other generated chunks) 2.3 MB 2.3 MB $\text{+912 B}$ $\text{+0\%}$
Startup chunk size (0 updated, 0 added, 0 removed)
Chunk Base Head Δ Δ (%)
(total) 956 KB 957 KB $\text{+912 B}$ $\text{+0.1\%}$
(other generated chunks) 882 KB 883 KB $\text{+912 B}$ $\color{orange}{\text{+0.1\%}}$
(other) 74 KB 74 KB 0 B 0%

Startup chunks are the Vite entry for src/_boot_.ts and its static imports.

Bundles Modules Entries Imports Size
Static Dynamic Rendered Gzip Brotli
Base 509 3,030 22 11,273 366 11 MB 3 MB 2.6 MB
Head 509 3,031 22 11,274 366 11 MB 3 MB 2.6 MB
Δ 0 $\color{orange}{\text{+1}}$ 0 $\color{orange}{\text{+1}}$ 0 $\color{orange}{\text{+1.5 KB}}$ $\text{+563 B}$ $\text{+446 B}$
Δ (%) 0% $\text{+0\%}$ 0% $\text{+0\%}$ 0% $\text{+0\%}$ $\text{+0\%}$ $\text{+0\%}$

Open treemap HTML

@mattyatea
mattyatea merged commit 9d4a393 into develop Oct 9, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants