Jon G Jon G - 1 year ago 114
Android Question

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

sample with a couple of small modifications:

public class FragmentDemoActivity extends AppCompatActivity implements YouTubePlayer.OnInitializedListener {

public void onCreate(Bundle savedInstanceState) {


YouTubePlayerFragment youTubePlayerFragment =
(YouTubePlayerFragment) getFragmentManager().findFragmentById(;
youTubePlayerFragment.initialize(DeveloperKey.DEVELOPER_KEY, this);

public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
boolean wasRestored) {
if (!wasRestored) {
player.loadVideo("nCgQDjiotG0", 10);

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


I have changed
to inherit from
instead of
, as the documentation says is fine to do. I have also changed the player style to be chromeless in
. Finally, I have changed
, 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

The video starts playing after buffering. The player is chromeless. However the buffering spinner never disappears. Is this a bug, or am I doing something I am not allowed to do?

Answer Source

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);
    // TODO 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) {
    // 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.

EDIT: If anyone using this solution discovers that this bug has been fixed or that the position of the ProgressBar has changed, please share so that I can edit my answer, thanks!