はじめに
Androidアプリにてふとした要件で動画を再生してほしいと言われたことはありませんか。
ビルトインで動画ファイル内包するのもなぁという思いもありつつあまり手間もかけたくない...
そんな時にあまり手間をかけずに実現するソリューションをご紹介しようと思います!
フォーカスしませんがその他の手段もまとめていますのでご活用いただければ嬉しいです。
今回作るアプリ
(みんな大好きbig buck bunnyです)
全体の流れ
- 動画ファイルをgoogle driveにアップロードする
- google driveからリンクを取得
- composeとexoplayerでgoogle driveの動画を再生する
動画リンクの用意
今回はサクッと試したいということで動画ストレージとしてgoogle driveを利用します。
-
google driveに動画をアップロードし、共有リンクを発行します。
(公開設定を「リンクを知っている人全員」にする必要があります。) -
以下のように共有リンクを変更して動画ファイルへのリンクを取得する。
共有リンク: https://drive.google.com/file/d/<ファイルID>/view?usp=sharing ↓↓↓ 動画リンク: https://drive.google.com/open?id=<ファイルID>
compose と exoplayerでプレイヤーの実装
動画ファイルへのリンクさえ用意できればあとは出回っているサンプル通りにexoplayerを実装するだけです。
manifest対応
<uses-permission android:name="android.permission.INTERNET" />
最新バージョンはこちら参照ください。
media3 = "1.4.0-alpha01"
androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3" }
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3" }
androidx-media3-dash = { module = "androidx.media3:media3-exoplayer-dash", version.ref = "media3" }
@Composable
fun VideoPlayer(modifier: Modifier) {
val context = LocalContext.current
val exoPlayer = remember {
ExoPlayer.Builder(context).build().apply {
playWhenReady = true
setMediaItem(MediaItem.fromUri("google drive 動画ファイルへのリンク"))
prepare()
}
}
AndroidView(
modifier = modifier
.fillMaxWidth()
.aspectRatio(16f / 9f),
factory = {
PlayerView(it).apply {
player = exoPlayer
}
},
)
// イベントに合わせてexoplayer.release()など...
LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) {
exoPlayer.pause()
}
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
exoPlayer.play()
}
}
ビルドして完了!
10分かからずにできたのではないでしょうか!
実際にはexoplayer周りは細かいカスタムが必要になることが多いのでここからが時間かかるというのが本音ですが...
以上が再生までの流れになります!
その他の手段
今回は利用しておりませんが、その他の手段も紹介しておきます。
android-youtube-playerを利用する
後述するライブラリの後継となっているものです。google公式が出しているものではありませんが、star数3.4k(2024/06時点)と高い評価を得ています。
ただ最近更新されていないようなので、プロダクトで利用する場合は慎重に議論する必要がありそうです。
IFrame Player API をWebViewで動かしてYoutube動画を再生できるようにしています。
videoIdの指定だけで簡単に動画再生できます。
uiのカスタムなどもできますが、webViewなので一定の使いづらさはありそうです。
// READMEより
YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);
getLifecycle().addObserver(youTubePlayerView);
youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
@Override
public void onReady(@NonNull YouTubePlayer youTubePlayer) {
String videoId = "S0Q4gqBUs7c";
youTubePlayer.loadVideo(videoId, 0);
}
});
現状Google側が公開しているYoutubeの再生手段はiFrameを使ってwebViewで表示するしかないので、
このライブラリを利用するかこのライブラリを参考にwebViewを自作するかというやり方になりそうです。
youtubeなどからm3u8を取得しexoplayerに流す
exoplayerはHlsMediaSourceなどを使うことでもちろんストリーミング再生することができるためm3u8ファイルなどを準備できれば動画再生できます。
ただし公式docsではyoutube動画を直接exoplayerで再生することはできないと公言しています。
そのためyoutubeからm3u8ファイルを引っこ抜いてこの方法を取ることは裏技的なものなので安易に選択すべきではありません。 (youtubeから取れるかも未検証です。)
今記事で取り上げたのは安易にこの手法を試して欲しくないという思いからです。 (お試しする場合は自己責任でお試しください。)
https://developer.android.com/media/media3/exoplayer/troubleshooting#can-i-play-youtube-videos-directly-with-exoplayer
Can I play YouTube videos directly with ExoPlayer?
No, ExoPlayer cannot play videos from YouTube, such as URLs of the form https://www.youtube.com/watch?v=.... Instead, you should use the YouTube IFrame Player API, which is the official way to play YouTube videos on Android.
YouTube Android Player APIを利用する(非推奨なので注意)
現在このライブラリはセキュリティ的な理由もあり非推奨となっているため利用しないことを強くお勧めします。
https://developers.google.com/youtube/android/player?hl=ja
ちょこちょこ見かけますがYouTubeBaseActivity
などを利用しているサンプルコードは注意が必要です。
参考
https://github.com/android/codelab-exoplayer-intro/tree/main
https://qiita.com/rot-z/items/299ac40361690c51ce1d