基本上,我正在尝试在React的上下文中使用https://github.com/cozmo/jsQR。但是,canvas仅在安装组件时捕获视频流。如何在整个过程中使用react canvas连续流式传输视频?
import React, { Component } from "react";
import jsQR from "jsqr";
class WebcamStream extends Component {
constructor(props) {
super(props);
this.videoTag = React.createRef();
this.canvas = React.createRef();
this.tick = this.tick.bind(this);
}
componentDidMount() {
// getting access to webcam
navigator.mediaDevices
.getUserMedia({ video: { facingMode: "environment" } })
.then(stream => {
const video = this.videoTag.current;
video.srcObject = stream;
video.setAttribute("playsinline", true);
video.play();
requestAnimationFrame(this.tick);
});
}
componentDidUpdate() {}
drawLine(begin, end, color) {
const canvasElement = this.canvas.current;
const canvas = canvasElement.getContext("2d");
canvas.beginPath();
canvas.moveTo(begin.x, begin.y);
canvas.lineTo(end.x, end.y);
canvas.lineWidth = 4;
canvas.strokeStyle = color;
canvas.stroke();
}
tick() {
const video = this.videoTag.current;
const checkVideoState = setInterval(() => {
if (video.readyState === video.HAVE_ENOUGH_DATA) {
clearInterval(checkVideoState);
const canvasElement = this.canvas.current;
const canvas = canvasElement.getContext("2d");
canvasElement.height = video.videoHeight;
canvasElement.width = video.videoWidth;
canvas.drawImage(
video,
0,
0,
canvasElement.width,
canvasElement.height
);
let imageData = canvas.getImageData(
0,
0,
canvasElement.width,
canvasElement.height
);
console.log(imageData);
var code = jsQR(imageData.data, imageData.width, imageData.height);
if (code) {
console.log("CODE");
this.drawLine(
code.location.topLeftCorner,
code.location.topRightCorner,
"#FF3B58"
);
this.drawLine(
code.location.topRightCorner,
code.location.bottomRightCorner,
"#FF3B58"
);
this.drawLine(
code.location.bottomRightCorner,
code.location.bottomLeftCorner,
"#FF3B58"
);
this.drawLine(
code.location.bottomLeftCorner,
code.location.topLeftCorner,
"#FF3B58"
);
} else {
}
}
}, 3000);
}
render() {
return (
<div>
<video ref={this.videoTag} width="400" height="400" autoPlay />
<canvas ref={this.canvas} />
</div>
);
}
}
export default WebcamStream;
答案 0 :(得分:0)
好的,我意识到这就像在requestAnimationFrame()
方法中再次调用tick()
一样简单。
import React, { Component } from "react";
import jsQR from "jsqr";
class WebcamStream extends Component {
constructor(props) {
super(props);
this.state = {
isVideoLoading: true
};
this.videoTag = React.createRef();
this.canvas = React.createRef();
this.tick = this.tick.bind(this);
}
componentDidMount() {
// getting access to webcam
navigator.mediaDevices
.getUserMedia({ video: { facingMode: "environment" } })
.then(stream => {
const video = this.videoTag.current;
video.srcObject = stream;
video.setAttribute("playsinline", true);
video.play();
requestAnimationFrame(this.tick);
});
}
drawLine(begin, end, color) {
const canvasElement = this.canvas.current;
const canvas = canvasElement.getContext("2d");
canvas.beginPath();
canvas.moveTo(begin.x, begin.y);
canvas.lineTo(end.x, end.y);
canvas.lineWidth = 4;
canvas.strokeStyle = color;
canvas.stroke();
}
tick() {
const video = this.videoTag.current;
const checkVideoState = setInterval(() => {
if (video.readyState === video.HAVE_ENOUGH_DATA) {
clearInterval(checkVideoState);
this.setState({ isVideoLoading: false });
const canvasElement = this.canvas.current;
const canvas = canvasElement.getContext("2d");
canvasElement.height = video.videoHeight;
canvasElement.width = video.videoWidth;
canvas.drawImage(
video,
0,
0,
canvasElement.width,
canvasElement.height
);
let imageData = canvas.getImageData(
0,
0,
canvasElement.width,
canvasElement.height
);
var code = jsQR(imageData.data, imageData.width, imageData.height);
if (code) {
this.drawLine(
code.location.topLeftCorner,
code.location.topRightCorner,
"#FF3B58"
);
this.drawLine(
code.location.topRightCorner,
code.location.bottomRightCorner,
"#FF3B58"
);
this.drawLine(
code.location.bottomRightCorner,
code.location.bottomLeftCorner,
"#FF3B58"
);
this.drawLine(
code.location.bottomLeftCorner,
code.location.topLeftCorner,
"#FF3B58"
);
}
requestAnimationFrame(this.tick);
}
}, 1000);
}
render() {
const { isVideoLoading } = this.state;
return (
<div>
<video
ref={this.videoTag}
width="400"
height="400"
autoPlay
style={{ display: "none" }}
/>
{!isVideoLoading && <canvas ref={this.canvas} />}
{isVideoLoading && <p>Please wait while we load the video stream.</p>}
</div>
);
}
}
export default WebcamStream;