Search code examples
javascriptreactjsreact-hooksreact-player

Pause other video if selected video is playing in react


I'm using react-player https://github.com/cookpete/react-player to play my videos. My problem is, how can I pause other videos while selected video is playing?

const videoRef = useRef();

const updateVideoHandler = async (videoId, videoTitle) => {
  setSelectedVideoId(videoId);
  if (!selectedVideoId) {
    videoRef?.current?.player?.player?.onPause();
  }
};

<ReactPlayer
  ref={videoRef}
  onPlay={() => updateVideoHandler(video.id, video.title)}
  playsinline={true}
  playing={true}
  controls={true}
  url={video?.url}
  width="100%"
  height="100%"
  playIcon={
    <div
      className="play-icon"
      role="button"
      tabIndex={0}
      style={{ outline: "none" }}
    >
      {" "}
      <img src="/images/play.png" alt="" />
    </div>
  }
  light={video?.pic}
/>;

Solution

  • You could store all player instances in a Context and use a Provider and Consumer to pause all players if one starts playing.

    Since you pass a playing boolean to ReactPlayer, you can easily store a id or reference of the current playing player.

    For example:

    PlayerProvider.jsx

    export const PlayerContext = React.createContext({
      play: (playerId) => true,
      pause: (playerId) => true,
      isPlaying: (playerId) => false,
    });
    
    function PlayerProvider({ children }) {
      // store the id of the current playing player
      const [playing, setPlaying] = useState('');
    
      // set playing to the given id
      const play = playerId => setPlaying(playerId);
    
      // unset the playing player
      const pause = () => setPlaying(false);
    
      // returns true if the given playerId is playing
      const isPlaying = playerId => playerId === playing;
    
      return (
        <PlayerContext.Provider value={{ play, pause, isPlaying }}>
          {children}
        </PlayerContext.Provider>
      )
    }
    
    export default PlayerProvider;
    

    Player.jsx

    import { PlayerContext } from './PlayerProvider';
    
    function Player({ video, id }) {
      const { isPlaying, play, pause } = useContext(PlayerContext);
    
      <ReactPlayer
        ref={videoRef}
        playsinline={true}
        playing={isPlaying(id)}
        controls={true}
        url={video?.url}
        width="100%"
        height="100%"
        onPause={() => pause(id)}
        onEnded={() => pause(id)}
        onClickPreview={() => play(id)}
        playIcon={
          <div
            className="play-icon"
            role="button"
            tabIndex={0}
            style={{ outline: "none" }}
          >
            {" "}
            <img src="/images/play.png" alt="" />
          </div>
        }
        light={video?.pic}
      />;
    }
    
    export default Player;
    

    Page.jsx

    import PlayerProvider from './PlayerProvider';
    import Player from './Player';
    
    function Page() {
      return (
        <PlayerProvider>
          <Player video="/path/to/video1.mp4" id="player1" />
          <Player video="/path/to/video2.mp4" id="player2" />
          <Player video="/path/to/video3.mp4" id="player3" />
        </PlayerProvider>
      )
    }