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

Created on 15 Mar 2017  路  49Comments  路  Source: davidohayon669/react-native-youtube

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:
```code:javascript
render() {
return (
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}
  />
)

}
```

bug

Most helpful comment

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 }}
            />
        );
    }
}

All 49 comments

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

@davidohayon669 I don't think it's the case for Master because the video/player DOESN'T WORK and I believe is broken in Master. Video is not being displayed but you can hear audio in the background. Can you confirm this? I'm using a Galaxy S7 fyi.

So I've been working in the V1 branch where the play DOES work and play but intermittently the players controls (pause, fullscreen) will NOT show. It displays the player controls maybe 40% and DOESN'T display 60% of the time in debug mode.

When doing a Android release build, it DOESN'T show at all 100% of the time :(

Any ideas?

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

@davidohayon669 Any update on this?

@larryranches not yet..

+1, I'm missing a play and a pause button.

I'm facing this same issue on my android phone.

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;

@johnckendall If you got it on a fork I can take a look

ok, I created a fork and updated RCTYouTubeExample with the code above if you still want to check it out. Thanks.

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 }}
            />
        );
    }
}

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

@davidohayon669 :
Same here today, if I use your example, there are no video-controls on startup.
If I toggle fullscreen and back to small screen, they appear.
(This happends any time - not only sometimes)

Even with @wack17s workarround, there are no video-controls in the Video after startup.

@davidohayon669: Maybe some additional Inforamtions that may help to find out why the bug happends.
If I change the stylesheet of player: {} and "Hot Reload" reinit the Player, the Controlls appear.
BUT if I switch to Video 1, the Controls disappear again.
If I use fullscreen:true, the controls appear everytime in the video.

