WebRTC通话期间无法在移动Chrome或Safari中更改相机

时间:2019-04-23 09:36:24

标签: android webrtc

我使用navigator.mediaDevices.enumerateDevices检索所有视频设备(element.kind === 'videoinput')的列表,然后调用navigator.mediaDevices.getUserMedia(constraints)来旋转视频设备(使用deviceId作为约束)。在Windows Chrome / Firefox上一切正常,但是在android手机(尝试使用Android 8/9的三星,华硕,华为)上,此呼叫对于带有NotReadableError的后置摄像头失败/无法启动视频源(对于Chrome )或AbortError /启动视频失败(对于Firefox)。 奇怪的是,相同的代码在iOS / Safari中也可以正常工作。 同样,仅当浏览器中存在WebRTC调用时,才会发生这种情况。如果没有通话,我可以选择任何视频设备。 另外,如果我先选择后置摄像头并尝试建立呼叫,那么它将无法正常工作,我会收到类似的错误消息。 我知道这牵强附会,但也许有人遇到过相同/相似的问题? 所有浏览器版本都是最新的。

[更新-代码段和日志]

switchCamera() {
try {
  if (this.localStream) {
    const tracks = this.localStream.getTracks();
    console.log('switchCamera stopping this.localStream tracks', tracks);
    tracks.forEach((track: MediaStreamTrack) => {
      console.log('switchCamera stopping track', track);
      track.stop();
    });
    console.log('switchCamera stop stream');
  }

  const constraints = {
    audio: true,
    video: { facingMode: this.faceCamera ? 'environment' : 'face' }
  };
  this.faceCamera = !this.faceCamera;
  console.log('switchCamera constraints: ', constraints);
  navigator.mediaDevices.getUserMedia(constraints)
    .then(stream => {
      console.log('getUserMedia:', stream);
      this.logText('got stream');

      this.localVideo.srcObject = stream;

      const videoTracks = stream.getVideoTracks();
      const audioTracks = stream.getAudioTracks();
      console.log('videoTracks', videoTracks);
      if (videoTracks.length > 0) {
        console.log(`Using video device: ${videoTracks[0].label}`);
      }

      const videoTrack = videoTracks[0];
      const audioTrack = audioTracks[0];

      console.log('Replacing track for pc', videoTrack, audioTrack);

      const pc = this.session.sessionDescriptionHandler.peerConnection;

      const videoSender = pc.getSenders().find(s => {
        return s.track && s.track.kind === videoTrack.kind;
      });
      const audioSender = pc.getSenders().find(s => {
        return s.track && s.track.kind === audioTrack.kind;
      });

      if (videoSender) {
        console.log('videoSender.replaceTrack', videoTrack);
        videoSender.replaceTrack(videoTrack);
      }
      if (audioSender) {
        console.log('audioSender.replaceTrack', audioTrack);
        audioSender.replaceTrack(audioTrack);
      }
    })
    .catch(e => {
      console.log('getUserMedia error:', e.name, e.code, e.message);
    });
} catch (e) {
  window.alert(e);
}

}

这是Chrome远程设备调试的日志:

enter image description here

错误是“ NotReadableError”,“无法启动视频源”,这意味着Chrome无法获得基础设备句柄... 再次,Safari / iOS可以正常工作...

2 个答案:

答案 0 :(得分:0)

对于移动设备,有一种专门的方法可以在前后摄像头之间进行选择。

VideoFacingMode-https://www.w3.org/TR/mediacapture-streams/#dom-videofacingmodeenum

TL; DR

window.navigator.mediaDevices.enumerateDevices().then(devices => {
    if (devices.filter(device => device.kind === 'videoinput').length > 1) {
        navigator.mediaDevices.getUserMedia({video: {facingMode: 'user' /*'environment'*/}}).then(console.log.bind(this))
    }   
})

它适用于移动Safari,Chrome和FF。

  

注意

     

请记住,在调用   再次将getUserMediavideo一起使用,否则,您将获得一个   

答案 1 :(得分:0)

好吧,所以我将范围缩小为在navigator.mediaDevices.getUserMedia()(这是Angular应用程序)中调用ngInit()。 即使删除.then()处理程序函数中的所有代码,效果也相同。 仅删除此呼叫可以解决问题。 目前尚不确定为什么会这样的行为,将对其进行更彻底的调查并进行更新。