在 React Konva 中的 Canvas 上播放视频

问题描述 投票:0回答:2

基于有关如何将视频渲染到画布的

Konva
文档,我想通过直接从
Konva.Image
实例访问视频引用来播放视频。下面是一个人为的示例,用于模拟我从组件外部动态播放视频的目标。即使
imageRef.current.image()
返回视频元素引用,下面的内容也不会按预期播放视频。关于如何访问视频参考有什么建议吗?

import React, { useEffect, useContext, useState } from 'react'
import { Image } from "react-konva";
import Konva from 'konva'

 export const MainVideo = ({ shape, dispatch  }) =>  {
  const imageRef = React.useRef(null);
  const video = document.createElement('video');
  video.setAttribute('src',shape.url);


  useEffect(() => {
    if(imageRef) {

  imageRef.current.image().play();
  const layer = imageRef.current.getLayer();

  const anim = new Konva.Animation(() => {
  }, layer);

        anim.start()

    }
  }, [imageRef])

    return (
     <Image 
     ref={imageRef}
     opacity={shape.o}
     id={shape.id} 
     image={video} 
     x={shape.x} 
     y={shape.y} 
     zIndex={0}
     height={360}
     width={640} />
    )
}
javascript konvajs react-konva
2个回答
3
投票

你可以这样做:

const Video = ({ src }) => {
  const imageRef = React.useRef(null);
  const [size, setSize] = React.useState({ width: 50, height: 50 });

  // we need to use "useMemo" here, so we don't create new video elment on any render
  const videoElement = React.useMemo(() => {
    const element = document.createElement("video");
    element.src = src;
    return element;
  }, [src]);

  // when video is loaded, we should read it size
  React.useEffect(() => {
    const onload = function() {
      setSize({
        width: videoElement.videoWidth,
        height: videoElement.videoHeight
      });
    };
    videoElement.addEventListener("loadedmetadata", onload);
    return () => {
      videoElement.removeEventListener("loadedmetadata", onload);
    };
  }, [videoElement]);

  // use Konva.Animation to redraw a layer
  React.useEffect(() => {
    videoElement.play();
    const layer = imageRef.current.getLayer();

    const anim = new Konva.Animation(() => {}, layer);
    anim.start();

    return () => anim.stop();
  }, [videoElement]);

  return (
    <Image
      ref={imageRef}
      image={videoElement}
      x={20}
      y={20}
      stroke="red"
      width={size.width}
      height={size.height}
      draggable
    />
  );
};

演示:https://codesandbox.io/s/react-konva-video-on-canvas-oygvf


0
投票
import ReactDOM from "react-dom";
import React, { useEffect, useRef, useState } from "react";
import { Image, Layer, Stage } from "react-konva";

const VideoPlayer = () => {
  const videoRef = useRef(null);
  const [videoNode, setVidoeNode] = useState();

  useEffect(() => {
    const video = videoRef.current;
    if (video) {
      video.src =
        "https://YOUR_VIDEO_LINK.mp4";

      // Konva animation frame
      const animate = () => {
        if (video.paused || video.ended) {
          return;
        }
        videoNode?.getLayer().batchDraw();
        requestAnimationFrame(animate);
      };

      video.addEventListener("loadeddata", () => {
        video.play();
        animate();
      });
    }
  }, [videoNode]);
  return (
    <>
      <Stage width={window.innerWidth} height={window.innerHeight - 0.5}>
        <Layer>
          <Image
            ref={(node) => {
              setVidoeNode(node);
            }}
            image={videoRef.current}
            width={window.innerWidth}
            height={window.innerHeight - 0.5}
          />
        </Layer>
      </Stage>
      <video ref={videoRef} hidden />
    </>
  );
};

export default VideoPlayer;

useEffect 挂钩用于设置视频播放和 Konva.js 集成。每当 videoNode 值发生变化时就会触发。 我们使用 videoRef 访问视频元素,将其源设置为您的视频 URL,并定义负责在视频播放期间更新 Konva.js 层的 animate 函数。 当视频的loadeddata事件被触发时,我们开始播放视频并调用animate函数来不断更新Konva.js层。

© www.soinside.com 2019 - 2024. All rights reserved.