Skip to content

fix: prevent stale camera and microphone streams during call reconnection - #104

Open
Danidfra wants to merge 4 commits into
lnbits:mainfrom
Danidfra:feat/call-reliability
Open

Danidfra wants to merge 4 commits into
lnbits:mainfrom
Danidfra:feat/call-reliability

Conversation

@Danidfra

@Danidfra Danidfra commented Oct 21, 2026 •

Copy link
Copy Markdown

Summary

  • Privacy fix: in group calls, turning the camera off now stops every peer's camera clone, including links that are down or reconnecting. Before, a reconnecting peer kept its clone live and, once the link returned, resent the camera and announced it as on.
  • Microphone sync: microphone switches now reach peers whose link is down, busy, or not yet confirmed, so a reconnecting peer never resends the old input. Camera and microphone controls changed while a link is down are applied on every reconnect.
  • Privacy fix after quality changes: a camera turned off while a peer link was restarting its camera for a new video quality (for example when screen sharing starts) is now applied once that restart finishes, instead of leaving the peer receiving the camera clone.
  • The call overlay no longer ticks or re-enumerates devices when it doesn't need to.

Testing

Automated

  • 8 new unit tests for room and peer media sync; 6 of the original 7 fail against main, and the new quality-refresh test fails without its fix.
  • Rebased onto current main (a4db9c6), keeping its room video-quality and camera-recovery changes.
  • Browser call tests, typecheck and build pass. 6 existing live-suite failures also occur on main.

Manual (Chrome and Brave, separate accounts)

  • Two-way audio and mute/unmute worked.
  • A call stayed stable for 10+ minutes.
  • A call stayed active with Brave minimized.
  • A ~18-second network interruption showed Reconnecting and recovered.
  • Three-person group call: video reached both other participants.
  • Turning off A's camera while B was offline kept it off after B reconnected.

Known limitation

Video frames queued before camera-off may arrive late after a brief network interruption. No frames captured after camera-off are sent.

… idle

The overlay stays mounted for the app's lifetime. Its one-second clock ran
even with no call, and the device list was re-enumerated on every call
store update because the store adapter rebuilds its object each time.

Run the clock only while a direct call shows a duration, and enumerate
devices only when the local stream appears or is replaced; the existing
devicechange listener still covers hardware changes.
…k is down

Each room peer link sends its own clone of the room's camera and
microphone. Turning the camera off or switching microphone only reached
peers in the active phase, and stopping the room's track does not stop
its clones. A reconnecting peer kept a live camera clone (the camera
light stayed on) and, once the link returned, resent it and announced
the camera as on. A switched microphone left the reconnecting peer on the
old input.

A peer runtime now turns its camera off and switches microphone while
its link is down, signalling only when the link is ready. The room drops
the camera clone of any link that is down and reapplies its microphone
and camera controls on every activation, not just the first, and after
a video quality refresh that may have skipped a change.

Microphone mute already reached every link; it is now covered by tests.
… old microphone

A peer link skips media changes while it is busy, so turning the camera off
while a reconnecting peer was still turning it on left that peer's camera
clone recording. A microphone switch skipped the same way, or made before an
outgoing peer confirmed the call, left that peer sending the old input.

Room peer sync now re-checks after each awaited change and replaces clones of
inputs the room no longer uses, and runs again after room camera and
microphone changes. A microphone can be switched before the peer confirms.
Room video quality is now refreshed when screen sharing starts or stops and
when the camera changes, and a refresh requested while a link is busy runs
later from that link's own timer. A camera turned off while such a refresh
restarted a link's camera was skipped, so that peer kept receiving the
camera clone.

Each peer link now reports a completed refresh and the room realigns that
link's camera and microphone. A failed refresh still leaves its camera
disabled.
@Danidfra
Danidfra force-pushed the feat/call-reliability branch from ca3e839 to 7b70b4e Compare October 23, 2026 13:17

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant