cookpete / react-player

A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion
https://cookpete.github.io/react-player
MIT License
9.44k stars 1.15k forks source link

Playing prop not changing when setting state #1469

Open garrett-a opened 2 years ago

garrett-a commented 2 years ago

Current Behavior

Playing prop not changing when setting state. Initial state is set to true. All streams are mapped as user searches.

Expected Behavior

I'm trying to play/pause all twitch streams on button click. In the console I can see my initial state as true on load. When clicked the state goes to false but nothing is happening.

//Context api
const [streamsPlaying, setStreamsPlaying] = useState(true);

//SettingModal.js
{ctx.streamsPlaying && (
          <div
            onClick={() => {
              ctx.pauseAllHandler();
              props.setOpen(false);
            }}
            className={classes.icon}
          >
            <i class="fa-solid fa-circle-pause"></i>
            <span>Pause all</span>
          </div>
        )}

//Stream.js
return (
    <Fragment>
      {ctx.searchedStreams.map((url) => (
        <div className={wrapperStyles} key={url} id={url}>
          <div className={classes.overlay}>
            <i
              onClick={() => {
                deleteStream(url);
              }}
              class="fa-solid fa-xmark"
            ></i>
          </div>

          <ReactPlayer
            key={url}
            className={classes.player}
            url={`https://www.twitch.tv/${url}`}
            width="100%"
            height="100%"
            theme="dark"
            playing={ctx.streamsPlaying}
            volume={ctx.streamMuted}
            controls={true}
            onPlay={() => ctx.setStreamsPlaying(true)}
            onPause={() => ctx.setStreamsPlaying(false)}
            onEnded={() => ctx.setStreamsPlaying(false)}

            // CHECK FOR ONPAUSE /////////////
          />
        </div>
      ))}
    </Fragment>
  );
};

Environment

karltaylor commented 2 years ago

I believe I might be having a similar issue and I have found that it's due to changing the state whilst updating the video url.

See a codesandbox example here: https://codesandbox.io/s/distracted-resonance-kc0ylj?file=/src/App.tsx

All I am doing is:

  1. Loading a .mp4 video.
  2. Playing .mp4 video after a countdown using playing prop.
  3. Whilst video is playing, clicking on "Go To Next Video" will:
    1. Change playing to false
    2. Change the url prop.
  4. If you click on Countdown again to play the video, the video does not play but the playing prop is true.

Update: I noticed that if you set the url to null the playing prop is respected again 🤔

m-danya commented 1 year ago

I've faced the same issue and I don't know how to fix it. The playing attribute is not working until I manually click on video to change current position.

m-danya commented 1 year ago

OMG I found a solution for my case! I added this:

<ReactPlayer
    ....
    onPlay={() => {this.setState({playing: true})}}
    ....
/>

It looks like when user starts the video, my variable this.state.playing is unsynced with actual video's attribtute. Keeping it up to date helps... Damn JS...

whynesspower commented 1 year ago

I was having the same issue, what you need to do is - wherever you are setting the value of playing state as false first change the same playing set to true and then immediately on the next line set it to false again.

It will work. Thanks