【js】获取媒体流实现拍照功能,摄像头切换

<script setup>
	import {
		onMounted,
		reactive,
		ref
	} from 'vue'

	const videoConstraints = reactive({
		width: 500,
		height: 300
	});
	let picArr = reactive([])
	let videoNode = ref(null)
	let show = ref(true)
	let stream = reactive({})
	onMounted(async () => {
	// 获取视频流,并用 video 标签播放
		videoNode.value = document.querySelector('#video');
		stream = await navigator.mediaDevices.getUserMedia({
			audio: true,
			video: videoConstraints
		});
		videoNode.value.srcObject = stream;
		videoNode.value.play();
	})
	// 拍照
	const photo = () => {
		// 通过canvas捕捉video流,生成base64格式图片
		const canvas = document.createElement('canvas');
		const context = canvas.getContext('2d');
		canvas.width = 500;
		canvas.height = 300;
		context.drawImage(videoNode.value, 0, 0, canvas.width, canvas.height);
		// download(canvas.toDataURL('image/jpeg'));
		picArr.push(canvas.toDataURL('image/jpeg'))
		// 下载图片
		// function download(src) {
		// 	if (!src) return;
		// 	const a = document.createElement('a');
		// 	a.setAttribute('download', new Date());
		// 	a.href = src;
		// 	a.click();
		// }
	}
	// 切换镜头
	const switchs = async () => {
		show.value = !show.value
		// enumerateDevices获取所有媒体设备
		const mediaDevices = await navigator.mediaDevices.enumerateDevices();

		// 通过设备实例king属性videoinput,过滤获取摄像头设备
		const videoDevices = mediaDevices.filter(item => item.kind === 'videoinput') || [];
		console.log(mediaDevices, videoDevices, 'videoDevices')

		if (show.value) {
			// 获取前置摄像头
			const videoDeviceId = videoDevices[0].deviceId;
			videoConstraints.deviceId = {
				exact: videoDeviceId
			}
			stream = await navigator.mediaDevices.getUserMedia({
				audio: true,
				video: videoConstraints
			});

		} else {
			// 获取后置摄像头
			if (videoDevices[1]) {
				const videoDeviceId = videoDevices[1].deviceId;
				videoConstraints.deviceId = {
					exact: videoDeviceId
				}
				stream = await navigator.mediaDevices.getUserMedia({
					audio: true,
					video: videoConstraints
				});
			}

		}

		videoNode.value.srcObject = stream;
		videoNode.value.play();

	}
	const close = async () => {
		stream.getTracks().forEach(track => track.stop());
		stream = null;
	}
</script>

<template>
	<video id="video" autoplay playsinline muted></video>
	<button @click="photo">拍照</button>
	<button @click="switchs">{{show?'切换至后镜头':'切换至前镜头'}}</button>
	<button @click="close">关闭摄像头设备
	</button>
	<br />
	<img v-for="(pic,index) in picArr" :src="pic" :key="index" alt="" />
</template>

<style scoped>
	img {
		width: 500px;
	}
</style>

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

语义分割——高分卫星土地覆盖数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

在浏览器执行js脚本的两种方式

