如何在 react-konva 中捕获视频的第一帧
How to capture the first frame of a video in react-konva
我使用 react-konva 制作了一个简单的视频播放器,我想在播放视频之前将第一帧显示为缩略图。
这是我的方法:
我正在使用 Konva.Image 显示视频并使用 Konva.Animation 更新图像。
import Konva from "konva";
import React, { useState, useRef, useEffect } from "react";
import { Stage, Layer, Image, Text } from "react-konva";
function VideoPlayer({ width, height }) {
const video = useRef();
const image = useRef();
const anim = useRef();
const text = useRef();
const [loading, setLoading] = useState(true);
useEffect(() => {
anim.current = new Konva.Animation(() => {
image.current.image(video.current);
}, image.current.getLayer());
});
return (
<div>
<button
onClick={() => {
text.current.destroy();
video.current.play();
anim.current.start();
}}
>
PLAY
</button>
<button
onClick={() => {
video.current.pause();
anim.current.stop();
}}
>
PAUSE
</button>
<video
style={{ display: "none" }}
ref={video}
onLoadedData={() => {
setLoading(false);
}}
src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"
/>
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Text
ref={text}
text={loading ? "Loading..." : "Press PLAY..."}
{...{
width: window.innerWidth,
height: window.innerHeight,
align: "center",
verticalAlign: "middle"
}}
/>
<Image
x={100}
y={100}
ref={image}
width={width}
height={height}
stroke="black"
/>
</Layer>
</Stage>
</div>
);
}
export default VideoPlayer;
我在这里创建了我的实施的工作 demo。
您可以使用钩子来:
- 为预览图像创建一个 canvas 元素
- 创建视频元素
- 等待视频加载
- 将第一帧绘制到canvas
- 视频未播放时,使用预览canvas作为源
const usePreview = (url) => {
const [canvas, setCanvas] = useState(null);
useEffect(() => {
const video = document.createElement("video");
video.src = url;
const onLoad = () => {
const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
video.currentTime = 1;
const ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0);
setCanvas(canvas);
};
video.addEventListener("canplay", onLoad);
return () => video.removeEventListener("load", onLoad);
}, [url]);
return canvas;
};
完整演示:https://codesandbox.io/s/react-konva-video-preview-0we9d?file=/src/index.js
我使用 react-konva 制作了一个简单的视频播放器,我想在播放视频之前将第一帧显示为缩略图。
这是我的方法:
我正在使用 Konva.Image 显示视频并使用 Konva.Animation 更新图像。
import Konva from "konva";
import React, { useState, useRef, useEffect } from "react";
import { Stage, Layer, Image, Text } from "react-konva";
function VideoPlayer({ width, height }) {
const video = useRef();
const image = useRef();
const anim = useRef();
const text = useRef();
const [loading, setLoading] = useState(true);
useEffect(() => {
anim.current = new Konva.Animation(() => {
image.current.image(video.current);
}, image.current.getLayer());
});
return (
<div>
<button
onClick={() => {
text.current.destroy();
video.current.play();
anim.current.start();
}}
>
PLAY
</button>
<button
onClick={() => {
video.current.pause();
anim.current.stop();
}}
>
PAUSE
</button>
<video
style={{ display: "none" }}
ref={video}
onLoadedData={() => {
setLoading(false);
}}
src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"
/>
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Text
ref={text}
text={loading ? "Loading..." : "Press PLAY..."}
{...{
width: window.innerWidth,
height: window.innerHeight,
align: "center",
verticalAlign: "middle"
}}
/>
<Image
x={100}
y={100}
ref={image}
width={width}
height={height}
stroke="black"
/>
</Layer>
</Stage>
</div>
);
}
export default VideoPlayer;
我在这里创建了我的实施的工作 demo。
您可以使用钩子来:
- 为预览图像创建一个 canvas 元素
- 创建视频元素
- 等待视频加载
- 将第一帧绘制到canvas
- 视频未播放时,使用预览canvas作为源
const usePreview = (url) => {
const [canvas, setCanvas] = useState(null);
useEffect(() => {
const video = document.createElement("video");
video.src = url;
const onLoad = () => {
const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
video.currentTime = 1;
const ctx = canvas.getContext("2d");
ctx.drawImage(video, 0, 0);
setCanvas(canvas);
};
video.addEventListener("canplay", onLoad);
return () => video.removeEventListener("load", onLoad);
}, [url]);
return canvas;
};
完整演示:https://codesandbox.io/s/react-konva-video-preview-0we9d?file=/src/index.js