概要
ExoPlayerは動画・音声再生を便利にするライブラリです
動画プレイヤーを使って再生というサンプルやコード例は多いですが、ボタンを押して音声だけ再生させたいというシンプルな構造をExoPlayerで行うにはどうするかを載せます よりよい方法や間違い・指摘があれば是非ご教授ください
(MediaPlayerでも十分ですが良いライブラリはどんどん使っていきたい)
導入
build.gradle
// android 部分
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
build.gradle
// dependencies 部分
def exoplayer_version = "2.11.6"
implementation "com.google.android.exoplayer:exoplayer:$exoplayer_version"
実装
XML
ただボタンを配置するだけです
ExoPlayerのサンプルのようにPlayerViewなどは使いません
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">
<ImageView
android:id="@+id/audio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="null"
app:srcCompat="@drawable/ic_sound_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
View
MainActivity.kt
package com.example.exoplayersoundonly
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var audioPlayer: SimpleExoPlayer? = null
private val playerEventListener = object : Player.EventListener {
override fun onIsPlayingChanged(isPlaying: Boolean) {
}
override fun onPlayerError(error: ExoPlaybackException) {
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initPlayer(buildMediaSource())
audio.setOnClickListener {
audioPlayer?.playWhenReady = true
}
}
private fun initPlayer(mediaSource: MediaSource?) {
mediaSource ?: return
val trackSelector = DefaultTrackSelector(this)
val loadControl = DefaultLoadControl()
audioPlayer = SimpleExoPlayer.Builder(this).setTrackSelector(trackSelector).setLoadControl(loadControl).build()
audioPlayer?.prepare(mediaSource)
audioPlayer?.addListener(playerEventListener)
audioPlayer?.playWhenReady = false
}
private fun buildMediaSource(): MediaSource? {
return try {
val uri = Uri.parse(SAMPLE_MP3)
val factory = DefaultDataSourceFactory(this, Util.getUserAgent(this, getString(R.string.app_name)))
ProgressiveMediaSource.Factory(factory).createMediaSource(uri)
} catch (e: Exception) {
null
}
}
private fun releasePlayer() {
audioPlayer?.let {
it.stop()
it.release()
audioPlayer = null
}
}
override fun onPause() {
releasePlayer()
super.onPause()
}
companion object {
private const val SAMPLE_MP3 = "http://www.ne.jp/asahi/music/myuu/wave/menuettm.mp3"
}
}
やっていることはとてもシンプルです
- 音声のもとになる
MediaSource
を作る - その
MediaSource
を使ってExoPlayer
インスタンスを生成する - ボタンを押した時に音声が再生されるようにする
- 使わないときは
release
する
だけです
MediaSource作成
ここではMP3のURLからMediaSource
を生成しています ただUri.parse
したものを渡すだけなのでとても簡単です
対応する形式に伴いMediaSource
を指定します 今回はmp3のためProgressiveMediaSourceになります
snippet.kt
private fun buildMediaSource(): MediaSource? {
return try {
val uri = Uri.parse(SAMPLE_MP3)
val factory = DefaultDataSourceFactory(this, Util.getUserAgent(this, getString(R.string.app_name)))
ProgressiveMediaSource.Factory(factory).createMediaSource(uri)
} catch (e: Exception) {
null
}
}
ExoPlayerインスタンスの生成と初期化
snippet.kt
private fun initPlayer(mediaSource: MediaSource?) {
mediaSource ?: return
val trackSelector = DefaultTrackSelector(this)
val loadControl = DefaultLoadControl()
audioPlayer = SimpleExoPlayer.Builder(this).setTrackSelector(trackSelector).setLoadControl(loadControl).build()
audioPlayer?.prepare(mediaSource)
audioPlayer?.addListener(playerEventListener)
audioPlayer?.playWhenReady = false
}
Builderで生成します
その後、
-
#prepare
で対応するMediaSource
をセット -
#addListener
で状態を検知するListenerをセット(任意) -
playWhenReady
で再生・停止の状態を設定 (ここでは初期化のみのためfalse
を指定しています)
とします
再生
onClickされた際にplayWhenReady
をtrue
にします
snippet.kt
audio.setOnClickListener {
audioPlayer?.playWhenReady = true
}
リリース
snippet.kt
private fun releasePlayer() {
audioPlayer?.let {
it.stop()
it.release()
audioPlayer = null
}
}
使わなくなったら停止・リリースしましょう
onPause
やonDestroy
でよく使われます
おわりに
これで音声のみ簡単に再生させることができます
参考になれば幸いです
こちらのレポジトリから簡単にお試しできます