Camera flipping issue -Twilio version 2.24

Viewed 26

The flip camera doesn't work on devices where they have more than 2 video inputs. In the first load, the video appears but when the flip camera button is clicked the application throws an error.

Expected behavior:

The camera should be flipped (environment)

Actual behavior:

It throws the following error:

error : call to getusermedia failed domexception could not start video source

Software versions:

  • Browser(s): Chrome
  • Operating System: Android (devices that I'm checking & it's not working eq. Samsung M31, Redmi note 11 T, One Plus 7T)
  • twilio-video.js: 2.24.0
  • Third-party libraries (e.g., Angular, nodejs, etc.):

Code used to start twilio stream

async startTwilioStream(twilioToken: string, localVideo: ElementRef, remoteVideo: ElementRef): Promise<void> {
  console.log('startTwilioStream');
  this.localVideoElement = localVideo;
  this.remoteVideoElement = remoteVideo;
  await this.startLocalVideo(this.localVideoElement);
  this.connectOptions = {
    video: false,
    audio: false,
    tracks: [this.localAudioTrack, this.localVideoTrack],
    audioConstraints: {
      mandatory: {
        googAutoGainControl: false,
      },
    },
    region: 'in1',
    preferredAudioCodecs: ['opus'],
    preferredVideoCodecs: ['H264'],
  };

  connect(twilioToken, this.connectOptions).then((twilioRoom: any) => {
    console.log('twilioRoom.localParticipant ================== ', twilioRoom.localParticipant);
    setTimeout(() => {
      if (this.remoteVideoElement?.nativeElement) {
        this.remoteVideoElement.nativeElement.muted = false;
      }
    }, 5000);

    this.twilioRoom = twilioRoom; 

    console.log('this.twilioRoom vvvv', this.twilioRoom);

    twilioRoom.localParticipant.setNetworkQualityConfiguration({
      local: 2,
      remote: 1,
    });

    // flip.addEventListener('change', this.updateVideoDevice);

    twilioRoom.on('participantConnected', participant => {
      console.log('participant Connected===============', participant);
      participant.tracks.forEach((publication) => {
        console.log('publication', publication);
        if (publication.isSubscribed) {
          const track = publication.track;
          this.attachTracks([track]);
        }
      });
      this.twilioRoom = twilioRoom;
    });



    twilioRoom.on('participantDisconnected', participant => {
      console.log('participantDisconnected', participant);
      console.log('SOME PARTICIPANT DISCONNECTED');
      if ((participant.identity === 'agent-screen-share' && this.serviceUserType !== 'agent') || (participant.identity === 'consumer-screen-share' && this.serviceUserType !== 'consumer')) {
        this.changeDetectionEmitter.emit('remoteScreenShareStopped');
        this.isRemoteScreenShareOn = false;
      } else if (participant.identity !== 'agent-screen-share' && participant.identity !== 'consumer-screen-share') {
        console.log('real participant dced');
        this.remoteMediaStream = null;
        this.detachTracks(participant);
        this.isRemoteVideoOn = false;
      }
      this.twilioRoom = twilioRoom;
    });

    twilioRoom.participants.forEach((participant) => {
      participant.tracks.forEach((publication) => {
        if (publication.track) {
          const track = publication.track;
          this.attachTracks([track]);
        }
      });

      participant.on('trackSubscribed', (track) => {
        console.log('trackSubscribed', track);
        this.attachTracks([track]);
      });
      this.twilioRoom = twilioRoom;
    });

    twilioRoom.on('trackAdded', (track, participant) => {
      console.log('trackAdded', track, participant);
      this.attachTracks([track]);
      this.twilioRoom = twilioRoom;
    });

    // When a Participant adds a Track, attach it to the DOM.
    twilioRoom.on('trackSubscribed', (track, err, participant) => {
      console.log('trackSubscribed', track);
      this.sendLoaderStatus('ringing');
      if ((participant.identity === 'agent-screen-share' && this.serviceUserType !== 'agent') || (participant.identity === 'consumer-screen-share' && this.serviceUserType !== 'consumer')) {
        this.attachScreenShareTrack([track]);
      } else if (participant.identity === 'agent-screen-share' || participant.identity === 'consumer-screen-share') {

      } else {
        this.attachTracks([track]);
      }
      this.twilioRoom = twilioRoom;
    });

    // When a Participant removes a Track, detach it from the DOM.
    twilioRoom.on('trackRemoved', (track, participant) => {
      console.log('trackRemoved', track);
      this.detachTracks([track]);
      this.twilioRoom = twilioRoom;
    });

  }, err => {
  });
}

Start local video and local audio track

async startLocalVideo(localVideo: ElementRef, deviceId = 'user'): Promise<void> {
  this.localVideoElement = localVideo;

  const localAudioTrack = await createLocalAudioTrack({
    audio: true
  });

  const localVideoTrack = await createLocalVideoTrack({
    facingMode: deviceId
  });

  this.localAudioTrack = localAudioTrack;
  this.localVideoTrack = localVideoTrack;
  if (!this.localAudioTrack) {
    alert('Audio source not found, do you hava a mic connected ?');
  }
  if (!this.localVideoTrack) {
    alert('Video source not found, do you hava a videocam connected ?');
  }
  console.log('this.localVideoTrack to check', this.localVideoTrack);
  this.localDisplayMediaStream = new MediaStream();
  console.log('this.localVideoTrack.mediaStreamTrack to check', this.localVideoTrack.mediaStreamTrack);
  this.localDisplayMediaStream.addTrack(this.localVideoTrack.mediaStreamTrack);
  console.log('this.localDisplayMediaStream to check', this.localDisplayMediaStream);
  this.localVideoElement.nativeElement.srcObject = this.localDisplayMediaStream;
}

Flip event listener calls on the click of switch button

const flip = document.querySelector('#flip');
flip.addEventListener('click', (e) => {
  if (this.facingMode == "user") {
    this.facingMode = "environment";
    this.twilioService.switch(this.facingMode)
  } else {
    this.facingMode = "user";
    this.twilioService.switch(this.facingMode)
  }
});

Switch camera function calls in flip event listener

async switch(facingMode) {

  console.log(this.localDisplayMediaStream);

  if (this.localDisplayMediaStream) {
    this.localDisplayMediaStream.getTracks().forEach(track => {
      track.stop();
    });

    if (this.twilioRoom) {
      await this.twilioRoom.localParticipant.videoTracks.forEach((track: any) => {
        console.log('track', track);
        track.track.stop();
      });
    }
  }

  const localVideoTrack = await createLocalVideoTrack({
    facingMode: facingMode
  });
  this.localVideoTrack = localVideoTrack;
  this.localDisplayMediaStream = new MediaStream();
  this.localDisplayMediaStream.addTrack(this.localVideoTrack.mediaStreamTrack);
  this.localVideoElement.nativeElement.srcObject = this.localDisplayMediaStream;
}
0 Answers
Related