react-native-youtube: View controls are not shown on Android

More often than not, the youtube view on Android, loads with only the starting image (cover) of the video, but without any video player controls. Nor the play button, nor the fullscreen mode button, nothing.

As far as I’ve seen throughout the other issues, this type of behaviour is not reported so-far. Is there something I am missing, or not using the component as intended?

I am using the component in the following manner:

  render() {
    return (
      <YouTube
        videoId={SOME_VIDEO_ID} // The YouTube video ID
        play={false}                                               // control playback of video with true/false
        hidden={false}                                             // control visibility of the entire view
        playsInline={true}                                         // control whether the video should play inline
        loop={false}                                               // control whether the video should loop when ended

        //onReady={(e)=> console.log("onReady", e)}
        //onChangeState={(e)=> console.log("onChangeState", e)}
        //onChangeQuality={(e)=> console.log("onChangeQuality", e)}
        //onError={(e)=> console.log("onError", e)}
        //onProgress={(e)=> console.log("onProgress", e)}

        ref={component => this._root = component}
        style={{alignSelf: 'stretch', height: 250, backgroundColor: 'black'}}
        apiKey={YOUTUBE_API_KEY}
      />
    )
  }

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 20
  • Comments: 49 (10 by maintainers)

Commits related to this issue

Most upvoted comments

this hack works for me

export default class extends Component {
    state = {
        height: 215
    }

    handleReady = () => {
        setTimeout(() => this.setState({ height: 216 }), 200);
    }

    render() {
        return (
            <YouTube
                apiKey   = {config.YOUTUBE_API_KEY}
                ref      = {item => this.player = item}
                videoId  = {getVideoId(uri)}
                controls = {1}
                onReady  = {this.handleReady}
                style    = {{ alignSelf: 'stretch', height: height }}
            />
        );
    }
}

use the hack above but set the timeout to 500, it works like charm for me.

Timeout hack is working only when the video is loaded in that given time. So, when controls are not visible and onReady is executed too early, only solution I found is to set auto playback to true and handle video playback state change. Sadly there’s no “video loaded from server” state, therefore auto playback is necessary. Better hack for this issue would be:

export default class extends Component {
    state = {
        height: 215
    }

    handleStateChange = ({state}) => {
        if(state === 'started') {
            setTimeout(() => this.setState({ height: 216 }), 200);
        }
    }

    render() {
        return (
            <YouTube
                apiKey={config.YOUTUBE_API_KEY}
                ref={item => this.player = item}
                videoId={getVideoId(uri)}
                controls={1}
                play={true}
                onChangeState={(e) => this.handleStateChange(e)}
                style={{ alignSelf: 'stretch', height: height }}
            />
        );
    }
}

This is still a dirty hack.

I know about this problem. It also affects my project I’ll probably tackle it in the next round

@wack17s i tried the above hack but youtube controls still don’t appear sometimes.

FYI…make sure you test the behavior extensively. I tried these hacks and the behavior of the player on Android is not very reliable.

Too bad this is still happening over a year from initial report 😦 In my case it happens 100% of the time on latest release. Only @wack17s using 500 as timeout solves it for me…

Bug still active and occurs very frequently.

@punksta @luisfuertes https://github.com/inProgress-team/react-native-youtube/pull/255, tested it with videoId, videoIds and playlistId, hope it gets merged soon. If you don’t want to wait for merge, you can use my fork’s branch "react-native-youtube": "https://github.com/Ilushkanama/react-native-youtube.git#android-controls-not-visible"

On my S7 emulator, I see the controls On my real S7 edge, I only see the startup image with no controls also

The hack of @wack17s with 500 works too …

works man thanks a lot

FWIW: I’ve created a project that has one screen that has only this one component styled exactly like the example (See code below). I consistently get the following behavior on both Android 4.1 on a motorola razr and on Android 7.1.1 in an emulator:

With play=true, controls=1, fullscreen=false . Comes up with a black rectangle of the appropriate dimensions . Has no controls . emits OVERLAY error . Touching rectangle has no affect . Rotating device (or emulator) causes the “Play” arrow to appear (still black) . Touching the Play arrow will start playback.
. Rotating back to portrait and pressing play will immediately pause with the “TOO SMALL” error. Hitting play again resumes without error.

With play=false, controls=1, fullscreen=false . Comes up with a black rectangle of the appropriate dimensions . Has no controls . NO error emitted . Touching rectangle has no affect . Rotating device (or emulator) causes the “Play” arrow and first frame to appear . Touching the Play arrow will start playback.
. Rotating and touching play will also start playback WITHOUT error

(if controls=2 then all controls appear instead of just play button)

When rotating back and forth the controls can become mis-sized and mis-positioned.

Note that the error can be avoided by setting play=true and fullscreen=true. Then, onChangeState where state=“playing” set both back to false. It will revert to portrait and touching the play button will resume playing without error.

import React, {Component} from 'react';
import YouTube from 'react-native-youtube';
import { AppRegistry } from 'react-native';

import {
  StyleSheet,
  PixelRatio,
  Dimensions,
  ScrollView,
} from 'react-native';

const styles=StyleSheet.create({
  container: {
    backgroundColor: 'white',
  },
  player:{
    height:PixelRatio.roundToNearestPixel(Dimensions.get('window').width/(16/9)),
    alignSelf:'stretch',
    backgroundColor:'black',
    marginVertical:10,
  },
});

class VideoPlayer extends Component {
  constructor(props) {
    super(props);
    this.state={
      play:true,
      fullscreen:true,
    };
  }
 
  render() {
    const opts={
      loop:false,
      showFullscreenButton:false,
      showinfo:false,
      modestbranding:true,
      controls:2,
      rel:true,
    }
    console.log('VideoPlayer render opts',opts);

    return (
      <ScrollView style={styles.container}>
        <YouTube
          ref={(ref)=>{
            this._videoPlayer=ref;
          }}
          apiKey='googleapikey'
          videoId='KVZ-P-ZI6W4'
          play={this.state.play}
          fullscreen={this.state.fullscreen}
          loop={opts.loop}
          style={styles.player}
          showFullscreenButton={opts.showFullscreenButton||true}
          showinfo={opts.showinfo||true}
          modestbranding={opts.modestbranding||true}
          rel={opts.rel||false}
          controls={opts.controls==undefined?2:opts.controls}

          onError={(e)=>{this.videoError(e.error)}}
          onChangeState={(e)=>{this.videoState({e:e,state:e.state})}}
          onReady={(e)=>{this.videoState({e:e,state:'ready'})}}
          onProgress={(e)=>{this.videoProgress({e:e,currentTime:e.currentTime,duration:e.duration})}}
          onChangeQuality={(e)=>{this.videoState({e:e,quality:e.quality})}}
          />
        </ScrollView>
    )
 
  } // render
  videoError(e){
    console.log('PlayVideo ****************ERROR',e)
  }
  videoState(e){
    console.log('PlayVideo state change',e)
    if (e.state=='playing'){
      // hack to get video to play in portrait; must init both to true in constructor
      if (this.state.fullscreen){
        this.setState({play:false,fullscreen:false,})
      }
    }
  }
  videoProgress(e){
    console.log('PlayVideo videoProgress event,videoPosition',e);
  }
}

AppRegistry.registerComponent('YoutubeTest',()=>VideoPlayer);

export default VideoPlayer;

Seems to be working great as of first tests

I also stumble upon this problem every now and then. Still don’t know what causes it but it seems to be pretty persistent on some scenarios so I hope to tackle it soon.

Try working with the v1 branch as it will be the next version of this project