fetch请求get 在浏览器执行http请求,可以使用fetch函数; fetch(“url”).then(response => response.text()) .then(data => console.log(JSON.parse(data)[‘status’])) .catch(error => console.error(error)) 直接返回json数据: fetch(“url”).then(response…

深入解析Linux逻辑卷管理器(LVM)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、Linux的起源与发展 2、什么是逻辑卷管理器&…

一觉醒来 AI科技圈发生的大小事儿 05月14日

&#x1f4f3;人类成功实现「蓝牙上天」&#xff01;接收来自600公里外太空信号 一家名为Hubble Network的初创公司成功实现了从地球到太空的蓝牙连接&#xff0c;通过SpaceX将两颗卫星送入轨道&#xff0c;从600公里外的卫星接收信号。他们开发了软件和相控阵天线&#xff0c…

设置linux终端用户输入空闲一段时间后就自动断开(linux终端超时自动断开)

在 /etc/profile 中加入TMOUT变量即可。 在文件的最后追加以下两行 export TMOUT600 # 600秒内无操作就断开。 readonly TMOUT # 将变量设置为只读&#xff0c;防止用户更改如图

好书推荐《智能网联汽车》

一本书打通 SLAM 在智能汽车 / 自动驾驶领域应用 自动驾驶技术已成为当今数字化时代汽车行业的热点话题之一。随着技术的不断成熟&#xff0c;越来越多的车辆采用激光 SLAM&#xff08;即时定位与地图构建&#xff09;和视觉 SLAM 技术&#xff0c;实现更高层次的智能网联汽车…

小果网页---套利系统添加了可以套利模块,提供数据api

最近在小果套利系统里面添加了一下可以套利模块&#xff0c;同时实现了盘中自动更新&#xff0c;30分钟更新一次。给大家提交交易参考&#xff0c;可以套利模块的选择 dfdf[df[申购状态] !暂停申购]dfdf[df[申购限额] !无限额]df[溢价率]df[溢价率].astype(float)df[成交量]df…

“网络安全新纪元:等保2.0的详细解读与实践”

网络安全等级保护基本要求》&#xff08;等保2.0&#xff09;于2019年6月发布&#xff0c;是我国网络安全等级保护制度的一项重要标准。等保2.0主要针对关键信息基础设施的网络安全保护&#xff0c;对数据安全和个人信息保护提出了更高的要求。本文将对等保2.0进行详细解读&…

leetcode-字符串变形-104

题目要求 思路 1.首先根据ASCII的规则&#xff0c;把字符串大小写替换&#xff0c;空格保持不变 2.将整个字符串进行翻转 3.以空格为区间&#xff0c;将区间内的字符串进行翻转&#xff0c;其中翻转的函数reverse() 代码实现 class Solution { public:string trans(string s…

数组定义方法

数组定义方法 "abcdef" 一个字符串 "a" "b" "c" "d" "e" "f" 字符串列表 ("a" "b" "c" "d" "e" &…

洛谷 P3372:线段树 1 ← 分块算法模板(区间更新、区间查询)

【题目来源】https://www.luogu.com.cn/problem/P3372【题目描述】 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; &#xff08;1&#xff09;将某区间每一个数加上 k。 &#xff08;2&#xff09;求出某区间每一个数的和。【输入格式】 第一行…

百面算法工程师 | YOLOv6面试考点原理全解析

本文给大家带来的百面算法工程师是深度学习目标检测YOLOv6面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习目标检测面试问题&#xff0c;并提供参考的回答…

pikachu靶场通关之暴力破解

目录 基于表单的暴力破解 1.打开网站&#xff0c;随便输入一个账号密码&#xff0c;点击登录 2.输入正确的账号密码&#xff0c;点击右上角的提示 3.随便输入账号密码&#xff0c;抓包 4.右键发送到intruder,点击intruder 5.设置攻击位置 6.设置攻击模式&#xff0c;选择…

【十大排序算法】----C语言版插入排序(详细图解)

目录 一&#xff1a;插入排序——原理 二&#xff1a;插入排序——分析 三&#xff1a;插入排序——实现 四&#xff1a;插入排序——效率 一&#xff1a;插入排序——原理 插入排序的原理和基本思想&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序…

Python-VBA函数之旅-zip函数

目录 一、zip函数的常见应用场景 二、zip函数使用注意事项 三、如何用好zip函数&#xff1f; 1、zip函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;https://myelsa1024.blog.csdn.net/ 一、zip函数的常见…

【C语言每日题解】三题:回文检查、刘备 关羽 张飞三人过年放鞭炮、约瑟夫环问题(犹太人死亡游戏)(难度up,推荐)

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f308;感谢大家的阅读、点赞、收藏和关注 &#x1f970;希望大家喜欢我本次的讲解 &#x1f31f;非常推荐最后一道题 &#x1f339; 犹太人死亡游戏&#xff0c;建议观看 &…

Milvus的系统架构

简介 Milvus的构建在许多知名的向量搜索库比如Faiss, HNSW, DiskANN, SCANN等之上的&#xff0c;它针对稠密向量数据集的相似搜索而设计&#xff0c;能支持百万、十亿甚至万亿级别的向量搜索。 Milvus支持数据分片&#xff0c;流式数据插入&#xff0c;动态schema&#xff0c…

【数据结构】队列的实现(链式)

文章目录 队列1.队列的概念及结构概念结构 2.队列的实现&#xff08;链式结构&#xff09;队列定义初始化队列入队出队获取队头元素获取队尾元素销毁队列判断队列是否为空队列有效个数 完整代码&#xff08;包含测试代码&#xff09;Queue.hQueue.ctest.c 队列 1.队列的概念及…

PCIE/PCI设备配置空间

PCI/PCIE Capability PCI/PCIE设备的配置空间记录了PCIE设备的capability支持信息&#xff0c;每个capability定义了一个ID标识&#xff0c;可以通过函数pci_find_capability和pci_find_ext_capability来探测和获取这些配置信息的位置。这些ID定义在文件include/uapi/linux/pc…

vue2+Ts中openLayer绘图工具组件封装

vue2Ts中openLayer绘图工具组件封装 效果&#xff1a; 封装组件代码&#xff1a; <!-- openLayer绘图工具 --> <template><a-button-group v-show"isShow"><a-button v-if"shouldShowButton(point)" click"draw(Point)"…