【Android】Kotlin + ExoPlayerで動画再生をやってみる

2020.06.05

kotlinで動画再生をしてみよう

 

 

こんにちは、せんだです。

 

コロナウイルスの影響でステイホームの生活が続いていましたが、茨城は先日緊急事態宣言も解除され徐々に元の生活が戻ってきたなと感じる今日この頃です。

元々アクティブなタイプじゃないので、そこまで窮屈な自粛生活ではなかった気もしますが、やっぱり気持ちの面で違いますね。

 

さて、今回ですが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を使って動画再生を実装する

今回は下記の動作をつくってみます。

  1. MainActivityのPlayボタンをタップ
  2. 別画面でローカルに保存された動画が再生される

 

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

    }
}

ちょこちょこコメントを書いていますが、流れとしては

 

  1. ExoPlayerのインスタンスを生成
  2. データソースを生成
  3. ExoPlayerインスタンスにデータソースを割り当てる

 

という感じになっています。

 

まとめ

今回はKotlinでExoPlayerを使った動画再生をやってみました。VideoViewを使って再生することもできるみたいですが、再生ボタンなどのコントローラなんかも自前で用意する必要があるので、簡単に実装したい場合はExoPlayerが結構おすすめです。

今回はローカルに保存された動画ファイルを再生しましたが、Youtube等オンライン上にある動画ファイルも再生できるので、気になる方は試してみていただければと。

 

それでは、また!!


Top