Help us understand the problem. What is going on with this article?

ExoPlayerで音声のみ簡単に再生させる方法

概要

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"
    }
}

やっていることはとてもシンプルです

  1. 音声のもとになるMediaSourceを作る
  2. そのMediaSourceを使ってExoPlayerインスタンスを生成する
  3. ボタンを押した時に音声が再生されるようにする
  4. 使わないときは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された際にplayWhenReadytrueにします

snippet.kt
audio.setOnClickListener {
    audioPlayer?.playWhenReady = true
}

リリース

snippet.kt
private fun releasePlayer() {
    audioPlayer?.let {
        it.stop()
        it.release()
        audioPlayer = null
    }
}

使わなくなったら停止・リリースしましょう
onPauseonDestroyでよく使われます

おわりに

これで音声のみ簡単に再生させることができます

参考になれば幸いです

こちらのレポジトリから簡単にお試しできます

他初心者向けの参考

sudo5in5k
しがないAndroiderやってまうs
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした