【Kotlin】YouTubeAPIでの動画再生の過程詳細

#はじめに
　この記事ではyoutubeAPIに備えられた機能を使えば、動画再生開始時や広告の開始時、動画終了時などに処理を記述できるという事を示します。応用の幅が広いと思うので、ぜひ参考にしてみてください。youtubeAPIを導入して取り敢えず再生させるまでについては、過去に記事を書いているので参考にしてみてください。
【Kotlin】YouTubeAPIを用いて動画再生まで行う：https://qiita.com/K4N4/items/149a11f529810f5ef79e

#概要
　今回は`PlaybackEventListener`と`PlayerStateChangeListener`というインターフェースを紹介します。これらのインターフェースは動画再生に関わるコールバックメソッドで、動画が開始されたり終了した時に呼び出されるメソッドを定義しています。動画再生イベントもActivityのライフサイクルと同じように、様々な過程を経て再生を行っており、その節々に処理を記述することが出来ます。また、これらは`YouTubePlayer`のネストされたインターフェースです。

##PlaybackEventListener
　これは動画の再生開始や停止、終了等の基本的な動画再生イベントが発生した場合に呼び出されるコールバックのインターフェース定義です。提供されている抽象メソッドを以下で紹介します。

###onBuffering(boolean isBuffering)
 **このメソッドは動画のバッファリングが行われるタイミングで呼び出されます。**引数はバッファリング開始時に`true`、バッファリング終了時に`false`になる変数です。ここで、バッファリングとは、動画の再生開始前などに、数秒から数分の映像データをデバイスの中に溜め込む技術のことで、突然オフラインになっても動画再生を継続させることが出来ます。**YouTubeにおいては、新たに動画を再生した時やシークバーを動かした時にバッファリングが行われます。**しかし、動画を再生した時毎回このメソッドが呼ばれるわけでは無く、一時停止してから再生するときなどはバッファリングする必要が無いので、呼ばれません。**また、バッファリングは動画再生中付け足されるように行われていきますが、このメソッドが呼ばれるのは初回のバッファリング時のみのようです。**

###onPaused()
 **このメソッドはユーザーの操作もしくは動的な処理で動画再生が一時停止された時に呼ばれます。**ホームボタンを押すもしくは電源ボタンを押す時は、動画が一時停止してから処理が行われるので、このメソッドが呼ばれます。

###onPlaying()
　**このメソッドは動画が再生される度に呼び出されます。**

###onSeekTo(int newPositionMillis)
　**このメソッドはユーザーの操作もしくは動的な処理によって、シークバーが動かされた時に呼び出されます。**引数はシークバーの移動先の絶対時間をミリ秒で保持します。（例：10分の動画でシークバーを0:10に動かすと、引数は10000を持つ。）

###onStopped()
　**このメソッドは動画が一時停止ではない理由で停止した場合に呼び出されます。**例えば、画面が回転させられた時は基本的にこのメソッドが呼ばれます。

##PlayerStateChangeListener
　このインターフェースはより大まかなプレーヤーの状態変化で受けられるコールバックインターフェース定義です。`PlaybackEventListener`よりも抽象的な過程で処理を記述することが出来ます。提供されている抽象メソッドを下に記述していきます。

###onAdStarted()
　**広告の再生が開始された時に呼び出されます。**動画途中の広告でも問題なく呼び出されます。

###onError(YouTubePlayer.ErrorReason reason)
　**動画再生におけるエラーが発生すると呼び出されます。**引数はエラーの内容で、エラーが起きたときに行いたい処理を記述する場合は、このメソッドに記述することになると思います。エラーの内容は以下のリンクに列挙してあるので、興味があったら確認してみてください。
公式リファレンス：https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/YouTubePlayer.ErrorReason.html

###onLoaded(String videoId)
　**このメソッドはプレーヤーが動画の読み込みを終了し、再生の準備が整ったときに呼び出されます。**先述した`onBuffering(boolean isBuffering)`はこの処理の後に呼び出されます。これは、動画の再生の準備が整った後にバッファリングを行っているという事を示しています。

###onLoading()
　**このメソッドはプレーヤーが動画の読み込みを開始した時に呼び出されます。**プレイヤービューが初期化されてビデオがロードされる度に呼び出されるので、シークバーを動かしたりする度に呼ばれるようなものでは無いです。

###onVideoEnded()
　**このメソッドは動画の最後に到達すると呼び出されます。**ちなみに、動画の最後に到達すると、`onStopped`メソッドも同時に呼び出されます。

###onVideoStarted()
　**このメソッドは動画の再生そのものが開始されると呼び出されます。**`onPlaying`と異なる点は、動画が再生される度に呼び出されるのではなくて、「動画の再生」が開始された時に呼び出されます。具体的には、先述した`onLoading`メソッドと同じく、プレイヤービューが初期化されて動画再生が始まる時がこのメソッドの担当です。

#上記メソッドの可視化
　YouTubeBaseActivity()を継承したアクティビティに、以下のコードを記述して、ログに先述したメソッドがどのように呼び出されるかを可視化します。

```
private val playbackEventListener = object: YouTubePlayer.PlaybackEventListener {
        override fun onSeekTo(p0: Int) {
            Log.d(TAG, p0.toString())
            Log.d(TAG, "onSeekTo called")
        }

        override fun onBuffering(p0: Boolean) {
            Log.d(TAG, p0.toString())
            Log.d(TAG, "onBuffering called")
        }

        override fun onPlaying() {
            Log.d(TAG, "onPlaying called")
        }

        override fun onStopped() {
            Log.d(TAG, "onStopped called")
        }

        override fun onPaused() {
            Log.d(TAG, "onPaused called")
        }
    }

    private val playerStateChangeListener = object : YouTubePlayer.PlayerStateChangeListener {
        override fun onAdStarted() {
            Log.d(TAG, "onAdStarted called")
        }

        override fun onLoading() {
            Log.d(TAG, "onLoading called")
        }

        override fun onVideoStarted() {
            Log.d(TAG, "onVideoStarted called")
        }

        override fun onLoaded(p0: String?) {
            Log.d(TAG, "onLoaded called")
        }

        override fun onVideoEnded() {
            Log.d(TAG, "onVideoEnded called")
        }

        override fun onError(p0: YouTubePlayer.ErrorReason?) {
            Log.d(TAG, "onError called")
            Log.d(TAG, p0.toString())
        }
    }
```

　onInitializationSuccessに次のコードを書きます。

```
youTubePlayer?.setPlayerStateChangeListener(playerStateChangeListener)
youTubePlayer?.setPlaybackEventListener(playbackEventListener)
```

　上手くいけば、動画を再生したり止めたりするたびに先述したメソッドがログに出力されると思います。これによって、細かい挙動の違いや仕様をより理解できると思うのでぜひ試してみてください。また、ログの部分に処理を記述することで実用化することが出来ます。参考にしてみてください。
#参考文献
　youtubeAPI公式リファレンス
https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/package-summary