twilio / twilio-video.js

Twilio’s Programmable Video JavaScript SDK
https://www.twilio.com/docs/video/javascript
Other
567 stars 216 forks source link

Twilio track disable not working as expected #1183

Closed omairshamshir closed 3 years ago

omairshamshir commented 3 years ago

I want to mute my self in a twilio video app. But the problem is that when I use the method mentioned in the documentation

room.localParticipant.videoTracks.forEach((publication) => {
                publication.track.disable();
            });

This hides the video on my screen, but the remote participants can still see my video. Same happens for audio too. When I tried to debug, the tracks received on the remote participant side still have enabled true. How should I properly mute/turn off my video so that it is reflected on remote participant

PikaJoyce commented 3 years ago

Hi @omairshamshir,

Thanks for opening this issue. You will also have to call track.detach() as well to remove the track from the DOM. Please refer to this QuickStart example that demonstrates this. Please let me know if you're still having issues!

Best, Joyce

omairshamshir commented 3 years ago

Thanks for the quick response @PikaJoyce . I tried this too but the disabled event is not fired when I disable the track. I have added listeners on tracks but they are not called when I disable a track

PikaJoyce commented 3 years ago

Hey @omairshamshir,

Can you please share a sample of your code where you are trying to achieve this? Perhaps we can debug this!

Thanks, Joyce

omairshamshir commented 3 years ago

Sure

    const disableTrack = (track) => {
        track.disable()
    }
    const enableTrack = (track) => {
        track.enable()
    }

    const muteMe = () => {
        if (room){
            room.localParticipant.tracks.forEach((publication) => {
                publication.track.disable();
                publication.track.enable(false);
            });
        }
    }

    useEffect(() => {
        if (!(token && roomName)) {
            return
        }

        if (room) {
            room.disconnect()
        }

        setParticipants([])

        const participantConnected = (participant: any) => {
            participant.tracks.forEach(track => {
                track.on('disabled', () => disableTrack(track))
                track.on('enabled', () => enableTrack(track))
            })
            setParticipants((prevParticipants: any[]) => [...prevParticipants, participant]);
        };

        const participantDisconnected = (participant: any) => {
            setParticipants(prevParticipants =>
                prevParticipants.filter(p => p !== participant)
            );
        };

        Video.connect(token, {
            name: roomName
        }).then((room: any) => {
            setRoom(room);
            room.on('participantConnected', participantConnected);
            room.on('participantDisconnected', participantDisconnected);
            room.participants.forEach(participantConnected);
            getApiRoomUsers(room.sid);
        });

        return () => {
            setRoom((currentRoom: any) => {
                if (currentRoom && currentRoom.localParticipant.state === 'connected') {
                    currentRoom.localParticipant.tracks.forEach(function (trackPublication: LocalTrackPublication) {
                        trackPublication.track.stop();
                    });
                    currentRoom.disconnect();
                    return null;
                } else {
                    return currentRoom;
                }
            });
        };
    }, [roomName, token]);
omairshamshir commented 3 years ago

I receive all the other signals like, participantConnected, TrackPublished/TrackUnpublished but not the disabled/enabled one. Dont know what am I doing wrong

PikaJoyce commented 3 years ago

Hey @omairshamshir,

Thank you for getting back to me. I see a few things that may be causing issues.

            room.localParticipant.tracks.forEach((publication) => {
                publication.track.disable();
                publication.track.enable(false);
            });

I believe you should either use publication.track.disable(); or publication.track.enable(false); but not both.

The next:

            participant.tracks.forEach(track => {
                track.on('disabled', () => disableTrack(track))
                track.on('enabled', () => enableTrack(track))
            })

I believe that this may be the cause of the problem as you are listening to a disabled event in order to call disableTrack(). However, because disableTrack() is the function that actually disables the track, you never actually call it as the disabled event is never fired. It should be something to the effect of track.on('disabled', () => updateDisabledTrackUI(track));, where updateUI is a function that shows a track is disabled, you could subsequently utilize track.detach(); here, or use CSS to demonstrate a UI change.

Please check out this example: Helper function

Here is how this example is using this helper function : Helper in use example

With that being said, I also noticed that you are not using the trackSubscribed event which could be another issue. Please refer to the usage section of our documentation here

With that being said, it should look something like this

const participantConnected = (participant) => {
  participant.tracks.forEach(trackSubscribed); // Handle tracks already subscribed
  participant.on('trackSubscribed', trackSubscribed); // Handle track subscriptions that happen after connect
  setParticipants((prevParticipants) => [...prevParticipants, participant]);
};
const trackSubscribed = (track) => {
  track.on('disabled', () => updateDisabledTrackUI(track));
  track.on('enabled', () => updateEnabledTrackUI(track));
};

I hope this helps! Please let me know if this fixes your problem.

Regards, Joyce

PikaJoyce commented 3 years ago

Hi @omairshamshir,

It's been awhile so I will be closing this issue now. I hope those solutions worked for you. If not, feel free to continue the conversation here or open a new issue.

Thank you! Joyce