连接浏览器的摄像头

该代码段展示了如何利用浏览器的媒体设备API获取计算机上的摄像头列表,打开摄像头进行实时预览,并实现拍照功能。通过Promise处理异步操作,用户可以点击拍照,将视频帧绘制到canvas上并转换为base64格式的图片。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

画一个需要展示的框架

 <div class="cameraCont">
 <!--打开摄像头展示-->
      <video
        ref="video"
        width="220"
        height="150"
        autoplay
        class="cameraVideo"
        v-show="row.shadow && !row.addImage"
        @click="photograph"
      ></video>
       <!--拍照成功后的图片-->
      <img  style="width: 100%;" :src="row.addImage" v-if="row.addImage" />
             <!--照片框架-->
      <canvas
        ref="canvas"
        width="220"
        height="150"
        v-show="false"
      ></canvas>
      <el-icon class="colse" v-show="row.addImage" @click="test"
        ><CircleCloseFilled
      /></el-icon>
      <div
        class="camerText"
        @click="photograph"
        v-show="!row.shadow && !row.addImage"
      >
        <el-icon :size="90" color="#8c939d"><Plus /></el-icon>
        <div style="color: #8c939d">点击拍照</div>
      </div>
    </div>
       <!-- 隐藏摄像头 第二个摄像头 -->
    <video
      ref="video1"
      width="220"
      height="150"
      autoplay
      class="cameraVideo"
      v-show="false"
    ></video>
    <canvas ref="canvas1" width="220" height="150" v-show="false"></canvas>
.colse {
  position: absolute;
  top: -4px;
  right: -3px;
}
.cameraCont {
  border: 1px dashed #d8d8d8;
  position: relative;
  width: 220px;
  height: 150px;
}
.camerText {
  text-align: center;
  /* line-height: 180px; */
  position: absolute;
  display: inline-block;
  width: 100%;
  left: 0;
  transform: translate(0, 29%);
}
.cameraWrap {
  display: flex;
  flex-direction: column;
  width: 222px;
}
.photoGraphi {
  text-align: center;
  font-size: 18px;
}
.cameraVideo {
  /* border: 1px solid #d8d8d8; */
}
.take {
  width: 100%;
  height: 60px;
  text-align: center;
  background: #3ba0ff;
  text-align: center;
  line-height: 60px;
  font-size: 18px;
  color: #fff;
  cursor: pointer;
}

获取计算机外设列表 存储摄像头数据

    /** @desc 获取计算机外设列表 储存摄像头数据 */
    const getDevices = () => {
      return new Promise((resolve, reject) => {
        if (
          !navigator.mediaDevices ||
          !navigator.mediaDevices.enumerateDevices
        ) {
          window.alert("不支持 mediaDevices.enumerateDevices()");
        }
        navigator.mediaDevices
          .enumerateDevices()
          .then((devices) => {
            console.log(devices);
            let cameraList = [];
            devices.forEach((device, index) => {
              if (
                device.kind &&
                device.kind === "videoinput" &&
                device.deviceId
              ) {
                cameraList.push({
                  deviceId: device.deviceId,
                });
              }else{
                console.log('未连接到摄像头');
              }
            });
            resolve(cameraList);
          })
          .catch((err) => {
            console.log(err.name + ": " + err.message);
            reject();
          });
      });
    };

调用多个摄像头方法

 // 同步调用摄像头 如果需要调用多个摄像头,需要同步摄像头,如果不需要调用多个摄像头者不需要 这一步
    const camera = async (res) => {
      console.log(res[0], "======>");
      // const data=res.filter(item=>item.kind:'')
      const ress = await initCamera(res[0]);
      proxy.$refs["video"].srcObject = ress;
      proxy.$refs["video"].play();
      const videH = await initCamera(res[1]);
      proxy.$refs["video1"].srcObject = videH;
      proxy.$refs["video1"].play();
    };

打开摄像头

function initCamera(deviceIds) {
    // callback = _callback
    // 打开多个摄像头
    let video = null
    console.log(deviceIds,'=video');
    if (deviceIds) {//打开多个摄像头
        video = { video: { deviceId: deviceIds.deviceId } }
    }else{//如果只要一个摄像头的话用这个就可以了
    
        video = { video:true}
    }

    return new Promise((resolve, reject) => {
        isInit = true
        navigator.mediaDevices.getUserMedia(video).then((success) => {
            videoSrcObject = success
            resolve(success)
        }).catch(error => {
            console.log("打开摄像头失败")
            reject(error)
        })
    })
}

调用摄像头

//调用多个摄像头
 getDevices().then((res) => {
        if (res.length != 0) {
          camera(res);
        }
      });
      // 调用一个摄像头
      getDevices().then((res) => {
          const ress = await initCamera(res[0]);
      proxy.$refs["video"].srcObject = ress;
      proxy.$refs["video"].play();
      }); 

获取拍照后的图片

  const photograph = () => {
      let ctx = proxy.$refs["canvas"].getContext("2d");

      // 把当前视频帧内容渲染到canvas上
      ctx.drawImage(proxy.$refs["video"], 0, 0, 240, 180);

      // 转base64格式、图片格式转换、图片质量压缩
      var imgBase64 = proxy.$refs["canvas"].toDataURL("image/jpeg", 0.7);
      //第二个摄像头
      let ctx1 = proxy.$refs["canvas1"].getContext("2d");
      // // imgUrl = imgBase64;
      // // 把当前视频帧内容渲染到canvas上
      ctx1.drawImage(proxy.$refs["video1"], 0, 0, 240, 180);

      // // 转base64格式、图片格式转换、图片质量压缩
      var imgBase641 = proxy.$refs["canvas1"].toDataURL("image/jpeg", 0.7);
      const data = {
        imgUrl: imgBase64,
        personnelUrl: imgBase641,
      };
      state.videoVisible = false;
      state.videoVisible1 = false;
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值