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

目录

前言:

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);});

实现效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/145295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode算法题解|LeetCode435. 无重叠区间、LeetCode763. 划分字母区间、LeetCode56. 合并区间

一、LeetCode435. 无重叠区间 题目链接&#xff1a;435. 无重叠区间 题目描述&#xff1a; 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 示例 1: 输入: intervals [[1,…

深度学习YOLOv5车辆颜色识别检测 - python opencv 计算机竞赛

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0…

linux高级篇基础理论一(详细文档、Apache,网站,MySQL、MySQL备份工具)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xff1a;云计算技…

【笔记 Pytorch】稀疏矩阵、scipy.sparse模块的使用

安装&#xff1a;pip install scipy 描述&#xff1a;就是专门为了解决稀疏矩阵而生。导入模块&#xff1a;from scipy import sparse 优缺点总结 七种矩阵类型描述coo_matrix ★【名称】coordinate format 【优点】    ① 不同稀疏格式间转换效率高(特别是CSR和CSC)  …

如何打包成一个可安装的Android应用程序包

在Android安卓开发中&#xff0c;打包APK通常是指将你的应用程序代码和资源打包成一个可安装的Android安卓应用程序包。以下是打包APK的基本步骤&#xff1a; 配置项目&#xff1a;在Android Studio中&#xff0c;打开你的项目&#xff0c;确保已经配置了正确的项目名称、包名…

读取PDF中指定数据写入EXCEL文件

使用Java读取文件夹中的PDF文件,再读取文件中的指定的字体内容,然后将内容写入到Excel文件中,其中包含一些正则判断,可以忽略,字体以Corbel字体为例。 所需要的maven依赖为: <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel…

VS2022升级之后,原有项目出现异常

最近对VS2022做了升级&#xff0c;发现之前开发的WebApi&#xff08;使用Net5&#xff09;调试运行报错&#xff1a; 根据提示的错误信息也在网上查找了一些资料&#xff0c;均无法正常解决&#xff0c;偶然发现问题是因为VS2022升级之后&#xff0c;不再支持Net5&#xff0c;…

【开源】基于Vue和SpringBoot的固始鹅块销售系统

项目编号&#xff1a; S 060 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S060&#xff0c;文末获取源码。} 项目编号&#xff1a;S060&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固…

论文技巧2

目录 1 找基准模型2 找模块小论文的三个实验怎么做对比试验Sota的挑选对⽐论⽂结果的获取3 消融实验什么是消融实验怎么做消融实验4 实例分析怎么做实例分析小论文必备三张图1 找基准模型 2 找模块 小论文的三个实验 怎么做对比试验

前端项目--命名规范

1. 文件命名&#xff1a; 项目命名&#xff1a;以小写字母命名&#xff0c;中划线分割。如my-project。 目录命名&#xff1a;以小驼峰命名法&#xff0c;除第一个单词之外&#xff0c;其他单词首字母大写。如myDir。JS/TS 文件&#xff1a;以小写字母命名&#xff0c;多个单词…

高性能音乐流媒体服务Diosic

什么是 Diosic ? Diosic 是一个开源的基于网络的音乐收集服务器和流媒体。主要适合需要部署在硬件规格不高的服务器上的用户。Diosic 是使用 Rust 开发的&#xff0c;具有低内存使用率和高性能以及用于流媒体音乐的非常干净的界面。 安装 在群晖上以 Docker 方式安装。 在注…

基于JavaWeb+SpringBoot+Vue医疗器械商城微信小程序系统的设计和实现

基于JavaWebSpringBootVue医疗器械商城微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 摘 要 目前医疗器械行业作为医药行业的一个分支&#xff0c;发展十分迅速。…

ceph集群移除物理节点

1. 概述 ceph分布式存储在生产或者实验环境&#xff0c;经常涉及到物理节点加入或者删除&#xff0c;本文仅对移除物理节点的相关步骤做了操作记录&#xff0c;以方便需要时查阅。 2. 移除物理节点 2.1 out掉相应osd 操作之前通过ceph -s确保整个集群状态是OK的&#xff0c;…

Sql Prompt 10下载安装图文教程

在操作过程中&#xff0c;请暂时关闭你的防病毒软件&#xff0c;以免其误报导致操作失败。 资源 SQL Prompt 10 https://www.aliyundrive.com/s/QuMWkvE1Sv6 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&…

【数据结构】树与二叉树(十六):二叉树的基础操作:插入结点(算法Insert)

文章目录 5.2.1 二叉树二叉树性质引理5.1&#xff1a;二叉树中层数为i的结点至多有 2 i 2^i 2i个&#xff0c;其中 i ≥ 0 i \geq 0 i≥0。引理5.2&#xff1a;高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点&#xff0c;其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…

通讯录实现之进阶版将通讯录数据保存在文件中(完整代码)

我们在之前的博客中已经写过两版通讯录了&#xff1a; 第一版是用C语言实现了通讯录&#xff0c;但是通讯录的存储人数信息是固定的&#xff0c;用完就没有了 感兴趣的可以转到对应博客看一下&#xff0c;附带链接&#xff1a;第一版通讯录 第二版是在第一版的基础上动态开辟…

三大开源向量数据库大比拼

向量数据库具有一系列广泛的好处&#xff0c;特别是在生成式人工智能方面&#xff0c;更具体地说&#xff0c;是在大语言模型&#xff08;LLM&#xff09;方面。这些好处包括先进的索引和精确的相似度搜索&#xff0c;有助于交付强大的先进项目。 本文将对三种开源向量数据库&…

NTP时钟同步服务器(卫星授时服务)在云计算数据机房的应用

NTP时钟同步服务器&#xff08;卫星授时服务&#xff09;在云计算数据机房的应用 NTP时钟同步服务器&#xff08;卫星授时服务&#xff09;在云计算数据机房的应用 1、云计算定义与特点 云计算概念定义 现阶段广为被接受的定义来自于每个国家标准与技术研究院&#xff08;NIS…

shell之xargs命令介绍

shell之xargs命令介绍 参数用法介绍 参数 xargs命令的参数选项包括&#xff1a; -a file&#xff1a;从文件中读入作为stdin。 -e flag&#xff1a;注意有的时候可能会是-E&#xff0c;flag必须是一个以空格分隔的标志&#xff0c;当xargs分析到含有flag这个标志的时候就停止…

虚幻引擎:UEC++中如何解析JSON字符串

一丶解析对象型JSON //解析对象形JSONFString JsonString TEXT("{\"name\":\"二狗\"}");//通过解析工厂创建解析阅读器TSharedRef<TJsonReader<>> Json TJsonReaderFactory<>::Create(JsonString);//创建用于接收的UE的Jso…