1

I am using twilio with twilio-video v beta-2 counting on the master branch of this repohttps://github.com/twilio/video-quickstart-js
I got to display the select media and push the devices into it but when I am trying to updateVideoDevice I got an error

updateVideoDevice error TypeError: track must be a LocalAudioTrack, LocalVideoTrack, LocalDataTrack, or MediaStreamTrack
at Object.INVALID_TYPE (index.js:30952)
at Object.validateLocalTrack (index.js:31469)
at LocalParticipant.unpublishTrack (index.js:17047)
at index.js:17096
at Array.reduce (<anonymous>)
at LocalParticipant.unpublishTracks (index.js:17095)
at index.js:36056

my updateVideoDevice function is as the following

function updateVideoDevice(event) {
const select = event.target;
const localParticipant = room.localParticipant;
if (select.value !== '') {
    Video.createLocalVideoTrack({
        deviceId: { exact: select.value }
    }).then(function(localVideoTrack) {
        const tracks = Array.from(localParticipant.videoTracks.values());
        localParticipant.unpublishTracks(tracks);
        log(localParticipant.identity + " removed track: " + tracks[0].kind);
        detachTracks(tracks);

        localParticipant.publishTrack(localVideoTrack);
        log(localParticipant.identity + " added track: " + localVideoTrack.kind);
        const previewContainer = document.getElementById('local-media');
        attachTracks([localVideoTrack], previewContainer);
    })
    .catch(error => {
        console.error('updateVideoDevice error' ,error);
    });
}
}

can any one explain what I am doing wrong?

Ashraf Hefny
  • 508
  • 1
  • 6
  • 20

1 Answers1

6

Twilio developer evangelist here.

This looks to be a breaking change between Twilio Video JS v1 and v2. In the v2 documentation, calling localParticipant.videoTracks returns a Map of <Track.SID, LocalVideoTrackPublication>. Calling .values() on that map returns an iterator of LocalVideoTrackPublications which is then turned to an array using Array.from.

The issue is that you then pass that array of LocalVideoTrackPublications to localParticipant.unpublishTracks(tracks); which causes the error because unpublishTracks expects an array of LocalTracks not LocalVideoTrackPublications.

You could fix this by mapping over the publications and returning the track property:

const tracks = Array.from(localParticipant.videoTracks.values())
                 .map(publication => publication.track);

Let me know if that helps.

philnash
  • 70,667
  • 10
  • 60
  • 88
  • thanks, this actually works, but only on ios safari browser. it doesn't work on android at all, not on chrome or firefox, the switch detaches and attaches a new track of the same camera?! – Ashraf Hefny Oct 04 '18 at 11:29
  • That sounds like a different problem now. Is there more debugging you can do and then ask a new question? – philnash Oct 04 '18 at 11:32
  • the error is, `NotReadableError: could not start a video source` – Ashraf Hefny Oct 04 '18 at 11:40
  • Have you also raised an issue on my GitHub repo about this? Perhaps we can work on it there instead? – philnash Oct 04 '18 at 14:25