Multiple <ReactPlayer>'s, how can I pause another when one starts?

50 Views Asked by At

I have a custom component that contains a single <ReactPlayer>. I am calling my component <VideoPlayer>. If I have multiple <VideoPlayer>'s on one page, they can be played simultaneously and I have manually pause the other one.

I want to come up with a solution that will pause whatever other players are playing. I've tried doing custom events but I am not sure how to reference the player that is playing. Any ideas? I am using vimeo as the host of these videos if that makes a difference.

The only prop that accepts right now is singleVideoIndex i.e: <VideoPlayer singleVideoIndex={1} />

The reasoning here is without that property a playlist is rendered next to the video. If an index is passed to the component, the playlist is not rendered and the video at whatever index is the one that gets loaded.

I came up with a solution that seems to be working, but I am not happy about it, nor do I think it is the react way I should be doing things. The handlePlay function is the part I am referring to that is working for now.

Here is a shortened version of my component

function VideoPlayer({singleVideoIndex}) {
  const videos =[...]
  const player = useRef(null);
  const [activeVideo, setActiveVideo] = useState(defaultIndex);
  const [seekTime, setSeekTime] = useState(0);
  const [playing, setPlaying] = useState(false);

  // Handle playing the video. This will pause all other vimeo iframes.
  const handlePlay = (player) => {
    // Get all .video-players
    const players = [...document.querySelectorAll('.video-player')];
    // Returns .video-players that aren't the one we just clicked.
    const filteredPlayers = players.filter(function(element) {
      return element !== player.current.wrapper;
    });
    // Now pause the iframes.
    filteredPlayers.forEach(function(element, index) {
      element.querySelector('iframe').contentWindow.postMessage('{"method":"pause"}', '*');
    });
    // This sets the state on the player you originally clicked on.
    setPlaying(true);
  };

  // Click to load a video.
  const playVideo = (index) => {
    setActiveVideo(index);
    setPlaying(true);
  };

  // Selecting a chapter.
  const selectChapter = (videoIndex, time) => {
    if (videoIndex !== activeVideo) {
      setActiveVideo(videoIndex);
    }
    setSeekTime(time);
    player.current.seekTo(time);
    setPlaying(true);
  };

  return (
    <ReactPlayer
      ref={player}
      url={`https://vimeo.com/${videos[activeVideo].vimeoId}`}
      controls
      playing={playing}
      onReady={() => player.current.seekTo(seekTime)}
      onPlay={() => handlePlay(player)}
      onPause={() => setPlaying(false)}
      width="100%"
      height="100%"
      className="video-player"
    />
  )
}

export default VideoPlayer;
0

There are 0 best solutions below