【Android】Kotlin + ExoPlayerで動画再生をやってみる
2020.06.05
こんにちは、せんだです。
コロナウイルスの影響でステイホームの生活が続いていましたが、茨城は先日緊急事態宣言も解除され徐々に元の生活が戻ってきたなと感じる今日この頃です。
元々アクティブなタイプじゃないので、そこまで窮屈な自粛生活ではなかった気もしますが、やっぱり気持ちの面で違いますね。
さて、今回ですがKotlinとExoPlayerを使って動画再生をやってみたいと思います。
ExoPlayerはAndroid Developersの公式サイトに書かれている通り、Android SDKとは別で配布されているOSSです。
標準のMediaPlayerではサポートされていないような機能もサポートされていたりと、メディア再生を行う際に重宝する便利なライブラリです。
今回やること
- build.gradleの設定
- ExoPlayerを使った動画再生の実装
環境情報
- macOS Catalina(10.15.4)
- Android Studio(3,6,2)
- Kotlin(1.3)
- Android 10.0 (API Level 29 エミュレータ)
それでは、早速やってみましょう。
build.gradleの設定
build.gradleに下記のcompileOptionsとimplementationを追記します。implementationのバージョンは適宜修正してください。
build.gradle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | android { ... ... compileOptions { targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { ... ... def exoplayer_version = '2.10.5' implementation "com.google.android.exoplayer:exoplayer:${exoplayer_version}" implementation "com.google.android.exoplayer:exoplayer-core:${exoplayer_version}" implementation "com.google.android.exoplayer:exoplayer-dash:${exoplayer_version}" implementation "com.google.android.exoplayer:exoplayer-ui:${exoplayer_version}" } |
ExoPlayerを使って動画再生を実装する
今回は下記の動作をつくってみます。
- MainActivityのPlayボタンをタップ
- 別画面でローカルに保存された動画が再生される
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?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"> <Button android:id="@+id/playButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/exo_controls_play_description" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val button = findViewById<Button>(R.id.playButton) button.setOnClickListener { val intent = Intent(applicationContext, Play::class.java) startActivity(intent) } } } |
ここでは、ボタンをタップした時に動画プレイヤーのActivityに飛ばしているだけです。
続いて、プレイヤー側の処理を書いていきます。
activity_play.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?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=".Play"> <com.google.android.exoplayer2.ui.SimpleExoPlayerView android:id="@+id/player_view" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
SimpleExoPlayerViewというExoPlayerのPlayerViewを定義しています。
Player.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import android.net.Uri import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import com.google.android.exoplayer2.ExoPlayerFactory import com.google.android.exoplayer2.source.ProgressiveMediaSource import com.google.android.exoplayer2.ui.PlayerView import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory class Player : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_play) // 動画ファイルのパスを取得する val uri = Uri.parse( "${applicationContext.filesDir}/videos/test.mp4") // プレイヤーを準備する this.setVideoPlayer(uri) } /* * 動画再生プレイヤーの設定処理 * */ private fun setVideoPlayer(uri: Uri) { // ExoPlayerのインスタンスを生成し、ViewにPlayerをセットする val player = ExoPlayerFactory.newSimpleInstance(this) val playerView = findViewById<PlayerView>(R.id.player_view) playerView.player = player // データソースを設定する val dataSourceFactory = DefaultDataSourceFactory(this, "play-inspect-video") val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri) // 再生準備 player.prepare(mediaSource) // 自動再生の設定 falseの場合はコントローラーの再生ボタンをタップすると再生される player.playWhenReady = true } } |
ちょこちょこコメントを書いていますが、流れとしては
- ExoPlayerのインスタンスを生成
- データソースを生成
- ExoPlayerインスタンスにデータソースを割り当てる
という感じになっています。
まとめ
今回はKotlinでExoPlayerを使った動画再生をやってみました。VideoViewを使って再生することもできるみたいですが、再生ボタンなどのコントローラなんかも自前で用意する必要があるので、簡単に実装したい場合はExoPlayerが結構おすすめです。
今回はローカルに保存された動画ファイルを再生しましたが、Youtube等オンライン上にある動画ファイルも再生できるので、気になる方は試してみていただければと。
それでは、また!!
↓↓↓ぜひチェックしてください
~提供中のヒューマンセンシング技術~
◆人物検出技術
歩行者・来店者数計測やロボット搭載も
https://humandetect.pas-ta.io
◆視線検出技術
アイトラッキングや次世代UIに
https://eyetrack.pas-ta.io
◆生体判定技術
eKYC・顔認証のなりすまし対策を!
https://bio-check.pas-ta.io
◆目検出技術
あらゆる目周りデータを高精度に取得
https://pupil.pas-ta.io
◆音声感情認識技術
会話から怒りや喜びの感情を判定
https://feeling.pas-ta.io
◆虹彩認証技術
目の虹彩を利用した生体認証技術
https://iris.pas-ta.io