How to play audio files synchronously (sequentially... one at a time... one after the other)? Kotlin/Android Studio

42 Views Asked by At

I'm curious how to play audio files synchronously (one at a time) in Kotlin, so there's no overlap during playback.

I do have an (updated) temporary solution listed below:

My current method works as follows:

  1. Create an audio queue for all pending sounds.
  2. Play each subsequent one when the onCompletionListener fires.

But I'm curious if there's a more optimal (read: less verbose) way to do this. Or — if there isn't — am I overlooking any flaws in my current method?

import android.content.Context
import android.media.MediaPlayer
    
//Note: Only Instantiate Once Per Activity
    class ClassAudio {
        //Create A MutableList Comprising Each Sound We Currently Have In The Queue
            private var mvAudioBuffer: MutableList<MediaPlayer> = arrayListOf()

        //Call This Function To Add Audio To The Queue And Play Them Sequentially
            fun mmPlayAudioSynchronously(mvContext : Context, mvAudio: Int) {
                mvAudioBuffer.also{it.add(MediaPlayer.create(mvContext, mvAudio))}.also{if (mvAudioBuffer.size == 1) mmPlayFirst()}
            }
        //Play The First Sound In The Queue If It Exists And It's Not Playing, "Remove" It From The Queue "onCompletion", Then Repeat The Process With The NEW First Sound
            private fun mmPlayFirst() {
                mvAudioBuffer.getOrNull(0)?.let{ if (it.isPlaying) null else it}?.also{it.start()}?.setOnCompletionListener{mvAudioBuffer.removeFirstOrNull()?.release().also{mmPlayFirst()}}
            }
        //Pause All Pending Audio, Release Alotted Resources, And "Clear" It From The Queue
            fun mmStopAllPendingAudio() {
                mvAudioBuffer.also{for (mvSound in it) {mvSound.also{it.pause()}.release()}}.clear()
            }
    }

Then to play the sounds sequentially:

val mvClassAudio : ClassAudio = ClassAudio()
mvClassAudio.mmPlayAudioSynchronously(this, R.raw.audio_file_1)
mvClassAudio.mmPlayAudioSynchronously(this, R.raw.audio_file_2)
mvClassAudio.mmPlayAudioSynchronously(this, R.raw.audio_file_3)

So again, this seems to work, but a less verbose or otherwise "best practices" approach is what I'm looking for.

0

There are 0 best solutions below