メディアファイル
(=
音声
・
動画
ファイル)は、
MediaPlayer
クラスを用いて再生する。
メディアファイル
を再生する手順は、以下の通り。
MediaPlayer()
での
MediaPlayer
オブジェクトの生成時、
MediaPlayer
オブジェクトは
Idle
状態から始まる。
メディアファイル
を制御する
プレーヤー
を定義するクラス。
生成した
MediaPlayer
オブジェクトに制御対象の
リソースファイル
を定義することで、
Initialized
状態に遷移させる。
なお、
リソースファイル
は
res
フォルダ内に
Resource Type: raw
の
Android Resource Directory
を作成し、作成したディレクトリ内に配置しておく。
MediaPlayer.setDataSource(
context: Context,
uri: Uri
): Unit
// パラメータ
// context: MediaPlayerを利用するアクティビティオブジェクト(コンテキスト)
// uri: メディアファイルのURI
String型→Uri型の変換
Uri.parse(uriString: String!): Uri!
// パラメータ
// uriString: Uri型に変換するUri文字列
サンプルコード
MainActivity.kt
class MainActivity : AppCompatActivity() {
// MediaPlayerプロパティ
private var _player: MediaPlayer? = null
// アクティビティ初期化時の処理
override fun onCreate(savedInstanceState: Bundle?) {
// メディアファイルのURI文字列
val mediaFileUriStr = "android.resource://${packageName}/${R.raw.<メディアファイル名>}"
// String型 → URI型 への変換
val mediaFileUri = Uri.parse(mediaFileUriStr)
// MediaPlayerがnullでない場合の処理
_player?.let {
// メディアファイルの指定
it.setDataSource(this@MainActivity, mediaFileUri)
MediaPlayerオブジェクトへのリスナ定義
メディアファイル
の準備完了(イベント)
を検知するMediaPlayer.OnPreparedListener
インタフェースを実装したリスナクラスと、
メディアファイル
の再生完了(イベント)
を検知するMediaPlayer.OnCompletionListener
インタフェースを実装したリスナクラスを定義する。
サンプルコード
MainActivity.kt
class MainActivity : AppCompatActivity() {
// MediaPlayerプロパティ
private var _player: MediaPlayer? = null
// アクティビティ初期化時の処理
override fun onCreate(savedInstanceState: Bundle?) {
// MediaPlayerがnullでない場合の処理
_player?.let {
// メディアファイルの準備完了時のリスナ定義
it.setOnPreparedListener(PlayerPreparedListener())
// メディアファイルの再生完了時のリスナ定義
it.setOnCompletionListener(PlayerCompletionListener())
// "メディアファイルの準備完了"イベントを検知するリスナクラス
private inner class PlayerPreparedListener: MediaPlayer.OnPreparedListener {
// "メディアファイルの準備"完了時の処理
override fun onPrepared(mp: MediaPlayer?) {
// "メディアファイルの再生完了"イベントを検知するリスナクラス
private inner class PlayerCompletionListener: MediaPlayer.OnCompletionListener {
// "メディアファイルの再生"完了時の処理
override fun onCompletion(mp: MediaPlayer?) {
インターネットのストリーミング再生
は一般的に処理に負荷がかかるため、
同期
でメディアの再生準備を行うprepare()
メソッドではなく、非同期
で再生準備を行うprepareAsync()
メソッドを用いる。
MediaPlayer.prepareAsync()
サンプルコード
MainActivity.kt
class MainActivity : AppCompatActivity() {
// MediaPlayerプロパティ
private var _player: MediaPlayer? = null
// アクティビティ初期化時の処理
override fun onCreate(savedInstanceState: Bundle?) {
// MediaPlayerがnullでない場合の処理
_player?.let {
// 非同期でのMediaPlayerオブジェクトの準備
it.prepareAsync()
MediaPlayerオブジェクトの解放
MediaPlayer
はシステムリソース
を消費するため、アクティビティ
の終了時(=onDestroy()
)にMediaPlayer
オブジェクトを解放する必要がある。
また、アクティビティクラス
でMediaPlayer
をプロパティとして宣言している場合、MediaPlayer
オブジェクトを確実に解放すると同時にプロパティ
の値をnull
にしておくことが推奨される。
MediaPlayer.release()
サンプルコード
MainActivity.kt
class MainActivity : AppCompatActivity() {
// MediaPlayerプロパティ
// -> オブジェクト解放時はnullにするため、Nullable型で宣言
private var _player: MediaPlayer? = null
// アクティビティ終了時の処理
override fun onDestroy() {
// MediaPlayerがnullでない場合の処理
// -> let関数ブロック内のitは非Nullable型であるため、
// let関数内では_playerの値をnullにできない
_player?.let {
// MediaPlayerが再生中であれば、安全のために停止
if (it.isPlaying) {
// MediaPlayerの停止
it.stop()
// MediaPlayerオブジェクトの解放
it.release()
// MediaPlayerをnullに変更
_player = null
// アクティビティの終了
super.onDestroy()
メディアファイル
の制御を行うMediaPlayer
クラスのメソッドを用いてプレーヤーを操作する。
ただし、メディアファイルの停止
を行うstop()
メソッドを用いた場合、
再度再生
する場合はprepare()
メソッドを用いて再生準備
を行う必要がある。
※上図を参照
メディアファイルの再生・一時停止・停止
メディアファイルの末尾に進む(再生を完了させる)
メディアファイル
の再生を完了させるには、MediaPlayer
クラスの現在セットされているメディアファイル
の再生時間を保持するduration
プロパティを用いてシーク操作
を行う。
なお、メディアファイル
の一時停止(=Paused
状態)中に終了位置までシーク操作
を行った場合、
MediaPlayer
は依然として再生完了
(=PlaybackCompleted
状態)直前のPaused
状態であるため、
start()
メソッドを用いてPlaybackCompleted
状態に遷移させる必要がある。
サンプルコード
kotlin.MainActivity.kt
// MediaPlayerがnullでない場合の処理
MediaPlayer?.let {
// 再生中のメディアファイルの長さ
val duration = it.duration
// 再生位置を末尾に変更
it.seekTo(duration)
// MediaPlayerが再生中でない場合の処理
if (!it.isPlaying) {
// MediaPlayerの再生
it.start()
現在セットされているメディアファイル
をループ
させるには、MediaPlayer
クラスのisLooping
プロパティを操作する。
ループ機能
の実装にあたって、一般的にはトグルスイッチ
が用いられる。
トグルスイッチの実装
トグルスイッチ
はBoolean
型の値を保持するボタンであり、チェックボックス
やラジオボタン
と同様、CompoundButton
クラスを継承している。
CompoundButtonクラス
Boolean
型の値を保持するボタン
を定義するクラス。
サンプルコード
MainActivity.kt
class MainActivity : AppCompatActivity() {
// MediaPlayerプロパティ
// -> オブジェクト解放時はnullにするため、Nullable型で宣言
private var _player: MediaPlayer? = null
// アクティビティ初期化時の処理
override fun onCreate(savedInstanceState: Bundle?) {
// MediaPlayerオブジェクトの生成
_player = MediaPlayer()
// トグルスイッチ
val loopSwitch = findViewById<SwitchMaterial>(R.id.swLoop)
// トグルスイッチをリスナとしてセット
loopSwitch.setOnCheckedChangeListener(LoopSwitchChangedListener())
// ループスイッチの"状態遷移"イベントを検知するリスナクラス
private inner class LoopSwitchChangedListener: CompoundButton.OnCheckedChangeListener {
// "状態遷移"イベント検知時の処理
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
// ループ機能の変更
_player?.isLooping = isChecked