Skip to content

如何打开浏览器摄像头并拍个照

背景

主要通过使用浏览器的 navigator.mediaDevices.getUserMedia() API,开启摄像头并捕获图像。接下来,我们将通过一个简单的示例代码,演示如何在浏览器中打开摄像头并拍摄照片。

一、开启摄像头

首先,使用 navigator.mediaDevices.getUserMedia() 来请求用户的摄像头权限,并获取摄像头的媒体流。如果用户允许访问摄像头,媒体流会被返回,我们可以将其绑定到一个 <video> 元素上进行显示,this.videoObj,让摄像头画面能够显示在页面上。如果失败,代码会处理错误并提供重试机制,确保摄像头能够尽量正常启动。

typescript
/**
 * @description 开启摄像头
 */
private async openCamera() {
  // 请求打开摄像头
  const promise = navigator.mediaDevices.getUserMedia(this.cameraParams);

  promise
    .then((stream) => {
      const cameraNums = stream.getVideoTracks(); // 获取视频流的轨道
      if (cameraNums.length === 0) {
        throw new Error('没有摄像头');
      }

      // 将摄像头流绑定到 video 元素上并开始播放
      this.videoObj.srcObject = stream;
      this.videoObj.play();

      // 打印日志,表示摄像头已成功开启
      info(loggerModules.pages, '开启摄像头完成!开始拍照');
    })
    .catch((err: any) => {
      console.log(err);
      info(loggerModules.pages, '开启摄像头失败, 错误为 ', err, '进行重试,目前重试次数 ' + this.nowCameraTime);

      this.nowCameraTime += 1;
      if (this.nowCameraTime < this.cameraTime) {
         // 3秒后重新尝试开启摄像头
          this.reTakeCameraTimer && clearTimeout(this.reTakeCameraTimer);
          this.reTakeCameraTimer = setTimeout(() => {
            EmitVuexData(listenToVuexChangeMethod.setOpenMyCamera, true);
            const waiting = this.nowCameraTime * 1000;
            this.setOpenMyCamera(true).then(() => {
              setTimeout(() => {
                this.openCamera(); // 递归尝试开启摄像头
              }, waiting);
            });
          }, 3000);
      } else {
        // 如果达到最大重试次数,提示用户未检测到摄像头
        // 未检测到摄像头,打开摄像头,再试一次吧~
        this.close();
      }
    });
}

二、拍照

当摄像头打开并显示在 <video> 元素上后,我们可以通过画布 (<canvas>) 来捕捉视频帧并生成图片。通过调用 canvas.getContext('2d').drawImage() 方法,我们可以将视频中的图像绘制到画布上,并使用 canvas.toDataURL() 获取图像的 Base64 编码,从而可以进行后续的操作,如保存或上传。

typescript
// 拍照
this.canvasObj.getContext('2d')!.drawImage(this.videoObj, 0, 0, videoSize.width, videoSize.height);

// 将画布转为 Base64 图像数据
const src = this.canvasObj.toDataURL('image/jpeg');

// 将 Base64 数据存储在 photoBase64 变量中
this.photoBase64 = src;

总结

通过上述方法,我们能够在浏览器中打开摄像头并拍摄照片。整体流程包括:

  1. 开启摄像头:使用 navigator.mediaDevices.getUserMedia() 请求摄像头权限,获取媒体流并显示在 <video> 元素上。
  2. 拍照:将视频流中的一帧图像绘制到 <canvas> 上,并将图像转换为 Base64 编码。 这个过程适用于 Web 应用中对用户进行拍照的场景,如头像上传、证件照拍摄等。在实现时需要注意用户权限问题,并确保摄像头正常工作。

在 MIT 许可下发布