KMP IOS AVAudioPlayer NPE

If you’re trying to play some sound on the IOS device using KMP, and face NPE while trying to instantiate the AVAudioPlayer instance, you may want to do it another way:

  • Have designated AVAudioEngine for the sound play operation
  • Configure AVAudioSession if you have multiple AVAudioEngines (as we already discussed here)
  • Create AVAudioPlayerNode and attach to our playback engine
  • Play sound on AVAudioPlayerNode

The code will be as follows:

private var playbackEngine: AVAudioEngine = AVAudioEngine()
private val playerNode = AVAudioPlayerNode()

init {
    setupAudioSession()
    setupPlaybackEngine()
}

private fun setupAudioSession() {
    val audioSession = AVAudioSession.sharedInstance()
    try {
        audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, null)
        audioSession.setActive(true, null)
    } catch (e: Exception) {
        println("Failed to set audio session category: ${e.message}")
    }
}

private fun setupPlaybackEngine() {
    playbackEngine.attachNode(playerNode)
    playbackEngine.connect(playerNode, playbackEngine.mainMixerNode, null)
    playbackEngine.prepare()
    try {
        playbackEngine.startAndReturnError(null)
    } catch (e: Exception) {
        println("Failed to start playback engine: ${e.message}")
    }
}

fun playAudio(audioBuffer: AVAudioPCMBuffer) {
    playerNode.scheduleBuffer(audioBuffer, null)
    playerNode.play()
}

Telegram channel

If you still have any questions, feel free to ask me in the comments under this article or write me at promark33@gmail.com.

If I saved your day, you can support me 🤝