こちらと同じことを行いました。
〈kotlin〉ExoPlayer
こちらの記事とも同様です。
Android Studio: ストリーミング
実機の動作確認は、Android 8.1.0 で行いました。
環境
インターネットに接続する
AndroidManifest.xml
(省略)
<uses-permission android:name="android.permission.INTERNET" />
(省略)
app/build.gradle.kts
android {
(省略)
buildFeatures {
viewBinding = true
}
}
(省略)
dependencies {
(省略)
val mediaVersion = "1.2.0"
implementation("androidx.media3:media3-exoplayer:$mediaVersion")
implementation("androidx.media3:media3-ui:$mediaVersion")
implementation("androidx.media3:media3-exoplayer-dash:$mediaVersion")
}
values/strings.xml
<resources>
<string name="app_name">exo03</string>
<string name="media_url_mp4">https://storage.googleapis.com/exoplayer-test-media-0/BigBuckBunny_320x180.mp4</string>
</resources>
画面
layout/main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">
<androidx.media3.ui.PlayerView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
プログラム
MainActivity.kt
package org.ekzemplaro
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer
import org.ekzemplaro.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var player: ExoPlayer? = null
private var playWhenReady = true //再生・一時停止の状態を保存
private var currentItem = 0 //メディアアイテムのインデックスを保存
private var playbackPosition = 0L //再生位置を保存
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
override fun onStart() {
super.onStart()
initializePlayer()
}
override fun onResume() {
super.onResume()
hideSystemUi() //全画面表示にするために他のUIを非表示にする
}
private fun hideSystemUi() {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowInsetsControllerCompat(window, binding.videoView).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
private fun initializePlayer(){
player = ExoPlayer.Builder(this)
.build()
.also { exoPlayer ->
binding.videoView.player = exoPlayer
val mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp4))
exoPlayer.setMediaItem(mediaItem)
exoPlayer.playWhenReady = playWhenReady
exoPlayer.seekTo(currentItem, playbackPosition) //特定のアイテムの特定の位置から開始
exoPlayer.prepare()
}
}
override fun onPause() {
super.onPause()
}
override fun onStop() {
super.onStop()
releasePlayer()
}
private fun releasePlayer() {
//playerを破棄する前に情報を保存しておき、中断したところから再開できるようにする。
player?.let { exoPlayer ->
playbackPosition = exoPlayer.contentPosition
currentItem = exoPlayer.currentMediaItemIndex
playWhenReady = exoPlayer.playWhenReady
exoPlayer.release()
}
player = null
}
}