vue3调用电脑摄像头实现拍照并上传功能

废话不多说直接上代码(代码内有多行注释)

<template>
  <div class="camera-box" style="width: 900px">
    <el-row :gutter="20">
      <el-col :span="12">
        <div style="text-align: center; margin-bottom: 10px">摄像头</div>
        <!-- 这里就是摄像头显示的画面 -->
        <video id="video" width="400" height="300" v-show="videoState"></video>
        <div class="iCenter">
          <el-button type="primary" @click="videoState = !videoState">
            开启摄像头
          </el-button>
        </div>
      </el-col>
      <el-col :span="12">
        <div style="text-align: center; margin-bottom: 10px">拍摄效果</div>
        <!-- 这里是点击拍照显示的图片画面 -->
        <canvas id="canvas" width="400" height="300" style="display: block">
        </canvas>
        <el-button type="primary" @click="takePhone"> 拍照 </el-button>
        <el-button type="primary" @click="takePhoneUpfile"> 保存 </el-button>
      </el-col>
    </el-row>
  </div>
</template>
<script setup>
const blobFile = ref(null)
const canvas = ref(null)
const video = ref(null)
const videoState = ref(false)
const mediaStreamTrack = ref()
onMounted(() => {
  // 摄像头
  video.value = document.getElementById('video')
  //画布
  canvas.value = document.getElementById('canvas')
})

watch(videoState, (newValue, oldValue) => {
  if (newValue) {
    let video = document.querySelector('video')

    // 兼容代码
    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL
    if (navigator.mediaDevices === undefined) {
      navigator.mediaDevices = {}
    }
    if (navigator.mediaDevices.getUserMedia === undefined) {
      navigator.mediaDevices.getUserMedia = function (constraints) {
        var getUserMedia =
          navigator.webkitGetUserMedia ||
          navigator.mozGetUserMedia ||
          navigator.msGetUserMedia
        if (!getUserMedia) {
          return Promise.reject(
            new Error('getUserMedia is not implemented in this browser')
          )
        }
        return new Promise(function (resolve, reject) {
          getUserMedia.call(navigator, constraints, resolve, reject)
        })
      }
    }

    let mediaOpts = {
      audio: false,
      video: true,
      video: { facingMode: 'user' }, // 或者 "environment"
      // video: { width: 1280, height: 720 }
      // video: { facingMode: { exact: "environment" } }// 或者 "user"
    }
    navigator.mediaDevices
      .getUserMedia(mediaOpts)
      .then(function (stream) {
        mediaStreamTrack.value = stream
        video = document.querySelector('video')
        if ('srcObject' in video) {
          video.srcObject = stream
        } else {
          video.src =
            (window.URL && window.URL.createObjectURL(stream)) || stream
        }
        video.play()
      })
      .catch(function (err) {
        console.log(err)
      })
  }
})


// base64转file方式附上
const dataURLtoFile = (dataurl, filename) => {
  var arr = dataurl.split(',')
  var mime = arr[0].match(/:(.*?);/)[1]
  var bstr = atob(arr[1])
  var n = bstr.length
  var u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], filename, { type: mime })
}

const takePhone = () => {
  //点击拍照截图画面
  canvas.value.getContext('2d').drawImage(video.value, 0, 0, 400, 300)
  let dataurl = canvas.value.toDataURL('image/jpeg')
  blobFile.value = dataURLtoFile(dataurl, 'camera.jpg') // 储存响应的图片File
 // tips 此时已经获取到了File类型的数据 可直接向后端传递数据
 // 若需要formData类型的数据,需加上以下代码

 // 创建虚拟表单保存file
  let formData = new FormData()
  formData.append('file', blobFile.value) //图片内容
// tips 此时已经获取到了fromData类型的数据
// console.log(formData.getAll('file'), 123) // 查看数据内容

// 剩下就是html处理
videoState.value = false // 关闭video
  canvas.value.getContext('2d').clearRect(0, 0, 400, 300) //清除画布
  // 关闭摄像头
  mediaStreamTrack.value.getVideoTracks().forEach(function (track) {
    track.stop()
  })
}

// 点击保存
const takePhoneUpfile = () => {
  // 发送api等等
}
</script>
问题1: getUserMedia is not implemented in this browser ( 谷歌的安全策略 )

在网页上输入下列指令:

chrome://flags/#unsafely-treat-insecure-origin-as-secure

出现如下画面:

红框1内输入访问摄像头的网址,红框2选择Enabled

问题2: DOMException: Could not start video source ( 无法启动视频源 ) 

tips: 若正常显示可忽略此项

给 video 配置 muted 属性 使其静音自动播放,与抖音网页版处理方式一致,代码如下:

<video id="video" width="400" height="300" v-show="videoState" muted ></video>

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值