在 Android 中制作完美的 Chromeless Youtube 播放器

Making a perfect Chromeless Youtube Player in Android

我在制作 CHROMELESS youtube 播放器视图时创建的内容在这里。它加载和播放完美,但缓冲圈连续播放,即使视频完成。任何人都可以帮助我在不需要时删除缓冲进度并制作完美的 youtube 播放器吗?

MainActivity.java

package com.rocky.youtubedemo;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;

public class MainActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {

    private static final int RECOVERY_REQUEST = 1;
    private static String YOUTUBE_API_KEY = "";
    private YouTubePlayerView youTubeView;
    private Context context;
    private MyPlayerStateChangeListener playerStateChangeListener;
    private MyPlaybackEventListener playbackEventListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        playerStateChangeListener = new MyPlayerStateChangeListener();
        playbackEventListener = new MyPlaybackEventListener();

        YOUTUBE_API_KEY = "PLACE_YOUR_API_KEY_HERE";

        youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
        youTubeView.initialize(YOUTUBE_API_KEY, this);
    }

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, final YouTubePlayer player, boolean wasRestored) {

        player.setPlayerStateChangeListener(playerStateChangeListener);
        player.setPlaybackEventListener(playbackEventListener);

        if (!wasRestored) {
            player.loadVideo("fhWaJi1Hsfo"); // Plays https://www.youtube.com/watch?v=fhWaJi1Hsfo
            player.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);
        }
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
        if (errorReason.isUserRecoverableError()) {
            Toast.makeText(context, errorReason.toString(), Toast.LENGTH_LONG).show();
//            errorReason.getErrorDialog(this, RECOVERY_REQUEST).show();
        } else {
            String error = errorReason.toString();
            Toast.makeText(context, error, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RECOVERY_REQUEST) {
            // Retry initialization if user performed a recovery action
            getYouTubePlayerProvider().initialize(YOUTUBE_API_KEY, this);
        }
    }

    private void showMessage(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }

    protected YouTubePlayer.Provider getYouTubePlayerProvider() {
        return youTubeView;
    }

    private final class MyPlaybackEventListener implements YouTubePlayer.PlaybackEventListener {

        @Override
        public void onPlaying() {
            // Called when playback starts, either due to user action or call to play().
            showMessage("Playing");
        }

        @Override
        public void onPaused() {
            // Called when playback is paused, either due to user action or call to pause().
            showMessage("Paused");
        }

        @Override
        public void onStopped() {
            // Called when playback stops for a reason other than being paused.
            showMessage("Stopped");
        }

        @Override
        public void onBuffering(boolean b) {
            showMessage("buffer");
        }

        @Override
        public void onSeekTo(int i) {
            // Called when a jump in playback position occurs, either
            // due to user scrubbing or call to seekRelativeMillis() or seekToMillis()
        }
    }

    private final class MyPlayerStateChangeListener implements YouTubePlayer.PlayerStateChangeListener {

        @Override
        public void onLoading() {
            showMessage("loading");
        }

        @Override
        public void onLoaded(String s) {
            showMessage("loaded");
        }

        @Override
        public void onAdStarted() {
            // Called when playback of an advertisement starts.
        }

        @Override
        public void onVideoStarted() {
            // Called when playback of the video starts.
            showMessage("started");
        }

        @Override
        public void onVideoEnded() {
            // Called when the video reaches its end.
        }

        @Override
        public void onError(YouTubePlayer.ErrorReason errorReason) {
            // Called when an error occurs.
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.youtube.player.YouTubePlayerView
        android:id="@+id/youtube_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

在您的 onInitializationSuccess() 中,在播放器上设置一个 PlaybackEventListener。覆盖 onBuffering() 并执行如下操作:

ViewGroup ytView = youTubeView; // if you are using YouTubePlayerView
ViewGroup ytView = (ViewGroup)ytPlayerFragment.getView(); // if you are using YouTubePlayerFragment
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/View
    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.
}

像这样制作方法:

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
    }

通过这种方式,您可以在缓冲时启用进度,在缓冲时禁用它。