目录
前言:
API:
API简单示例:
拍照功能
实现效果:
前言:
本文将介绍Vue中如何使用navigator.mediaDevices.getUserMedia调用相机功能,实现拍照使用实例,需要的朋友可以参考一下。
注意:
Vue 调用本地摄像头实现拍照功能,由于调用摄像头有使用权限,只能在本地运行,线上需用 https 域名才可以使用。
API:
Navigator.mediaDevices.getUserMedia()是一种用于访问流媒体设备(如摄像机或麦克风)的API,它是Navigator.mediaDevices API的一部分。它允许网页访问摄像头和/或麦克风,并捕获实时流视频/音频。
此API采用异步方式,通过返回一个Promise来提供访问流媒体设备的权限。如果用户允许,API将返回一个MediaStream对象,该对象可以进一步用于捕获视频和音频。
具体使用方法:MediaDevices.getUserMedia() - Web API 接口参考 | MDN (mozilla.org)
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><canvasstyle="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);});