show code block

2017年3月22日 星期三

third-party元件(Youtube API) ─ Youtube API 簡易使用(二) 控制元件、移除SeekBar、自訂按鈕

前言:


今天來講一下YoutubePlay的控制方式。

想要自己控制PLAY、PAUSE按鈕,又或者想要自訂SeekBar。

這時候就必須要一個乾淨純粹的View ─

除了一個Time Bar 和點擊畫面上的Play、Pause外,是不是很乾淨的,很純粹。


其實也可以把所有控制按鈕都拿掉,所有的控制元件都自己設定,就像MixerBox一樣。

MixerBox就是自己控制所有元件的最好例子,單看畫面還不覺得這出自Youtube!

先讓我們看看Youtube官方文件。
https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/YouTubePlayer.PlayerStyle

在裡面有一個mothed是專門控制Style的



YouTubePlayer.PlayerStyle

java.lang.Object
   ↳java.lang.Enum<E extends java.lang.Enum<E>>
   ↳com.google.android.youtube.player.YouTubePlayer.PlayerStyle

Overview

The different styles available for the player.

Summary

Enum values
YouTubePlayer.PlayerStyle.CHROMELESSA style that shows no interactive player controls.
YouTubePlayer.PlayerStyle.DEFAULTThe default style, showing all interactive controls.
YouTubePlayer.PlayerStyle.MINIMALA minimal style, showing only a time bar and play/pause controls.
Public methods
static YouTubePlayer.PlayerStylevalueOf(String name)
final static PlayerStyle[]values()


public static final YouTubePlayer.PlayerStyle CHROMELESS

A style that shows no interactive player controls.
這個風格完全移除和畫面的互動,所有東西都必須自訂。
ex:就如同MixerBox一樣,自訂所有畫面

public static final YouTubePlayer.PlayerStyle DEFAULT

The default style, showing all interactive controls.
正常版風格,保留了一切你在Youtube上面看的到的控制元件,包含點它們右下角的Youtube可直接跳轉到它們app觀看的原件。

public static final YouTubePlayer.PlayerStyle MINIMAL

A minimal style, showing only a time bar and play/pause controls.
最小簡化的風格,只保留TimeBar和螢幕上的播放和暫停控制元件。
ex:就如同我前言那張圖一樣,可以明顯看出pause暫停按鈕和下面的TimeBar




程式碼:

先前的程式碼請先參考:http://nikeru8.blogspot.tw/2017/03/androidyoutube-api-youtube-api.html

我們加在讀取成功後的方法內。

onInitializationSuccess


當然要讀取成功後控制這一切才有意義XDD
 @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean wasRestored) {
        Toast.makeText(this, "onInitializationSuccess!", Toast.LENGTH_SHORT).show();
        if (youTubePlayer == null) {
            Log.d("CheckPoint", "CheckPoint youtubePlayer == null");
            return;
        }
        // Start buffering
        if (!wasRestored) {
            Log.d("CheckPoint", "CheckPoint !wasRestored");
            youTubePlayer.cueVideo(VIDEO_ID);
        }
//        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);//移除全部控制按鈕
//        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT);//原版
        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.MINIMAL);//移除下面的控制按鈕
    }


這邊比較值得注意的是,使用PlayerStyle.CHROMELESS時,因為移除了全部的控制按鈕,你甚至不能按下Play按鈕,要請你自己添加控制元件囉。
不然就會像一張圖片一樣卡在那。




控制元件Code:

如上所述,先在onInitializationSuccess內上程式碼。

youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);



再來改變main_activity.xml的布局

main_activity.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="com.chat.a015865.youtube.MainActivity">

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

    <LinearLayout
        android:id="@+id/video_control"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/player_view"
        android:background="#444"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:visibility="visible"
        android:weightSum="10"
        tools:layout_editor_absoluteX="84dp"
        tools:layout_editor_absoluteY="374dp">

        <ImageButton
            android:id="@+id/play_video"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:background="@null"
            android:src="@drawable/ic_play" />

        <ImageButton
            android:id="@+id/pause_video"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:background="@null"
            android:src="@drawable/ic_pause" />

        <SeekBar
            android:id="@+id/video_seekbar"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_weight="6"
            android:max="100"
            android:progress="0" />

        <TextView
            android:id="@+id/play_time"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_weight="2"
            android:text="--:--"
            android:textColor="@android:color/white" />
    </LinearLayout>
</RelativeLayout>





MainActivity.java

public class MainActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener, View.OnClickListener {


    public static final String API_KEY = "AIzaSyAPThx6WbAxjnX2En0qtf9OhD80tUcp380";

    //https://www.youtube.com/watch?v=
    public static final String VIDEO_ID = "qZIWO9TqvIA";

    private YouTubePlayer mYoutubePlayer;
    private View mPlayButtonLayout;
    private TextView mPlayTimeTextView;

    private Handler mHandler = null;
    private SeekBar mSeekBar;


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

