Skip to content

fix: hold the warm-up mic stream until the call leaves 'connecting' - #22

Merged
kolchinski merged 1 commit into
mainfrom
fix/hold-warm-mic-through-connect
Jul 29, 2026
Merged

kolchinski merged 1 commit into
mainfrom
fix/hold-warm-mic-through-connect

Conversation

@kolchinski

Copy link
Copy Markdown
Member

Problem

Users hear a gap in the middle of the first ringback ring on the landing demo (later rings are clean). Diagnosis from an instrumented run on thunderphone.com: connect() warms the mic and stops the stream immediately; LiveKit then re-acquires the mic after room connect (~1–2s after click), and that second capture engagement flips the OS output device into communications mode mid-ring — a one-time audible dropout (dramatic on Bluetooth, where the headset switches A2DP→HFP). The ringback element itself never stalls: the landing ringback is a synthesized in-memory WAV, and the only code path touching it is the permanent fade-on-connect.

Fix

Hold the warm-up stream until the widget leaves connecting instead of stopping it immediately. The audio device is then already in communications mode when LiveKit captures, so nothing glitches mid-ring. Released on connect/error/disconnect/unmount, and immediately if the attempt is already over when getUserMedia resolves (late-resolve race).

Trade-offs (reviewed with Alex): mic indicator lights at click and stays on through connection; brief double-capture until connected; on Bluetooth the HFP quality switch moves to click-time (consistent, no gap).

tsc clean, 7/7 vitest, tsup build green. No version bump — leaving CDN release cadence to the usual process; the monorepo will bump its submodule pointer to pick this up for the landing/web bundles.

🤖 Generated with Claude Code

connect() acquires the mic early so the permission prompt overlaps the
session request, but it stopped the stream immediately. That let the OS
drop the audio output device out of communications mode, and LiveKit's
own capture at room connect re-engaged it — an audible output dropout in
the middle of the first ringback ring (a long one on Bluetooth headsets,
which switch profiles A2DP->HFP).

Hold the warm stream until the widget leaves 'connecting' instead: the
device mode stays engaged, so LiveKit's capture is silent. The stream is
released on connect/error/disconnect/unmount, and immediately if the
attempt is already over when getUserMedia resolves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kolchinski
kolchinski requested a review from alec-bell July 29, 2026 23:29
@kolchinski
kolchinski merged commit 5c7c028 into main Jul 29, 2026
1 check passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.2.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants