如何在 react-konva 中捕获视频的第一帧

Posted

技术标签:

【中文标题】如何在 react-konva 中捕获视频的第一帧【英文标题】:How to capture the first frame of a video in react-konva 【发布时间】:2021-02-18 22:23:24 【问题描述】:

我使用 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。

【问题讨论】:

我在某处读到过,您可以在离屏画布中播放第一帧,然后抓取画布的图像并将其放入预览支架中,然后销毁离屏画布。 @VanquiishedWombat 我猜this 是您的建议。我正在尝试使其适应当前的反应,并且在实施时遇到了一些麻烦 【参考方案1】:

您可以使用钩子:

    为预览图像创建一个画布元素 创建视频元素 等待视频加载 将第一帧绘制到画布中 视频未播放时,使用预览画布作为源
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

【讨论】:

非常感谢。我尝试了类似this 的方法,现在我知道我哪里出错了

以上是关于如何在 react-konva 中捕获视频的第一帧的主要内容,如果未能解决你的问题,请参考以下文章

如何截取视频的第一帧图片

如何在视频的第一帧之前放置静止图像?

如何记录使用 AVCaptureSession 捕获的第一个和最后一个电影帧的确切时间?

web获取视频图片第一帧

在Android中如何获取视频的第一帧图片并显示在一个ImageView中

如何把上传的视频用该视频的第一帧的缩略图显示