2020 Sep. 20.
2020 Jul. 24.
出典元
https://gumiossan.hatenablog.com/entry/2020/03/06/002802
https://github.com/Gumio/exo-sample-app
https://qiita.com/niusounds/items/cce4ff69f5911908259b
https://codelabs.developers.google.com/codelabs/exoplayer-intro/#0
build.gradle(Module: app)の編集
build.gradle(Module: app)のdependencies { }にExoPlayer2を追記する
implementation 'com.google.android.exoplayer:exoplayer:2.x.x'
最新バージョンサイト exoplayer - Maven - Bintray
build.gradle(Module: app)のandroid { }にJava8を記述する
compileOptions { targetCompatibility JavaVersion.VERSION_1_8 }
// build.gradle(Module: app) apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 defaultConfig { applicationId "fairway.rokkosan.mylearnexoplayer" minSdkVersion 23 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'com.google.android.exoplayer:exoplayer:2.11.7' implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.0' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package YOUR.PACKAGE.PROJECT /* * Almost of these codes are copy from * https://gumiossan.hatenablog.com/entry/2020/03/06/002802 * https://github.com/Gumio/exo-sample-app */ import android.annotation.SuppressLint import android.net.Uri import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.View.* import android.widget.Toast import com.google.android.exoplayer2.ExoPlaybackException import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.SimpleExoPlayer import com.google.android.exoplayer2.ui.PlayerView import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.source.ProgressiveMediaSource import com.google.android.exoplayer2.source.dash.DashMediaSource import com.google.android.exoplayer2.trackselection.DefaultTrackSelector import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private val TAG = "MyLog" private lateinit var playerView: PlayerView private var mySimpleExoPlayer: SimpleExoPlayer? = null private var myPlayWhenReady: Boolean = false private var playbackPosition = 0L private var currentWindow = 0 // set eventListener-object of ExoPlayer2 to a variable. /* * Player.EventListener is public static interface * about Player.EventListener -> * https://exoplayer.dev/listening-to-player-events.html * https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/Player.html * https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/Player.EventListener.html * https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/package-summary.html * ExoPlayer2 is version 2 of ExoPlayer. * Exoplayer version 1 is not used. */ private val playerEventListener = object : Player.EventListener { override fun onIsPlayingChanged(isPlaying: Boolean) { val state = if (isPlaying) "STATE_PLAYING" else "STATE_NOT_PLAYING" Log.d(TAG, "isPlayingChanged: $state") } override fun onPlayerError(error: ExoPlaybackException) { Log.d(TAG, "Error: ${error.message ?: ""}") } override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) { val stateStr = when(playbackState) { SimpleExoPlayer.STATE_IDLE -> "STATE_IDLE" SimpleExoPlayer.STATE_BUFFERING -> "STATE_BUFFERING" SimpleExoPlayer.STATE_READY -> "STATE_READY" SimpleExoPlayer.STATE_ENDED -> "STATE_ENDED" else -> "UNKNOWN" } val strBool = if (playWhenReady) "true" else "false" Log.d(TAG, "state is $stateStr, playWhenReady is ${strBool}") } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // get savedInstances if the Activity is being re-created. if (savedInstanceState != null) { myPlayWhenReady = savedInstanceState.getBoolean("keyPlayWhenReady") playbackPosition = savedInstanceState.getLong("keyPlaybackPositon") Toast.makeText(this, "got playbackPosition: ${playbackPosition.toString()}", Toast.LENGTH_LONG).show() } val strBool: String = if ( myPlayWhenReady) "true" else "false" Log.d(TAG, "onCreating. myPlayWhenReady is ${strBool}") playerView = video_view } override fun onResume() { super.onResume() hideSystemUi() if (mySimpleExoPlayer == null) { initPlayer() } } override fun onStop() { releasePlayer() super.onStop() } override fun onPause() { releasePlayer() super.onPause() } // save values for re-creation of Activity override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putBoolean("keyPlayWhenReady", myPlayWhenReady) outState.putLong("keyPlaybackPositon", playbackPosition) Toast.makeText(this, "saved playbackPosition: ${playbackPosition.toString()}", Toast.LENGTH_LONG).show() } // create ExoPlayer-instance /* * SimpleExoPlayer extends ExoPlayer to add additional high level player functionality. * It prepares and plays media from a variety of sources. * about SimpleExoPlayer -> * https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/SimpleExoPlayer.html */ private fun initPlayer() { val mediaSource = buildMediaSource() val trackSelector = DefaultTrackSelector(this).apply { setParameters(buildUponParameters().setMaxVideoSizeSd()) } mySimpleExoPlayer = SimpleExoPlayer.Builder(this) .setTrackSelector(trackSelector) .build() .apply { setPlayWhenReady(myPlayWhenReady) seekTo(currentWindow, playbackPosition) addListener(playerEventListener) prepare(mediaSource, false, false) } // connect ExoPlayer-instance to UI-PlayerView playerView.player = mySimpleExoPlayer } private fun buildMediaSource(): MediaSource { val dataSourceFactory = DefaultDataSourceFactory(this, "exoplayer-sample-app") // dash media /* val uri = Uri.parse(getString(R.string.media_url_dash)) return DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri) */ // mp4 media val uri = Uri.parse(getString(R.string.media_url_mp4)) return ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri) } private fun releasePlayer() { mySimpleExoPlayer?.let { myPlayWhenReady = it.playWhenReady playbackPosition = it.currentPosition currentWindow = it.currentWindowIndex it.removeListener(playerEventListener) it.release() mySimpleExoPlayer = null } } // Make android-device-UI-screen disappeared for ExoPlayer to use all of screen. // Set off lint-check for "InlinedApi": Using inlined constants on older versions. @SuppressLint("InlinedApi") private fun hideSystemUi() { playerView.systemUiVisibility = ( SYSTEM_UI_FLAG_LOW_PROFILE or SYSTEM_UI_FLAG_FULLSCREEN or SYSTEM_UI_FLAG_LAYOUT_STABLE or SYSTEM_UI_FLAG_IMMERSIVE_STICKY or SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or SYSTEM_UI_FLAG_HIDE_NAVIGATION ) } }
strings.xml
<resources> <string name="app_name">MyLearnExoPlayer</string> <string name="media_url_dash">https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd</string> <string name="media_url_mp4">https://storage.googleapis.com/exoplayer-test-media-0/BigBuckBunny_320x180.mp4</string> </resources>