この記事は
YouTube Android Player APIの謎挙動に振り回されて得た知見を共有する記事です。諸事情で作り直しました。
問題内容
以下のようなYouTube動画を全画面で流すシンプルなアプリを用意します。
class SamplePlayerActivity : YouTubeBaseActivity() {
private val apiKey = "hogehoge" // 実際には公式で発行されたAPIkeyが必要です
private val youtubeId = "H_oGi8uuDpA" // 流したい動画ID
private val videoListener = object : YouTubePlayer.OnInitializedListener { // 初期化リスナーを定義
override fun onInitializationSuccess(provider: YouTubePlayer.Provider?, player: YouTubePlayer?, wasRestored: Boolean) {
if(!wasRestored) player?.loadVideo(youtubeId) // restoreされてなければplayerに動画をロードさせる
}
override fun onInitializationFailure(provider: YouTubePlayer.Provider?, error: YouTubeInitializationResult?) {
// 初期化失敗したときの処理、今回は不要
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.player_activity)
playerView.initialize(apiKey, videoListener) // YouTubePlayerViewを初期化
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.google.android.youtube.player.YouTubePlayerView
android:id="@+id/playerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
動画を表示した状態でYouTubeロゴや関連動画をタップしてYouTube公式アプリに遷移後、YouTube公式アプリのほうをキルして戻ってくると、動画プレイヤーが消え黒い画面が残った状態になります。
YouTubeBaseActivity
の他にYouTubePlayerFragment
, YouTubePlayerSupportFragment
で実装しても同様の現象が起きます。
#何故こうなるのか
どうやら公式アプリとYouTube APIは同じプロセスを共有しているらしく、公式アプリをキルするとサンプルアプリ側のYouTubePlayerがrelease()されるようです。
試しにサンプルアプリに戻ってきたところで再度player?.loadvideo(youtubeId)
をする処理を追加してみたところ、
Caused by: java.lang.IllegalStateException: This YouTubePlayer has been released
でアプリが終了します。
そもそもこのYouTubePlayer、公式アプリが無効化されていると初期化時にエラーが発生して動画再生できません。
このことから推察するに、YouTubePlayerは公式アプリの何らかの処理を裏でやりとりして動画再生しており、それがアプリキルによってやりとりが遮断され、結果releaseされたと考えられます。
誰だこんなAPI設計したのは
#対応策
結論
動画再生するときはIntent投げて公式アプリにやってもらいましょう。
(このAPI使っておいて元も子もないですが…)
それ以外の方法
こちらのエラーはYouTubePlayer.ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION
で拾うことができるので、そこからフックして対応することも可能です。
しかし、公式アプリをキル→高速で戻ってくるとplayerがreleaseされず残り、バックグラウンドに移行するとアプリが落ちるのを確認してます。
issueが上がっているのは確認しましたが、2013年から放置されています。。。
一方で、特殊ケースかつ軽微な問題なので気にしないのもありです。
どうしても自分のアプリ内で動画再生したい、かつこの問題もまるっと解決したい場合は、YouTubeStandalonePlayerを使うと回避できることは確認できています。
(理由は不明…)
ただこのYouTubeStandalonePlayer、カスタマイズ性がほぼ皆無でめちゃくちゃ使いづらいです。(再生中のフルスクリーンの切り替えもできない)
動画再生は公式に任せろというYouTubeさんからの強いメッセージを感じます。
#最後に
YouTubeStandalonePlayer以外でも解決できる方法をご存知の方がもしいらっしゃればぜひ教えていただきたいです。