Huge incoming traffic
Select which package(s) are affected
@livekit/components-react
Describe the bug
Hi! Thank you for your project.
My case: I have a conference with 100 participants (all have their camera on), but only 25 participants are shown in the grid.
What I'm expecting
I receive incoming video traffic from 100 participants as 25 participants.
What happens instead
I receive incoming video traffic from 100 participants as 100 participants even though I don't render anything (just LiveKitRoom with no children).
I reproduced it even on https://meet.livekit.io
Workaround 1
If I render a VideoTrack for each participant and then unmount it and leave only 25 VideoTracks, I will receive the correct incoming traffic.
Workaround 2 (not the best solution, I have a problem on older versions of Safari)
import * as React from 'react';
import {
useTracks,
TrackReferenceOrPlaceholder,
} from '@livekit/components-react';
import { RemoteTrackPublication, Track } from 'livekit-client';
type Props = {
visibleTrackRefs: TrackReferenceOrPlaceholder[];
};
/** Used to prevent unnecessary traffic */
export const useVideoSubscription = ({ visibleTrackRefs }: Props) => {
const rawTrackReferences = useTracks([
{ source: Track.Source.Camera, withPlaceholder: true },
{ source: Track.Source.ScreenShare, withPlaceholder: false },
]);
// Create visible track sids set.
const visibleSids = React.useMemo(
() =>
new Set<string | undefined>(
visibleTrackRefs.map(trackRef => {
// Use getTrackPublications to find even unsubscribed track
// because if publication is unsubscribed trackRef.publication is undefined.
const videoPub = trackRef.participant
.getTrackPublications()
.find(pub => pub.kind === 'video');
return videoPub?.trackSid;
}),
),
[visibleTrackRefs],
);
// It's required to unsubscribe here to avoid unnecessary traffic.
React.useEffect(() => {
rawTrackReferences.forEach(trackRef => {
// Use getTrackPublications to find even unsubscribed track
// because if publication is unsubscribed trackRef.publication is undefined.
const videoPub = trackRef.participant
.getTrackPublications()
.find(pub => pub.kind === 'video');
if (!(videoPub instanceof RemoteTrackPublication)) {
return;
}
if (visibleSids.has(videoPub.trackSid)) {
if (!videoPub.isSubscribed) {
videoPub.setSubscribed(true);
}
} else if (videoPub.isSubscribed) {
videoPub.setSubscribed(false);
}
});
}, [rawTrackReferences, visibleSids]);
return null;
};
Suggestion
Add an optional parameter to LiveKitRoom to initially unsubscribe from every publication and only subscribe to it when VideoTrack is rendered.
Reproduction
import { LiveKitRoom } from '@livekit/components-react';
...
return (
<LiveKitRoom
token={session?.token}
serverUrl={session?.url}
connect={isConnect}
onError={onConnectionError}
options={ROOM_OPTIONS}
/>
);
Logs
System Info
Any platform and browser.
"@livekit/components-react": "^2.2.1",
"livekit-client": "^2.1.3",
I checked the newest versions, same problem.
Severity
serious, but I can work around it
Additional Information
No response