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,一经查实,立即删除!

相关文章

深度学习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;云计算技…

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 找模块 小论文的三个实验 怎么做对比试验

高性能音乐流媒体服务Diosic

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

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

基于JavaWebSpringBootVue医疗器械商城微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 摘 要 目前医疗器械行业作为医药行业的一个分支&#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;有助于交付强大的先进项目。 本文将对三种开源向量数据库&…

“开源 vs. 闭源:大模型的未来发展趋势预测“——探讨大模型未来的发展方向

文章目录 每日一句正能量前言什么是大模型的开源与闭源开源与闭源的定义和特点开源的意义开源和闭源的优劣势比较不同的大模型企业&#xff0c;开源、闭源的策略不尽相同。企业在开发垂类模型时选择开源还是闭源大模型开源vs 闭源&#xff1a;两者并非选择题后记 每日一句正能量…

【网络】TCP协议的相关实验

TCP协议的相关实验 一、理解listen的第二个参数1、实验现象2、TCP 半连接队列和全连接队列3、关于listen的第二个参数的一些问题4、SYN洪水Ⅰ、什么是SYN洪水攻击Ⅱ、如何解决SYN洪水攻击&#xff1f; 二、使用Wireshark分析TCP通信流程 一、理解listen的第二个参数 在编写TCP…

有什么进销存软件,比较适合零售行业日常开单要求及库存记录?

本文将为大家总结一下对于进销存软件要求&#xff1a; 基础功能&#xff1a;可以日常开单、退换货处理、出入库进阶功能&#xff1a;电脑、手机数据同步&#xff0c;保障数据安全&#xff0c;可进行数据分析 其实无论是小型创业公司&#xff0c;还是一家大型企业&#xff0c;…

MathType2024最新word公式编辑器

使用word进行论文编写时&#xff0c;常需要使用公式编辑器&#xff0c;但有些word中并没有公式编辑器&#xff0c;这时应该怎么办呢&#xff1f;本文将围绕word里没有公式编辑器怎么办&#xff0c;word中的公式编辑器怎么用的内容进行介绍。 一、word里没有公式编辑器怎么办 …

现货黄金职业交易员怎么使用技术分析?

职业的交易员每天要处理很多不同的信息&#xff0c;其中只一部分是涉及技术指标。在这一部分处理技术分析的时间里&#xff0c;只能再分出少之又少的时间给技术指标。那职业交易员会利用做技术指标做什么呢&#xff1f;下面我们就来讨论一下。 识别行情。技术指标的主要作用就是…

Digicert证书:您的网络安全守护神

在当今数字化的世界中&#xff0c;网络安全已经成为每一个企业和个人必须面对的问题。而Digicert品牌证书&#xff0c;就是您网络安全的最佳选择。它不仅具有强大的安全性和稳定性&#xff0c;还能广泛应用于各种场景&#xff0c;为您提供全方位的保护。 首先&#xff0c;我们要…

【Linux】Ubuntu16.04配置repo

Ubuntu16.04配置repo失败 在学习韦东山Linux嵌入式开发过程中&#xff0c;使用repo获取内核及工具链: git clone https://e.coding.net/codebug8/repo.gitmkdir -p 100ask_imx6ull-sdk && cd 100ask_imx6ull-sdk../repo/repo init -u https://gitee.com/weidongshan/m…

万能在线答题考试小程序源码系统 既能刷题 又能考试 带完整的搭建教程

现如今&#xff0c;线上学习和考试已经成为一种趋势。近年来&#xff0c;移动端的普及以及微信小程序的兴起&#xff0c;使得在线答题考试系统变得更加便捷和高效。今天罗峰就来给大家介绍一款万能在线答题考试小程序源码系统&#xff0c;既能刷题&#xff0c;又能考试&#xf…

Tosca 2023x 新功能介绍

Tosca/Structure的功能增强 热优化功能增强 在优化过程中&#xff0c;支持将对流边界条件转移至新创建的表面&#xff0c;方便更加真实地模拟传热行为。支持恒定传导。多物理场优化能力增强。通过使用多个输入面板对热和结构荷载进行分别输入&#xff0c;以支持同时对热和结构…