React-native-youtube: Need more player control methods: playVideo, pauseVideo, stopVideo

Created on 26 Aug 2017  路  7Comments  路  Source: davidohayon669/react-native-youtube

Thanks much for the great work on react-native-youtube.
It works great for my project, but I found that I need more control of the video player, which are exposed by YouTube API: playVideo(), pauseVideo(), stopVideo()
https://developers.google.com/youtube/iframe_api_reference#playVideo

Thanks

Most helpful comment

@zengxinzhy I intentionally don't implement these methods since one of React's strong concepts is declarative APIs. The play prop should handle playing/pausing state in the native component very concisely. If you need more control, you can always sync your state with the native state by listening to onChangeState like this:

<YouTube
  play={this.state.play}
  onChangeState={event => {
    if (event.state === 'playing') {
      this.setState({ play: true })
    } else if (event.state === 'paused' || event.state === 'stopped' || event.state === 'ended') {
      this.setState({ play: false })
    }
  }}
/>

(All other states are transitions between a playing and a paused/stopped state so you can ignore syncing with them)

All 7 comments

@zengxinzhy I intentionally don't implement these methods since one of React's strong concepts is declarative APIs. The play prop should handle playing/pausing state in the native component very concisely. If you need more control, you can always sync your state with the native state by listening to onChangeState like this:

<YouTube
  play={this.state.play}
  onChangeState={event => {
    if (event.state === 'playing') {
      this.setState({ play: true })
    } else if (event.state === 'paused' || event.state === 'stopped' || event.state === 'ended') {
      this.setState({ play: false })
    }
  }}
/>

(All other states are transitions between a playing and a paused/stopped state so you can ignore syncing with them)

@davidohayon669 Thanks much for the quick reply, the solution you suggested works well for my project.

BTW, I saw we currently don't have any control on playback rate:
https://developers.google.com/youtube/iframe_api_reference#Playback_rate

Do you think we can add it? If so, I'll work on it and submit a pull request.

Thanks

@zengxinzhy these features are available only on the iOS. I think implementing them will be a bit of an overkill for a component that is meant to be as universal as possible. I'm not sure if there is any demand for these pretty specific methods, but maybe I'm wrong. Do you need to control playback rate in your project?

@davidohayon669 when the player state changes to stopped, either because the phone screen is locked, and i try to resumen the video through prop play, it doesn't work. The video stays in the same state of stopped.

Any fix/trick to handle this?


In example also occurs and is only when the screen is blocked directly with the video playing.

@hasaezs is your local state synced with the native state? you can try play={false} and then true again after a few milliseconds

@davidohayon669 Here is the code for my component, so I use it for the moment. But it continues to happen when the state changes to stopped

class SongScreen extends React.Component {
  state = {
    isReady: false,
    isPlaying: false,
    state: null
  };

  onReady = (e) => {
    this.setState({ isReady: true });
  };

  changeState = (e) => {
    let self = this;

    this.setState({ status: e.state });

    if (e.state === 'playing') {
      this.setState({ isPlaying: true })
    }
    else if (e.state === 'stopped' || e.state === 'paused' || e.state === 'ended') {
      setTimeout(function() {
        self.setState({ isPlaying: false });
      }, 200);
    }
  };

  togglePlay = () => {
    let self = this;

    setTimeout(function() {
      self.setState(s => ({ isPlaying: !s.isPlaying }));
    }, 200);
  };

  render() {
    const { song } = this.props.navigation.state.params;
    let { isReady, isPlaying } = this.state;

    return (
      <View style={styles.container}>
        <YouTube
          apiKey={'API_KEY'}
          videoId={song.youtube_id}
          play={isPlaying}
          controls={1}
          onReady={this.onReady}
          onChangeState={this.changeState}
          style={styles.youtubePlayer}
        />
        <Grid containerStyle={styles.contentContainer}>
          <Row>
            <Text>{this.state.status}</Text>
          </Row>
          <Row>
            <Text>{isPlaying ? 'Reproduciendo' : 'No reproduciendo'}</Text>
          </Row>
          <Row>
            <Col size={25} style={{ justifyContent: 'center', paddingLeft: 5 }}>
              <Icon
                name={isPlaying ? 'pause' : 'play-arrow'}
                size={48}
                color={isReady ? PRIMARY_COLOR : SECONDAY_COLOR}
                onPress={this.togglePlay}
                disabled={!isReady}
              />
            </Col>
            <Col size={75} style={{flex: 1, alignItems: 'stretch', justifyContent: 'center', paddingRight: 20, paddingLeft: 10}}>
              <Slider />
            </Col>
          </Row>
        </Grid>
      </View>
    );
  }
}

@hasaezs I couldn't cause a stopped state anyway I tried (Incoming call, Lock button, Siri), can you tell me exactly what you do to reproduce this event? Also, I don't see any reason for you to use setTimeout around setState which is already an async process

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dblazeski picture dblazeski  路  5Comments

savioseb picture savioseb  路  4Comments

MattJLeach picture MattJLeach  路  5Comments

dungnguyen10989 picture dungnguyen10989  路  3Comments

manjeet-dobble picture manjeet-dobble  路  5Comments