js webrtc getUserMedia 切换摄像头失败

319 阅读1分钟

项目开发中有一个用户场景是用户可能有两个以上的摄像头

video需要支持摄像头的切换

getUserMedia设置deviceId进行切换时 有时会无效

看了一下发现设置deviceId 的时候 加一个 exact 就可以

示例源码如下

let constraints = {
  audio: true,
  video: {
    deviceId: { exact: DataStore.cameraDeviceId },
    width:  DataStore.resolutionRatioWidth,
    height: DataStore.resolutionRatioHeight,
  },
};

navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
  let video:any = document.getElementById("visualizerVideo");
  // 设置视频源
  video.srcObject = stream;
  // 视频1加载完元数据后播放
  video.onloadedmetadata = () => {
    video.play()
      .then(() => {
        console.log("Video正在播放  cameraDeviceId",DataStore.cameraDeviceId);
      })
      .catch((err) => {
        console.log("Video出错了:", err);
      });
  };
})
.catch((err) => {
  console.log("err-视频播放", err);
});

查询gpt还建议将之前的stream停掉,说这样也会导致切换摄像头失败,但是我没有用到,如果失败的话你们可以试试

示例源码如下

async function getVideoStream(deviceId) {
  if (window.currentStream) {
    window.currentStream.getTracks().forEach(track => track.stop());
  }

  const constraints = {
    video: {
      deviceId: deviceId ? { exact: deviceId } : undefined
    }
  };

  try {
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    // 将流绑定到 video 元素上
    const videoElement = document.querySelector('video');
    videoElement.srcObject = stream;
    // 保存以便以后停止
    window.currentStream = stream;
  } catch (err) {
    console.error("获取视频流时出错", err);
  }
}

async function listDevices() {
  try {
    const devices = await navigator.mediaDevices.enumerateDevices();
    devices.forEach(device => {
      if (device.kind === 'videoinput') {
        console.log(`Device ID: ${device.deviceId}, Label: ${device.label}`);
      }
    });
  } catch (err) {
    console.error("列举设备时出错", err);
  }
}

// 列出所有视频输入设备并尝试第一个设备
listDevices().then(() => getVideoStream(null));