fix: use autoSubscribe:false to prevent LiveKit renegotiation storm on screen share

When a viewer joined while a screen share was active, autoSubscribe:true
caused a subscribe-then-unsubscribe dance for screen share tracks,
triggering cascading renegotiations, MaxListeners warnings, and
negotiation timeouts. Now the SFU starts with no subscriptions and we
explicitly subscribe only to non-screen-share tracks (audio, camera).
Screen shares remain controlled by the watch/unwatch UI flow.
This commit is contained in:
Jannis Braun
2026-02-26 03:02:27 +01:00
parent 61e0bf6fe8
commit 2184ded2c1
+8 -8
View File
@@ -393,10 +393,10 @@ export function useLiveKit() {
newRoom.on(RoomEvent.ParticipantMetadataChanged, guardedUpdate); newRoom.on(RoomEvent.ParticipantMetadataChanged, guardedUpdate);
newRoom.on(RoomEvent.TrackPublished, (publication: RemoteTrackPublication, participant: RemoteParticipant) => { newRoom.on(RoomEvent.TrackPublished, (publication: RemoteTrackPublication, participant: RemoteParticipant) => {
if ( if (
publication.source === Track.Source.ScreenShare || publication.source !== Track.Source.ScreenShare &&
publication.source === Track.Source.ScreenShareAudio publication.source !== Track.Source.ScreenShareAudio
) { ) {
(publication as RemoteTrackPublication).setSubscribed(false); publication.setSubscribed(true);
} }
guardedUpdate(); guardedUpdate();
}); });
@@ -443,7 +443,7 @@ export function useLiveKit() {
useVoiceStore.getState().setIsLiveKitConnected(false); useVoiceStore.getState().setIsLiveKitConnected(false);
}); });
await newRoom.connect(url, token); await newRoom.connect(url, token, { autoSubscribe: false });
if (gen !== _connectGeneration) { destroyRoom(newRoom); return; } if (gen !== _connectGeneration) { destroyRoom(newRoom); return; }
_activeRoom = newRoom; _activeRoom = newRoom;
connectedChannelRef.current = storedId; connectedChannelRef.current = storedId;
@@ -454,14 +454,14 @@ export function useLiveKit() {
updateParticipants(); updateParticipants();
// Unsubscribe from any remote screen share tracks that auto-subscribed during connect // Subscribe to non-screen-share tracks from existing participants (safety net)
newRoom.remoteParticipants.forEach((rp) => { newRoom.remoteParticipants.forEach((rp) => {
rp.trackPublications.forEach((pub) => { rp.trackPublications.forEach((pub) => {
if ( if (
(pub.source === Track.Source.ScreenShare || pub.source === Track.Source.ScreenShareAudio) && pub.source !== Track.Source.ScreenShare &&
pub.isSubscribed pub.source !== Track.Source.ScreenShareAudio
) { ) {
(pub as RemoteTrackPublication).setSubscribed(false); (pub as RemoteTrackPublication).setSubscribed(true);
} }
}); });
}); });