Is there a way to show lock screen controls using AVAudioEngine and AVAudioPlayerNode?
Asked Answered
C

1

7

I am handling audio playback using AVAudioEngine and AVAudioPlayerNode in my app, and I want to implement remote controls. Background audio is configured and working.

Control center controls work, but the play/pause button does not update when I play/pause the music from inside the app. I am testing on a real device.

Control center screenshot

Here is my AVAudioSession setup code:

func setupAudioSession() {

    UIApplication.shared.beginReceivingRemoteControlEvents()

    do {
        try AVAudioSession.sharedInstance().setActive(true)
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
    } catch let sessionError {
        print("Failed to activate session:", sessionError)
    }
}

MPRemoteCommandCenter setup:

func setupRemoteControl() {

    let commandCenter = MPRemoteCommandCenter.shared()

    commandCenter.playCommand.isEnabled = true
    commandCenter.playCommand.addTarget { (_) -> MPRemoteCommandHandlerStatus in
        self.audioPlayerNode.play()
        return .success
    }

    commandCenter.pauseCommand.isEnabled = true
    commandCenter.pauseCommand.addTarget { (_) -> MPRemoteCommandHandlerStatus in
        self.audioPlayerNode.pause()
        return .success
    }
}

Lock screen controls - never appeared.

Caracul answered 19/4, 2018 at 16:11 Comment(3)
@matt edited the questionCaracul
@matt yes, everything is playing in the background just fine. Background modes are configured. Maybe some AVAudioEngine special setup I am missing?Caracul
@matt Sure, I can play/pause audio from control center. But the play button icon in control center wouldn't update from "pause icon" to "play icon" if i would go inside my app and pause the audio calling AVaudioPlayerNode.pause() for example, same thing happens in reverseCaracul
C
9

So here is the solution to my problem, I was starting my AVAudioEngine together with its setup function called from viewDidLoad(), that was the issue, and i used .play()/.pause() methods on my AVAudioPlayerNode to manipulate the audio, however AVAudioPlayerNode does not emit master audio, outputNode of AVAudioEngine does.

So whenever you want to play/pause audio from inside your app or from command center, if you are using AVAudioEngine to handle audio in you application, don’t forget to call .stop()/.start() methods on your AVAudioEngine. Lock screen controls should show up and play/pause buttons should update properly in command center/lock screen even without a single property set to MPNowPlayingInfoCenter.default().nowPlayingInfo.

MPRemoteCommandCenter setup:

func setupRemoteControl() {

    let commandCenter = MPRemoteCommandCenter.shared()

    commandCenter.playCommand.isEnabled = true
    commandCenter.playCommand.addTarget { (_) -> MPRemoteCommandHandlerStatus in
        try? self.audioEngine.start()
        return .success
    }

    commandCenter.pauseCommand.isEnabled = true
    commandCenter.pauseCommand.addTarget { (_) -> MPRemoteCommandHandlerStatus in
        self.audioEngine.stop()
        return .success
    }
}
Caracul answered 25/4, 2018 at 17:7 Comment(4)
Please note that if you will be accessing the play/pause command multiple times, it is better to use the AVAudioEngine's pause() method instead of stop().Undesirable
Thank you!!! Had been trying to figure this out for ages. I had just been pausing the individual notes, and not the whole engine.Tympanum
Thank you sweet @anton! I'm using AudioKit, which uses AVAudioEngine and AVAudioPlayerNode, and could not get the UI controls to sync up with MPRemoteCommandCenter. This worked like a charm! I sunk so many hours into trying to figure out why this was happening.Johanson
Update: this is causing problems when pausing from the lock screen while the app is in the background. 5 seconds or so after pausing, when I try to resume/play again, the app crashes due to the AVAudioEngine not running. In my playAudio() command, I do try to start the engine if it's not already running, but that fails. Any ideas? P.S. If I keep everything in the foreground: no problems.Johanson

© 2022 - 2024 — McMap. All rights reserved.