From e7b72bb583f1d77cec24ff9ee2d9616f6cb118b1 Mon Sep 17 00:00:00 2001 From: Nilton Neto Date: Tue, 30 Jul 2024 12:45:44 -0300 Subject: [PATCH 1/2] logic to add support for instances created AFTER 'connect' --- src/hooks/useWebAvatar.tsx | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/hooks/useWebAvatar.tsx b/src/hooks/useWebAvatar.tsx index 04f1833..2155340 100644 --- a/src/hooks/useWebAvatar.tsx +++ b/src/hooks/useWebAvatar.tsx @@ -1,4 +1,4 @@ -import { RoomEvent, Track } from 'livekit-client'; +import { ConnectionState, RoomEvent, Track } from 'livekit-client'; import { useEffect, useRef, useState } from 'react'; import type { RemoteTrack } from 'livekit-client'; @@ -15,14 +15,26 @@ export function useWebAvatar() { if (!room) { return; } + if (room.state === ConnectionState.Connected) { + // support for instances created AFTER "connect" by making sure the new video and audio elements are attached + room.remoteParticipants.forEach((participant) => { + participant.trackPublications.forEach(({ track }) => { + handleTrackSubscribed(track!); + }); + }); + } function handleTrackSubscribed(track: RemoteTrack) { - if (track.kind === Track.Kind.Video) { + if ( + track.kind === Track.Kind.Video && + !track.attachedElements.includes(videoRef.current!) + ) { track.attach(videoRef.current!); } else if ( audioRef && track.kind === Track.Kind.Audio && - room?.canPlaybackAudio + room?.canPlaybackAudio && + !track.attachedElements.includes(audioRef.current!) ) { track.attach(audioRef.current!); } @@ -39,14 +51,20 @@ export function useWebAvatar() { room .on(RoomEvent.TrackSubscribed, handleTrackSubscribed) .on(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed) - .on(RoomEvent.AudioPlaybackStatusChanged, handleAudioPlaybackStatusChanged) + .on( + RoomEvent.AudioPlaybackStatusChanged, + handleAudioPlaybackStatusChanged, + ); return () => { room .off(RoomEvent.TrackSubscribed, handleTrackSubscribed) .off(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed) - .off(RoomEvent.AudioPlaybackStatusChanged, handleAudioPlaybackStatusChanged); - } + .off( + RoomEvent.AudioPlaybackStatusChanged, + handleAudioPlaybackStatusChanged, + ); + }; }, [room]); return { ...avatar, videoRef, audioRef, canPlaybackAudio }; From 6f66ce7494079a0c9e7add9b85a61617f74d30e4 Mon Sep 17 00:00:00 2001 From: Nilton Neto Date: Tue, 30 Jul 2024 15:00:38 -0300 Subject: [PATCH 2/2] chore: PR review suggestion to move the logic further down the function --- src/hooks/useWebAvatar.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hooks/useWebAvatar.tsx b/src/hooks/useWebAvatar.tsx index 2155340..13775a7 100644 --- a/src/hooks/useWebAvatar.tsx +++ b/src/hooks/useWebAvatar.tsx @@ -15,14 +15,6 @@ export function useWebAvatar() { if (!room) { return; } - if (room.state === ConnectionState.Connected) { - // support for instances created AFTER "connect" by making sure the new video and audio elements are attached - room.remoteParticipants.forEach((participant) => { - participant.trackPublications.forEach(({ track }) => { - handleTrackSubscribed(track!); - }); - }); - } function handleTrackSubscribed(track: RemoteTrack) { if ( @@ -56,6 +48,15 @@ export function useWebAvatar() { handleAudioPlaybackStatusChanged, ); + if (room.state === ConnectionState.Connected) { + // support for instances created AFTER "connect" by making sure the new video and audio elements are attached + room.remoteParticipants.forEach((participant) => { + participant.trackPublications.forEach(({ track }) => { + handleTrackSubscribed(track!); + }); + }); + } + return () => { room .off(RoomEvent.TrackSubscribed, handleTrackSubscribed)