Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View controls are not shown on Android #131

Closed
gorjanz opened this issue Mar 15, 2017 · 49 comments
Closed

View controls are not shown on Android #131

gorjanz opened this issue Mar 15, 2017 · 49 comments
Labels

Comments

@gorjanz
Copy link

gorjanz commented Mar 15, 2017

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}
      />
    )
  }
@davidohayon669
Copy link
Owner

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

@larryranches
Copy link

larryranches commented Apr 6, 2017

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

@davidohayon669
Copy link
Owner

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

@larryranches
Copy link

@davidohayon669 Any update on this?

@davidohayon669
Copy link
Owner

@larryranches not yet..

@vtam311
Copy link

vtam311 commented May 23, 2017

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

@kamalk333
Copy link

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

mikelambert added a commit to mikelambert/dancedeets-monorepo that referenced this issue Jul 1, 2017
…n name).

Also some fixes because the android player sometimes doesn't show controls:
davidohayon669/react-native-youtube#131

Namely, we will play the video on returning to the same screen. And we support the tutorial row itself as a play/pause button.
@johnckendall
Copy link

johnckendall commented Jul 3, 2017

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;

@davidohayon669
Copy link
Owner

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

@johnckendall
Copy link

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

@wack17s
Copy link

wack17s commented Jul 11, 2017

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

@jayprakash1
Copy link

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

@xstable
Copy link
Contributor

xstable commented Aug 11, 2017

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

@tirrorex
Copy link

tirrorex commented Sep 5, 2017

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

@SamMatthewsIsACommonName

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?

@koswarabilly
Copy link

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

@MrBrownser
Copy link

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

@Lexiwu
Copy link

Lexiwu commented Dec 18, 2017

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

@koswarabilly
Copy link

@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

@Kisepro
Copy link

Kisepro commented Dec 19, 2017

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

@Loigor
Copy link

Loigor commented Dec 21, 2017

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.

@punksta
Copy link

punksta commented Jan 10, 2018

any update?

@luisfuertes
Copy link

+1

@davidohayon669
Copy link
Owner

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

@davidohayon669
Copy link
Owner

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

@luisfuertes
Copy link

luisfuertes commented Jan 31, 2018

I continue with bug and have v1.1.0 @davidohayon669

@SamMatthewsIsACommonName

Seems to be working great as of first tests

@davidohayon669
Copy link
Owner

@luisfuertes Does it also occur in the example app?

@saidattax
Copy link

Bug still active and occurs very frequently.

@luisfuertes
Copy link

@davidohayon669 cant compile example in android

@luisfuertes
Copy link

luisfuertes commented Mar 23, 2018

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

@wahju
Copy link

wahju commented May 6, 2018

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?

@motogod
Copy link

motogod commented May 21, 2018

Same issue too, device is Huawei mate8.

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

@syntax-e
Copy link

syntax-e commented May 22, 2018

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"

@adrianocastellini
Copy link

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

@ghost
Copy link

ghost commented Jul 30, 2018

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.

@almorak
Copy link

almorak commented Aug 9, 2018

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

@ankit-2017
Copy link

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

@gautham20
Copy link

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

@tandat2209
Copy link

Any updates?

@lucianolev
Copy link

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

@tanveerbyn
Copy link

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

@NicholasDwyer
Copy link

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.

@milesmeow
Copy link

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

@andrei0807
Copy link

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

Please increase time of timeout

@zulqarnain26
Copy link

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

@Moh-Rangwala
Copy link

Moh-Rangwala commented Aug 13, 2019

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 (
        <View
          style={{ flex: 1, justifyContent: 'center', alignContent: 'center' }}
        >
          <ActivityIndicator size={'large'} />
        </View>
      );
    }
    return null;
  };

  render() {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          backgroundColor: 'rgb(41,34,108)',
          width: this.state.containerWidth,
        }}
      >
        <View style={styles.mainContainer}>
          {this.renderLoading()}
          <YouTube
            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 }}
          />
        </View>
        <View style={styles.container}>
          <ElementButton
            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%'),
            }}
          />
        </View>
      </View>
    );
  }
}

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

@davidohayon669
Copy link
Owner

solved in c9a0c38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests