Add stopMicrophoneOnMute option to release the microphone while muted - #987
Open
adrian-niculescu wants to merge 1 commit into
Open
Add stopMicrophoneOnMute option to release the microphone while muted#987adrian-niculescu wants to merge 1 commit into
adrian-niculescu wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: fe05d1c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
adrian-niculescu
force-pushed
the
stop-microphone-on-mute
branch
2 times, most recently
from
July 28, 2026 19:25
a3b9bd8 to
e60d2f6
Compare
Also fixed local track publication jobs leaking on full reconnect.
adrian-niculescu
force-pushed
the
stop-microphone-on-mute
branch
from
July 28, 2026 19:30
e60d2f6 to
fe05d1c
Compare
adrian-niculescu
marked this pull request as ready for review
July 28, 2026 19:38
adrian-niculescu
requested review from
MaxHeimbrock,
davidliu and
xianshijing-lk
as code owners
July 28, 2026 19:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #375.
Android equivalent of the web SDK's
stopMicTrackOnMute, added asLocalAudioTrackOptions.stopMicrophoneOnMute.Two reasons to want it:
mediaTrack.enabled = false). The ADM keepsAudioRecordopen, so the OS microphone-in-use indicator stays lit for as long as the track is published. An indicator burning next to a muted mic is a privacy concern.Unpublishing and republishing the track does release the mic, but it leaks native memory on the audio path and churns track history on the server.
Leak measurements
Measured on LiveKit Android SDK 2.27.0, on a Pixel 6a (bluejay) running Android 17 beta (build
CP41.260701.005, API 37, 2026-07-05 security patch).On a two-party call with the camera off, toggling the microphone 50 times through unpublish/republish retained about 11.7 MB of native heap, roughly 0.23 MB per cycle, against a baseline noise band of 0.9 MB.
Three details point at retention rather than an artifact. There was no decay: five samples over the following 60 seconds read 104.1, 104.2, 103.6, 104.2, 104.2 MB.
Native Heap Sizegrew from 125.5 to 134.0 MB, so the arena was extended to satisfy live allocations, which fragmentation slack does not do.Graphicsis unchanged, so no part of the video pipeline is involved.The same test driving the camera instead fell back inside its baseline band within 16 seconds, which lines up with #971 fixing the video path by stopping the transceiver and disposing the
VideoSourceon unpublish. The audio path has no counterpart to that fix, and the measured version already contains it.That split looks deliberate rather than accidental. Reviewing the libwebrtc side in webrtc-sdk/webrtc#194, the transceiver teardown crash is described as "not even reproducible without audio", and the equivalent SDK-side fix then landed for video only, described as "restricting to video tracks (where it really matters), due to reproducible crashes in the audio stack". So the audio-side leak is known and was left in place rather than risk the audio path.
The web SDK's approach has no direct port here, since capture is owned by the ADM shared across the
PeerConnectionFactoryrather than by the track. Muting the publication instead stops capture throughPeerConnection.setAudioRecording(false), which flipsrecording_enabled_on the factory-scopedAudioStateand stops the ADM, releasingAudioRecordwith no renegotiation and no change to the publication.AudioState::AddSendingStreamchecks the same flag, so a reconnect or republish won't silently reopen the mic while muted. Capture restarts on unmute.Recording state is reconciled from the current publications on mute changes (including server-initiated ones), publish, unpublish, and
applyOptionschanges while published, with the desired state computed on the RTC thread so rapid toggles converge. Capture is shared by every local audio track, so it is only stopped while all published audio tracks are muted. Apps that don't opt in get no behavior change; a test assertssetAudioRecordingis never called for them.Also fixed:
prepareForFullReconnect()clears the publications, so theunpublishTrack()calls inrepublishTracks()could never find and cancel the publication jobs, leaking each old audio publication's feature collector on every full reconnect and leaving it sending feature updates for a stale track sid. The reconciliation added here rides those same jobs, which is how it surfaced. The jobs are now cancelled when preparing for the reconnect.Tests cover mute/unmute release and restore, zero native calls without opt-in, unpublish while muted,
applyOptionstoggling the flag in both directions while muted, and the all-tracks-muted rule with two simultaneous audio publications.