Jon G February 2016

YouTube Android API: YouTubePlayerFragment loading spinner

I am using the Android YouTube API samples to create a chromeless YouTube player in my app. I am having an issue that the buffering / loading progress bar carries on displaying over my video even after it has loaded and started playing. I can reproduce this in the FragmentDemoActivity sample with a couple of small modifications:

public class FragmentDemoActivity extends AppCompatActivity implements YouTubePlayer.OnInitializedListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.fragments_demo);

        YouTubePlayerFragment youTubePlayerFragment =
            (YouTubePlayerFragment) getFragmentManager().findFragmentById(R.id.youtube_fragment);
        youTubePlayerFragment.initialize(DeveloperKey.DEVELOPER_KEY, this);
    }

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
          boolean wasRestored) {
        if (!wasRestored) {
            player.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);
            player.loadVideo("nCgQDjiotG0", 10);
        }
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {}

}

I have changed FragmentDemoActivity to inherit from AppCompatActivity instead of YouTubeFailureRecoveryActivity, as the documentation says is fine to do. I have also changed the player style to be chromeless in onInitializationSuccess. Finally, I have changed cueVideo to loadVideo, just to trigger auto play.

This happens on multiple devices including Nexus 5X. I am using library version 1.2.2. No error is triggered in onInitializationFailure.

The video starts playing after buffering. The player is chromeless. However the buffering spinner

Answers


Ribesg February 2016

I encountered this too, it really looks like a bug. Here is how I managed to work around it.

In your onInitializationSuccess, set a PlaybackEventListener on the player. Override the onBuffering and do something like this:

ViewGroup ytView = (ViewGroup)ytPlayerFragment.getView();
ProgressBar progressBar;
try {
    // As of 2016-02-16, the ProgressBar is at position 0 -> 3 -> 2 in the view tree of the Youtube Player Fragment
    ViewGroup child1 = (ViewGroup)ytView.getChildAt(0);
    ViewGroup child2 = (ViewGroup)child1.getChildAt(3);
    progressBar = (ProgressBar)child2.getChildAt(2);
} catch (Throwable t) {
    // As its position may change, we fallback to looking for it
    progressBar = findProgressBar(ytView);
    // I recommend reporting this problem so that you can update the code in the try branch: direct access is more efficient than searching for it
}

int visibility = isBuffering ? View.VISIBLE : View.INVISIBLE;
if (progressBar != null) {
    progressBar.setVisibility(visibility);
    // Note that you could store the ProgressBar instance somewhere from here, and use that later instead of accessing it again.
}

The findProgressBar method, used as a fallback just in case the Youtube code changes:

private ProgressBar findProgressBar(View view) {
    if (view instanceof ProgressBar) {
        return (ProgressBar)view;
    } else if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup)view;
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            ProgressBar res = findProgressBar(viewGroup.getChildAt(i));
            if (res != null) return res;
        }
    }
    return null
}

This solution works perfectly fine for me, enabling the ProgressBar when the player is buffering and disabling it when it's not.

Post Status

Asked in February 2016
Viewed 1,726 times
Voted 14
Answered 1 times

Search




Leave an answer