        final YouTubePlayerView mYoutubePlayerView = (YouTubePlayerView) findViewById(R.id.player_view);
        mYoutubePlayerView.initialize(API_KEY, this);
        initView();
        mPlayButtonLayout = findViewById(R.id.video_control);
        findViewById(R.id.play_video).setOnClickListener(this);
        findViewById(R.id.pause_video).setOnClickListener(this);

        mPlayTimeTextView = (TextView) findViewById(R.id.play_time);
        mSeekBar = (SeekBar) findViewById(R.id.video_seekbar);
        mSeekBar.setOnSeekBarChangeListener(mVideoSeekBarChangeListener);
        mHandler = new Handler();
    }

    private void initView() {

    }

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean wasRestored) {
        Toast.makeText(this, "onInitializationSuccess!", Toast.LENGTH_SHORT).show();
        mYoutubePlayer = youTubePlayer;
        if (youTubePlayer == null) {
            Log.d("CheckPoint", "CheckPoint youtubePlayer == null");
            return;
        }
        // Start buffering
        if (!wasRestored) {
            Log.d("CheckPoint", "CheckPoint !wasRestored");
            youTubePlayer.cueVideo(VIDEO_ID);
        }
        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);
//        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT);//原版
//        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.MINIMAL);//移除下面的控制按鈕

        youTubePlayer.setPlayerStateChangeListener(mPlayerStateChangeListener);//影片在run時的狀態
        youTubePlayer.setPlaybackEventListener(mPlaybacckEventListener);
    }

    YouTubePlayer.PlaybackEventListener mPlaybacckEventListener = new YouTubePlayer.PlaybackEventListener() {
        @Override
        public void onPlaying() {
            mHandler.postDelayed(runnable, 100);
            displayCurrentTime();
        }

        @Override
        public void onPaused() {
            mHandler.removeCallbacks(runnable);
        }

        @Override
        public void onStopped() {
            mHandler.removeCallbacks(runnable);
        }

        @Override
        public void onBuffering(boolean b) {

        }

        @Override
        public void onSeekTo(int i) {
            Log.d("CheckPoint", "CheckPoint i = " + i);
            mHandler.postDelayed(runnable, 100);
        }
    };
    YouTubePlayer.PlayerStateChangeListener mPlayerStateChangeListener = new YouTubePlayer.PlayerStateChangeListener() {
        @Override
        public void onLoading() {

        }

        @Override
        public void onLoaded(String s) {

        }

        @Override
        public void onAdStarted() {

        }

        @Override
        public void onVideoStarted() {
            displayCurrentTime();
        }

        @Override
        public void onVideoEnded() {

        }

        @Override
        public void onError(YouTubePlayer.ErrorReason errorReason) {

        }
    };

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
        Toast.makeText(this, "Failed to initialize.", Toast.LENGTH_LONG).show();
    }

    SeekBar.OnSeekBarChangeListener mVideoSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(final SeekBar seekBar, final int progress, boolean fromUser) {
            long lengthPlayed = (mYoutubePlayer.getDurationMillis() * progress) / 100;
            mYoutubePlayer.seekToMillis((int) lengthPlayed);
            seekBar.setProgress(progress);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    };

    private void displayCurrentTime() {
        if (mYoutubePlayer == null) return;
        String formattedTime = formatTime(mYoutubePlayer.getDurationMillis() - mYoutubePlayer.getCurrentTimeMillis());
        mPlayTimeTextView.setText(formattedTime);
    }

    private String formatTime(int millis) {
        int seconds = millis / 1000;
        int minutes = seconds / 60;
        int hours = minutes / 60;
        return (hours == 0 ? "- - : " : formatS(hours) + ":") + formatS(minutes % 60) + ":" + formatS(seconds % 60);
    }

    private String formatS(int x) {
        String s = "" + x;
        if (s.length() == 1)
            s = "0" + s;
        return s;
    }


    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            displayCurrentTime();

            mHandler.postDelayed(this, 100);
        }
    };

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.play_video:
                if (null != mYoutubePlayer && !mYoutubePlayer.isPlaying())
                    mYoutubePlayer.play();
                break;
            case R.id.pause_video:
                if (null != mYoutubePlayer && mYoutubePlayer.isPlaying())
                    mYoutubePlayer.pause();
                break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mYoutubePlayer.release();
        mYoutubePlayer = null;
        mHandler.removeCallbacks(runnable);
    }
}


edit(2017/03/27)
上面無法和seekbar連動,當你移動seekbar影片會跟著移動,但影片再撥放的時候seekbar無法連動。
我試過RunOnUiThread設定seekbar會發生錯誤。
我修好的話會在上傳新code







沒有留言:

張貼留言

協程(coroutine) - 協程為什麼要學它?

 Coroutine 協程 再強調一次 協程就是由kotlin官方所提供的線程api //Thread Thread { }.start() //Executor val execu...