0

I'm using react-player to render youtube videos with map(), like so:

class Jukebox extends Component {
  constructor (props) {
    super(props);
    this.state = {
     youtube_urls:[],      
     clients:[],        
    };
  };

  componentDidMount() {
    if (this.props.isAuthenticated) {
      this.getItems();
    }
  };

  getItems(event) {
    const {userId} = this.props
    const options = {
      url: `${process.env.REACT_APP_WEB_SERVICE_URL}/jukebox/${userId}`,
      method: 'get',
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': true,
        Authorization: `Bearer ${window.localStorage.authToken}`
      }
    };
    return axios(options)
    .then((res) => { 
      console.log(res.data)  
      console.log(res.data.data) 
      this.setState({
        clients: res.data.data[0].clients,
        youtube_urls:res.data.data[0].youtube_urls
      })
    })
    .catch((error) => { console.log(error); });
  };

render() {
 const { youtube_urls } = this.state;
 return (
  <div>      
   <h1 className="title is-1">Jukebox</font></h1>
  {
   clients.map((client, index) => {
     /* 
    Obtain preview from state.previews for current artist index 
    */
    const audio = youtube_urls[index]
    /* 
    Render current client data, and corresponding audio url
    */
    return(
      <div key={index}>
      <ul>
        <ReactPlayer 
          url={ audio }
          controls
          playing // <--- does not work
          width='50'
          height='150'
        />
        <div className="Line" />
      </ul></div>
     )
   })
 })
};

According to to one the library props, playing (see above), you can play media automatically when render finishes, but if I use map() this will result in all videos playing at the same time.

At the same time, there is the callback prop onReady():

Called when media is loaded and ready to play. If playing is set to true, media will play immediately.


QUESTION:

How do I implement this and have all videos play, from index 0 on, one at at time, after all media is loaded?

8-Bit Borges
  • 9,643
  • 29
  • 101
  • 198

1 Answers1

2

I'd use two state variables: videosLoadedCount, playingIndex. Initialize videosLoadedCount at 0 and playingIndex at -1.

You can deduce the playing props from the playingIndex state value.

Whenever there's an onReady, increment videosLoadedCount. When it reaches the number of videos, you can increment playingIndex. Whenever there is a onEnded callback, you increment playingIndex.


Something like this should work:

class Jukebox extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loadedVideosCount: 0,
      currentPlayingIndex: -1,
    };
  }

  render() {
    const { youtube_urls } = this.props;
    const { loadedVideosCount, currentPlayingIndex } = this.state;

    return (
      <div>
        {youtube_urls.map((url, index) => (
          <ReactPlayer
            url={url}
            controls
            onLoaded={() =>
              this.setState(currentState => ({
                loadedVideosCount: loadedVideosCount + 1,
                currentPlayingIndex:
                  loadedVideosCount + 1 === youtube_urls.length ? 0 : -1,
              }))
            }
            onEnded={() =>
              this.setState(currentState => ({
                currentPlayingIndex: currentPlayingIndex + 1,
              }))
            }
            playing={index === currentPlayingIndex} // <--- does not work
            width="50"
            height="150"
          />
        ))}
      </div>
    );
  }
}
Axnyff
  • 9,213
  • 4
  • 33
  • 37
  • Could you use code? I've added my constructor. I'd accept and upvote for the kindness – 8-Bit Borges Nov 10 '19 at 22:45
  • why do you change youtube_urls from state to props? – 8-Bit Borges Nov 10 '19 at 23:08
  • I recreated the component from scratch as the syntax wasn't correct. It didn't make much sense as they was no way to add a video to the youtube_urls and having it as state might complexify the problem – Axnyff Nov 10 '19 at 23:11
  • For completedness sake, I've edited my components so you can understand my states. Still does not make sense? I map from `clients`, not `yoube_urls`, which user clients index...in case it helps you – 8-Bit Borges Nov 10 '19 at 23:19