【Android】独自アプリで Youtube の プレイリストをバックグラウンドで再生する

今回は、`android-youtube-player`を使用して、バックグラウンドでプレイリストを再生する Android アプリが作成できたため、実装方法の要点を書き記しておこうと思います。
`android-youtube-player`のライブラリは、以下のリンクで、`README`を翻訳すれば、この記事に書かれていることは、ほぼそのまま書かれています。

https://github.com/PierfrancescoSoffritti/android-youtube-player

要点は良いから、アプリをくれよ！という人は、以下の`Github`にコードを上げたので、`Android Studio` でデバッグ実行すれば、インストールできます！

https://github.com/NagaJun1/AndroidYoutubeBackgroundPlayer

`Google Play Store` での配信は、規約に違反するので、無理ですね！
多分、すぐ削除されます。

## build.gradle
以下追加で、インストール

```build.gradle
dependencies {
  implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:12.1.0'
}
```

## Youtube 動画を再生する

単一の動画の再生だけでよければ、`.xml`の記載だけで実装できます。（以下コードは、サンプルページのコードのコピペです。）
`videoId`に対して、`Youtube`のURLから`?v=`のパラメータの後ろの部分のコピペだけで実装できます。
```activity.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
        android:id="@+id/youtube_player_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        app:enableAutomaticInitialization="true"
        app:videoId="S0Q4gqBUs7c"
        app:autoPlay="true" />

</LinearLayout>
```

### バックグラウンド再生を許可
バックグラウンド再生を許可したい場合は、`MainActivity.kt(もしくは、.java)`側で、以下を実行すれば、非表示でも`Youtube`が流れ続けるはずです。

```MainActivity.kt
this.findViewById<YouTubePlayerView>(R.id.youtube_player_view)
  .enableBackgroundPlayback(true)
```

### video ID を更新して、再生動画を変更する

以下、コードみたいな実装すれば、既存の`YouTubePlayerView`のビデオを更新できます。
ビデオの更新自体は、`YouTubePlayer.loadVideo(videoId, 0f)`で処理できますが、`YouTubePlayerView`から、`YouTubePlayer`の取得には、`.getYouTubePlayerWhenReady()`で`YouTubePlayer`が初期化されている場合に、`override fun onYouTubePlayer()`を実行する形で処理されるため、少しクセのある書き方になります。

```MainActivity.kt
// 新しい video ID でロードする
val youtubeView = this.findViewById<YouTubePlayerView>(R.id.youtube_player_view)
youtubeView.getYouTubePlayerWhenReady(object : YouTubePlayerCallback {

  // youTubePlayer が初期化済みなら処理
  override fun onYouTubePlayer(youTubePlayer: YouTubePlayer) {
    youTubePlayer.loadVideo(videoId, 0f)
  }
})
```

因みに、私が作ったサンプルだと、`TextEditor`に入力された`videoId`をロードする形と、最近よく聞いているとかいう理由で、janne da arc の曲を直接表示するみたいな実装になっています笑

## プレイリストの再生

ここからが、プレイリスト再生方法についてです。
まず、前提として、`YouTubePlayerView`が、内部的に`.initialize()`されていないことが前提となります。（初期化済みだと、例外になって、起動できません）
`.enableAutomaticInitialization = false`で設定することで、自動的な初期化処理を行わない様にできます。
以下、私が作ったサンプルのコピペです。
`Activity.kt`側で、`playlist`を設定した`IFramePlayerOptions`を生成 -> `YouTubePlayerView.initialize()`の第二引数に生成した`IFramePlayerOptions`を設定して初期化することで、プレイリストを保持する`YouTubePlayerView`が出来上がります。
※因みに、プレイリストID は、URLパラメータの`&list=～`の箇所です。

```PlayListActivity.kt
private fun settingPlayListView() {
  val youtubeView = this.findViewById<YouTubePlayerView>(R.id.youtubePlayListView)

  // ↓ Youtube のプレイリストID
  val playlistId = "PLQD-wlLhjtvrz9SdwbRgjkwodswe9ANqk"

  if(playlistId is String) {
      // プレイリスト指定用オプションを生成
      val option = IFramePlayerOptions.Builder()
          .controls(1)
          .listType("playlist")
          .list(playlistId) // プレイリストID
          .build()

      // 「youtube_player_view」を再構築
      youtubeView.enableBackgroundPlayback(true) // バックグラウンド再生を許可
      youtubeView.initialize(object : AbstractYouTubePlayerListener() {}, option)
  }
}
```

## `YouTubePlayerView` の破棄
一応、`YouTubePlayerView`の仕様的に、Android のライフサイクルに`YouTubePlayerView`を登録する方法もありますが、`.release()`で破棄できるので、`onDestroy()`で`.release()`を処理する方が無難かと思います。

```PlayListActivity.kt
override fun onDestroy() {
  super.onDestroy()

  // 「youtubePlayListView」の破棄
  val youtubeView = this.findViewById<YouTubePlayerView>(R.id.youtubePlayListView)
  youtubeView.release()
}
```

## 課題

どうやら、10分くらい、バックグラウンドで再生していると、勝手に止まるらしい...。
その度に、アプリ開き直さないといけなくなるので、何か、解決方法が必要っぽいですね。

## 感想

Android のアプリで、バックグラウンドで Youtube が再生できるのは、個人的にはめちゃ感動ですね笑
Google の規約的に、こういうアプリは商用利用厳しいですが、技術的に見ると、結構おもしろかった笑
あと、`Kotlin`を初めて触ってみたのですが、意外と書けましたね笑
やってみるもんですね！