vue使用navigator.mediaDevices.getUserMedia调用相机功能

前言:

本文将介绍Vue中如何使用navigator.mediaDevices.getUserMedia调用相机功能,实现拍照使用实例,需要的朋友可以参考一下。

注意:Vue 调用本地摄像头实现拍照功能,由于调用摄像头有使用权限,只能在本地运行,线上需用 https 域名才可以使用。

API:
Navigator.mediaDevices.getUserMedia()是一种用于访问流媒体设备(如摄像机或麦克风)的API,它是Navigator.mediaDevices API的一部分。它允许网页访问摄像头和/或麦克风,并捕获实时流视频/音频。

此API采用异步方式,通过返回一个Promise来提供访问流媒体设备的权限。如果用户允许,API将返回一个MediaStream对象,该对象可以进一步用于捕获视频和音频。

具体使用方法:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia


API简单示例:

以下是一个使用Vue.js调用相机功能的示例:

<template>
  <div>
    <video ref="video" autoplay></video>
    <button @click="startCamera">启动相机</button>
    <button @click="stopCamera">关闭相机</button>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      cameraStream: null,
    };
  },
  methods: {
    async startCamera() {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: false,
          video: true,
        });
        this.cameraStream = stream;
        this.$refs.video.srcObject = stream;
      } catch (error) {
        console.error(error);
      }
    },
    stopCamera() {
      if (this.cameraStream) {
        this.cameraStream.getTracks()[0].stop();
        this.cameraStream = null;
      }
    },
  },
};
</script>

在上面的代码中,我们首先在模板中添加一个视频元素,该元素被引用为“video”。我们还添加了两个按钮来启动和关闭相机。

在数据属性中,我们定义了一个名为cameraStream的变量,用于存储从相机捕获的视频流。

在startCamera方法中,我们首先使用await关键字调用navigator.mediaDevices.getUserMedia()方法,传递一个选项对象,其中audio属性设置为false,因为我们不需要捕获音频,video属性设置为true,因为我们需要捕获视频。

如果用户允许访问相机,方法将返回一个MediaStream对象,我们将其存储在cameraStream变量中并将其作为“video”元素的源对象。

在stopCamera方法中,我们首先检查cameraStream是否存在,如果存在,则使用getTracks()[0].stop()方法停止从相机捕获的视频流,并将cameraStream设置为null。
 


拍照功能 

完整示例:

<template>
  <div id="body">
    <div class="body">
      <div class="camera">
        <video ref="video"></video>
        <canvas
          style="display: none"
          id="canvasCamera"
          ref="canvasDom"
        ></canvas>
      </div>
      <div class="img_body">
        <div class="img_content">
          <div class="image" v-for="(item, index) in image" :key="index">
            <img :src="item" alt="" />
          </div>
        </div>
      </div>
      <div>
        <button @click="open">打开相机</button>
        <button @click="takePhoto">拍照</button>
        <button @click="CloseCamera">关闭相机</button>
      </div>
    </div>
  </div>
</template>
 
<script setup>
import { ref, onMounted } from "vue";
import { useRouter } from "vue-router";
const video = ref(null);
const canvasDom = ref(null);
const router = useRouter();
const mediaStreamTrack = ref({});
const video_stream = ref("");
const imgSrc = ref("");
const image = ref([]);
const front = ref(true);
onMounted(() => {
  getCamera();
});
// 打开相机
const open = () => {
  getCamera();
};
const getCamera = () => {
  if (navigator.mediaDevices) {
    navigator.mediaDevices
      .getUserMedia({ video: true })
      .then((stream) => {
        // 摄像头开启成功
        video.value.srcObject = stream;
        video.value.play();
      })
      .catch((err) => {
        console.log(err);
      });
  }
};
// 拍照 绘制图片
const takePhoto = () => {
  // 设置画布大小与摄像大小一致
  canvasDom.value.width = video.value.videoWidth;
  canvasDom.value.height = video.value.videoHeight;
  // 执行画的操作
  canvasDom.value.getContext("2d").drawImage(video.value, 0, 0);
  // 将结果转换为可展示的格式
  imgSrc.value = canvasDom.value.toDataURL("image/webp");
  console.log(imgSrc.value);
  image.value.push(imgSrc.value);
};
// 关闭摄像头
const CloseCamera = () => {
  console.log("关闭摄像头");
  video.value.srcObject.getTracks()[0].stop();
};
</script>
 
 
<style scoped>
#body {
  width: 100%;
  display: flex;
  justify-content: center;
}
button {
  width: 60px;
  height: 25px;
  background-color: rgb(86, 250, 174);
  margin: 5px;
  border-radius: 5px;
}
.camera {
  margin-top: 10px;
}
.camera video {
  border-radius: 5px;
}
.img_body {
  width: 100%;
}
.img_content {
  width: 100%;
  display: flex;
}
.image {
  width: 100px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.image img {
  width: 80px;
  height: 80px;
  border-radius: 5px;
}
</style>

navigator.mediaDevices.getUserMedia切换手机前后摄像头:

前置摄像头:

navigator.mediaDevices
      .getUserMedia({ video: true })
      .then((stream) => {
        // 摄像头开启成功
        video.value.srcObject = stream;
        video.value.play();
      })
      .catch((err) => {
        console.log(err);
      });

后置摄像头: 

navigator.mediaDevices
      .getUserMedia({
        audio: true,
        video: { facingMode: { exact: "environment" } },
      })
      .then((stream) => {
        // 摄像头开启成功
        video.value.srcObject = stream;
        video.value.play();
      })
      .catch((err) => {
        console.log(err);
      });

实现效果:

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个功能,你需要使用Web APIs中的MediaRecorder和getUserMedia函数。MediaRecorder可以录制音频,并将其保存为文件。getUserMedia函数则用于获取用户的音频流,以便MediaRecorder可以录制它。 以下是一个简单的Vue组件,它演示了如何在点击路由时启动录音功能: ```vue <template> <div> <button @click="startRecording">开始录音</button> <button @click="stopRecording">停止录音</button> </div> </template> <script> export default { data() { return { mediaRecorder: null, audioChunks: [], }; }, methods: { startRecording() { navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { this.mediaRecorder = new MediaRecorder(stream); this.mediaRecorder.addEventListener("dataavailable", (event) => { if (event.data.size > 0) { this.audioChunks.push(event.data); } }); this.mediaRecorder.start(); }); }, stopRecording() { this.mediaRecorder.stop(); const audioBlob = new Blob(this.audioChunks); const audioUrl = URL.createObjectURL(audioBlob); const audio = new Audio(audioUrl); audio.play(); }, }, }; </script> ``` 在这个组件中,我们定义了两个按钮:一个用于开始录音,另一个用于停止录音。当用户点击“开始录音”按钮时,我们使用getUserMedia函数获取用户的音频流,并创建一个MediaRecorder对象来录制该流。我们还添加了一个dataavailable事件监听器,以便在录制过程中收集音频数据。当用户点击“停止录音”按钮时,我们停止录制并使用收集到的音频数据创建一个Blob对象,然后将其转换为URL并播放。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值