twilio-video.js icon indicating copy to clipboard operation
twilio-video.js copied to clipboard

Camera flipping issue -Twilio version 2.24

Open Ajinkyakadage opened this issue 3 years ago • 1 comments

Problem

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: [1]: https://i.stack.imgur.com/JyHPF.png Attaching screenshot for your reference.

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

Software versions:

Browser(s): Chrome
Operating System: Android (devices that i'm checking & its 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.):

below 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;
}

Ajinkyakadage avatar Sep 12 '22 07:09 Ajinkyakadage

Hi @Ajinkyakadage,

Thank you for opening this issue with us.

A question, on your device, have you tried to test this quickstart example with your device?

Also, could you please try calling restart on your video track instead of stop?

Something like this taken from your snippet:

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

Please let me know!

Thanks, Joyce

PikaJoyce avatar Sep 12 '22 16:09 PikaJoyce

Closing due to inactivity.

manjeshbhargav avatar Sep 28 '22 16:09 manjeshbhargav