Is there a fix for this?
I encounter the same issue, if fullscren == true then controls will show up in both fullscreen and inline mode (though sometimes they still won't show up in inline mode) when user exit fullscreen however i cannot get them to show up if video launches inline
Possible fix would be for us to put custom controls at the implementation, don't know if we can send actions to the player though

I'm also experiencing this problem. I've made it fullscreen for android and it works, but it's quite jarring having the video pop up full screen at first. Any ideas how I might be able to trick it into being fullscreen but invisible but then immediately closed?

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

@koswarabilly answer solved the problem for me, thanks a lot!!

youtube controls still don't appear sometimes. Has anyone solved the problem?
I have tried the solutions above. It doesn't work.

@Lexiwu the actual problem is sometime when you rescale the controls it do not have enough time, i guess the bigger the value of timeout the better it scale, the solution is you might have to add loading screen so that it have better user experience, for any particular fix without using rescaling, i am afraid their isn't any solution yet

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 ...

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.

any update?

+1

@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"

@Ilushkanama I'll take a look at this soon. Hope it really solves this

@Ilushkanama @luisfuertes @punksta @Loigor @Kisepro @xstable @tirrorex
Should have been taken care of now in version 1.1.0
Please provide feedback

I continue with bug and have v1.1.0 @davidohayon669

Seems to be working great as of first tests

@luisfuertes Does it also occur in the example app?

Bug still active and occurs very frequently.

@davidohayon669 cant compile example in android

I tried to unlink component and remove from package but It doesn't work.

Maybe play services versions are wrong?

                force 'com.google.firebase:firebase-messaging:11.0.4'
                force 'com.google.firebase:firebase-core:11.0.4'
                force 'com.google.android.gms:play-services-gcm:11.0.4'
                force 'com.google.android.gms:play-services-vision:11.0.4'
                force 'com.google.android.gms:play-services-base:11.0.4'
                force 'com.google.android.gms:play-services-location:11.0.4'
                force 'com.google.android.gms:play-services-maps:11.0.4'

Package versions:

"react": "16.0.0-alpha.12",
"react-native": "0.48.3",
"react-native-youtube": "^1.1.0",

The bug still occurs randomly in our app. On some devices, like Galaxy S7, Galaxy S8, or Moto G5, the bug appears more often than on other Android devices like Moto G5 Plus. Are there any new insights?

Same issue too, device is Huawei mate8.

  "dependencies": {
    "react": "16.3.1",
    "react-native": "~0.55.2",
    "react-native-youtube": "^1.1.0",
  } 

Same issue as well. This only seems to be an issue on Android for me. I have a flatlist of 'products'. Tapping one navigates to a particular product screen which is a redux connected container. Within that container there is a react-native-youtube video. The video controls render maybe 2/3rds of the time. It seems the video player becomes more unstable over time and eventually, given enough navigation, the video controls do not display for any video until the app is restarted.
The code looks something like this:
<YouTube videoId={this.props.videoYouTubeId} modestbranding={true} resumePlayAndroid={false} apiKey={ApiConfig.GoogleApiKey} style={{ alignSelf: 'stretch', height: 300 }} />

"react": "16.0.0",
"react-native": "^0.51.0",
"react-native-youtube": "^1.1.0"

No updates for it? Still with control problems do not appear in 2/3 of the times any news?

The only means of mitigating this issue that I found was to instantiate the YouTube player only once per app lifespan. I'm not sure if there's a singleton pattern that could be applied here but it'd probably do the trick.

bug still active:
"react": "^16.2.0",
"react-native": "^0.53.0",
"react-native-youtube": "^1.1.0",

*it only work on debug but not on release

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

Faced the same issue on MI Redmi note 5 Pro, and the hack with 500 works

"react": "16.6.1",
"react-native": "0.57.7",
"react-native-youtube": "^1.1.0",

Any updates?

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...

hey how can I automatic landscape mode in full screen like.. at this time if I click on fullscreen button it goes into fullscreen in landscape mode but I want that it working on the basis of orientation like if my device is in portrait mode and if click on fullscreen button it goes into full screen but portrait and if my device is in landscape mode than I will be in... how can I do it...

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

Thank you. You saved me from a weekend of fully rewriting the android logic.

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

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

Please increase time of timeout

any updates? I am facing the same problem
The hack with 500 works on some resolutions , not every time

```import React from 'react';
import {
View,
StyleSheet,
BackHandler,
Dimensions,
Platform,
StatusBar,
Text,
ActivityIndicator,
TouchableHighlight,
} from 'react-native';
import YouTube from 'react-native-youtube';
import Orientation from 'react-native-orientation';
import { Button as ElementButton, Icon } from 'react-native-elements';
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from 'react-native-responsive-screen';
import { MainRouter, NavigationService } from '../../navigator';

export default class YouTubeVideo extends React.Component {
// static navigationOptions = {
// headerTitle: "YouTube",
// headerStyle: {
// backgroundColor: "#000",
// },
// headerTitleStyle: {
// color: "#fff",
// },
// };

constructor(props) {
super(props);
this.state = {
isMounted: false,
isReady: false,
loading: false,
status: null,
quality: null,
error: null,
isPlaying: true,
isLooping: true,
duration: 0,
currentTime: 0,
fullscreen: false,
containerMounted: false,
containerWidth: wp('100%'),
signal: null,
controls: 0,
height: 0,
width: 0,
};
}

componentDidMount() {
this.setState({ isMounted: true });
}

componentWillUnmount() {
this.setState({ isMounted: false, isReady: false });
}

handleStateChange = ({ state }) => {
console.log('loadingState', state, this.state.isReady);
if (this.state.isReady) {
if (state === 'started') {
setTimeout(
() =>
this.setState({
height: '90%',
width: '98%',
controls: 1,
isPlaying: true,
}),
500
);
} else if (state === 'buffering') {
setTimeout(
() =>
this.setState({
height: '89.9%',
width: '97.9%',
controls: 1,
isPlaying: true,
}),
1000
);
} else {
setTimeout(
() =>
this.setState({
height: '90%',
width: '98%',
controls: 1,
isPlaying: true,
}),
2000
);
}
}
};

handleFullScreen = f => {
if (!f.isFullscreen) {
Orientation.lockToPortrait();
this.setState({ fullscreen: false });
} else {
Orientation.lockToLandscapeLeft();
this.setState({ fullscreen: true });
}
};

renderLoading = () => {
if (!this.state.isReady) {
return (
style={{ flex: 1, justifyContent: 'center', alignContent: 'center' }}
>


);
}
return null;
};

render() {
return (
style={{
flex: 1,
alignItems: 'center',
backgroundColor: 'rgb(41,34,108)',
width: this.state.containerWidth,
}}
>
{this.renderLoading()}
apiKey={API_KEY}
ref={item => (this.player = item)}
videoId={this.props.navigation.state.params.youtubeId}
controls={this.state.controls}
fullscreen={false}
onReady={e => this.setState({ isReady: true })}
play={this.state.isPlaying}
onChangeState={e => this.handleStateChange(e)}
onChangeFullscreen={f => this.handleFullScreen(f)}
style={{ width: this.state.width, height: this.state.height }}
/>

onPress={() => console.log('Something!)}
title="Do Something!"
type="outline"
titleStyle={{ color: 'rgb(41,34,108)' }}
buttonStyle={{ backgroundColor: 'white' }}
containerStyle={{
marginTop: 60,
borderWidth: 0.5,
borderColor: 'rgb(41,34,108)',
width: wp('40%'),
}}
/>


);
}
}

const styles = StyleSheet.create({
mainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgb(41,34,108)',
height: hp('60%'),
width: wp('100%'),
},
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
width: wp('100%'),
backgroundColor: 'rgb(41,34,108)',
// backgroundColor: 'white',
},
});
```
This works for me...(99% error free)
Adjust the timeouts accordingly ...

solved in c9a0c38c1799f7cfb7d3ad9435ad834c52ba56d8

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthiasleitner picture matthiasleitner  路  5Comments

LorienHW picture LorienHW  路  3Comments

dblazeski picture dblazeski  路  5Comments

MattJLeach picture MattJLeach  路  5Comments

idhowardgj94 picture idhowardgj94  路  3Comments