话不多说 直接上代码
import React, { useState, useRef } from "react";
const Camera = () => {
const videoRef = useRef(null);
const canvasRef = useRef(null);
const [stream, setStream] = useState(null);
// 打开摄像头功能函数
const startCamera = async () => {
try {
// navigator.mediaDevices.getUserMedia()方法请求用户授权访问摄像头,并传入一个包含video: true的参数对象,表示需要访问视频流
// 使用await关键字等待getUserMedia()方法返回一个Promise对象,该对象会在用户授权成功后被解析为一个包含视频流的MediaStream对象。
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
// 将视频流赋值给videoRef.current.srcObject属性,这样就可以将视频流绑定到一个HTML5 <video>元素上,在页面中显示视频。
videoRef.current.srcObject = stream;
// 使用setStream(stream)方法将视频流存储在状态中,以便在其他地方使用。
setStream(stream);
} catch (error) {
// 这里是捕获错误信息打印错误简述
console.error(error, "错误信息");
}
};
// 拍照功能的实现以及生成的图片转换成base64格式的数据
const takePhoto = () => {
// 通过videoRef.current获取到绑定视频流的HTML5 <video>元素。
const video = videoRef.current;
// 通过canvasRef.current获取到一个绑定了<canvas>元素的引用。
const canvas = canvasRef.current;
// 使用canvas.getContext("2d")方法获取到一个2D绘图上下文对象,该对象用于在<canvas>上进行绘图操作。
const context = canvas.getContext("2d");
// 使用context.drawImage()方法将视频帧绘制到<canvas>上,参数依次为视频元素、起始点的x坐标、起始点的y坐标、绘制的宽度和高度
context.drawImage(video, 0, 0, canvas.width, canvas.height);
// 获取拍摄的照片数据
// 使用canvas.toDataURL("image/png")方法获取到绘制后的照片数据,参数指定了输出格式为PNG格式。
const photoData = canvas.toDataURL("image/png");
console.log("Photo data:", photoData);
};
// 关闭摄像头功能
const stopCamera = () => {
// 判断stream是否存在,是不是有摄像头视频流在运行
if (stream) {
// 如果stream存在,则通过stream.getTracks()方法获取到所有的视频轨道(tracks)
const tracks = stream.getTracks();
// 使用forEach()方法遍历每个视频轨道,并调用track.stop()方法停止轨道的使用,即停止摄像头的视频流。
tracks.forEach((track) => track.stop());
// 最后,使用setStream(null)方法将stream设置为null,表示摄像头已停止工作。
setStream(null);
}
};
return (
<div>
<button onClick={startCamera}>打开摄像头</button>
<button onClick={takePhoto}>拍照</button>
<button onClick={stopCamera}>关闭摄像头</button>
<video ref={videoRef} autoPlay />
<canvas ref={canvasRef} style={{ display: "bloxk" }} />
</div>
);
};
export default Camera;