feat(sounds): receive stream_watch pings + evict watchers on participant disconnect

This commit is contained in:
Jannis Braun
2026-04-28 14:35:14 +02:00
parent 005559d95e
commit 62aa87c737
+13
View File
@@ -32,6 +32,7 @@ import {
handleScreenShareUnpublished, handleScreenShareUnpublished,
resolveNativeOverdrive, resolveNativeOverdrive,
} from '../utils/screenShare'; } from '../utils/screenShare';
import { parseStreamWatch } from '../utils/streamWatchProtocol';
import { getMediaStreamTrack } from '../utils/livekitInternals'; import { getMediaStreamTrack } from '../utils/livekitInternals';
import { deactivate as deactivateHwOverdrive } from '../utils/hwOverdrive'; import { deactivate as deactivateHwOverdrive } from '../utils/hwOverdrive';
@@ -293,6 +294,17 @@ export function useLiveKit() {
}, []); }, []);
const handleDataReceived = useCallback((payload: Uint8Array, participant?: RemoteParticipant) => { const handleDataReceived = useCallback((payload: Uint8Array, participant?: RemoteParticipant) => {
// Try the stream_watch protocol first (typed parser; returns null on non-matches).
if (participant) {
const sw = parseStreamWatch(payload);
if (sw) {
// sw.target is the streamer's bare userId. participant.identity is the
// viewer's full LiveKit identity ("userId:username"); we key by identity
// so ParticipantDisconnected can evict cleanly.
useVoiceStore.getState().recordStreamWatch(sw.target, participant.identity, sw.watching);
return;
}
}
try { try {
const text = new TextDecoder().decode(payload); const text = new TextDecoder().decode(payload);
const msg = JSON.parse(text); const msg = JSON.parse(text);
@@ -532,6 +544,7 @@ export function useLiveKit() {
} }
}); });
newRoom.on(RoomEvent.ParticipantDisconnected, (participant: RemoteParticipant) => { newRoom.on(RoomEvent.ParticipantDisconnected, (participant: RemoteParticipant) => {
useVoiceStore.getState().evictWatcher(participant.identity);
guardedUpdate(); guardedUpdate();
// Clean up stale WS-based voice status for the departed participant // Clean up stale WS-based voice status for the departed participant
const { userId } = parseIdentity(participant.identity); const { userId } = parseIdentity(participant.identity);