phloxic / videojs-sprite-thumbnails

Video.js plugin to display thumbnails from a sprite image when hovering over the progress bar
https://lastshiphome.de/en/movie
MIT License
51 stars 11 forks source link

ES6 Import videojs-sprite-thumbnails in TS React app #59

Open ftirej opened 9 months ago

ftirej commented 9 months ago

HI, is there a way to import the plugin in a React v18 app using TS?.

phloxic commented 7 months ago

Hi @ftirej, to be honest: I cannot say, due to lack of experience with React and/or typescript

singh-inder commented 4 weeks ago

You can use the following approach. Note: I've not created types for videojs options or spriteThumbnails config.

Sandbox

import { useEffect, useRef } from "react";
import videojs from "video.js";
// @ts-expect-error no types
import SpriteThumbnails from "videojs-sprite-thumbnails";
import "video.js/dist/video-js.css";

type Props = {
  // TODO: any types of options https://videojs.com/guides/options/
  options: any;
  onReady?: (player: ReturnType<typeof videojs>) => void;
};

type Player = ReturnType<typeof videojs> & {
  // TODO: add types for config // https://www.npmjs.com/package/videojs-sprite-thumbnails#configuration
  spriteThumbnails?: (config: Object) => void;
};

export default function VideoPlayer({ options, onReady }: Props) {
  const videoRef = useRef<HTMLDivElement | null>(null);
  const playerRef = useRef<Player | null>(null);

  useEffect(() => {
    // Make sure Video.js player is only initialized once
    if (!playerRef.current) {
      // The Video.js player needs to be _inside_ the component el for React 18 Strict Mode.
      const videoElement = document.createElement("video-js");

      videoElement.classList.add("vjs-big-play-centered");
      videoRef.current?.appendChild(videoElement);

      const player = (playerRef.current = videojs(videoElement, options, () => {
        videojs.log("player is ready");
        onReady && onReady(player);
      }));

      // You could update an existing player in the `else` block here
      // on prop change, for example:
    } else {
      const player = playerRef.current;

      player.autoplay(options.autoplay);
      player.src(options.sources);
    }

    // https://github.com/phloxic/videojs-sprite-thumbnails/blob/master/src/plugin.js#L86
    const pluginName = "spriteThumbnails";

    if (typeof videojs.getPlugin(pluginName) === "undefined") {
      videojs.registerPlugin(pluginName, SpriteThumbnails);
    }

    // setup 160x90 thumbnails in sprite.jpg, 1 per second
    playerRef.current.spriteThumbnails?.({
      interval: 1,
      url: "https://raw.githubusercontent.com/GiriAakula/samuel-miller-task/master/openvideo.png",
      width: 160,
      height: 90,
      columns: 10,
    });
  }, [options, videoRef]);

  // Dispose the Video.js player when the functional component unmounts
  useEffect(() => {
    const player = playerRef.current;

    return () => {
      if (player && !player.isDisposed()) {
        player.dispose();
        playerRef.current = null;
      }
    };
  }, []);

  return (
    <div data-vjs-player>
      <div ref={videoRef} />
    </div>
  );
}
phloxic commented 3 weeks ago

Hi @singh-inder, thank you for this example. It seems a good idea to add it to the README, or, to avoid overloading it, to some doc or contrib section. Patch welcome ;-) or drop me an email if you like.

sitaoi commented 3 weeks ago

@singh-inder @I follow this link https://codesandbox.io/p/sandbox/immutable-cloud-ly8468? file=%2Fsrc%2Fcomponents%2FVideoPlayer.tsx%3A13%2C37, why is the thumbnails function not implemented

singh-inder commented 3 weeks ago

Hi @phloxic sure I can create an example repo and also add a codesandbox link. But how do you want to handle types? In this repo itself or inside DefinitelyTyped repo. DefinitelyTyped could take some time for merging PR.

singh-inder commented 3 weeks ago

@singh-inder @i follow this link https://codesandbox.io/p/sandbox/immutable-cloud-ly8468? file=%2Fsrc%2Fcomponents%2FVideoPlayer.tsx%3A13%2C37, why is the thumbnails function not implemented

@sitaoi I've added a comment right above haven't added any types for the example code. Also have added a link for config object.

sitaoi commented 3 weeks ago

@singh-inder @phloxic It means that this feature is not supported yet,Now, there is an urgent need for such plug-ins

singh-inder commented 3 weeks ago

@singh-inder @phloxic It means that this feature is not supported yet,Now, there is an urgent need for such plug-ins

What do you mean by feature not supported? If you're referring to missing types, you can easily create a type yourself based on the config