Nadav
Nadav

Reputation: 333

Control audio outside app in iOS

I'm trying to control my audio player from outside of the app, I started an av audio session but it's not playing on the background(worked fine on swift 3),

        do{


        myPlayer =  AVPlayer(url: url!)

        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setCategory(AVAudioSessionCategoryPlayback
            )
            do {
                try audioSession.setActive(true)

            }

        }
        catch {
            print(error)
        }
    }

my main goal is to control play and pause like this: enter image description here

Upvotes: 9

Views: 5612

Answers (1)

Pietro Basso
Pietro Basso

Reputation: 1423

So you are building an app that plays audio on the background using AVPlayer. You should use MPNowPlayingInfoCenter to display the song's metadata on the Lock Screen and Control Center, and use MPRemoteCommandCenter to control the previous/next/play/pause actions on the lock screen and control center.

  • Enable Background Mode for Audio, AirPlay and Picture in Picture in your Target > Capabilities.
  • If you're streaming audio from the web, enable Background Mode for Background Fetch too.

Background Mode for Audio

  • Import AVKit and MediaPlayer dependencies.

Setup your AVPlayer with an AVPlayerItem:

guard let url = URL(string: "http://your.website.com/playlist.m3u8") else {
    return
}
player = AVPlayer(url: url)

Setup your AVAudioSession:

private func setupAVAudioSession() {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)
        debugPrint("AVAudioSession is Active and Category Playback is set")
        UIApplication.shared.beginReceivingRemoteControlEvents()
        setupCommandCenter()
    } catch {
        debugPrint("Error: \(error)")
    }
}

Setup the InfoCenter and the RemoteCommandCenter:

private func setupCommandCenter() {
    MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: "Your App Name"]

    let commandCenter = MPRemoteCommandCenter.shared()
    commandCenter.playCommand.isEnabled = true
    commandCenter.pauseCommand.isEnabled = true
    commandCenter.playCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
        self?.player.play()
        return .success
    }
    commandCenter.pauseCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
        self?.player.pause()
        return .success
    }
}

You can place the setupAVAudioSession() method in your viewDidLoad() method, or in any other place you need it.

If you need to place more info in the MPNowPlayingInfoCenter here's a list of all available properties: General Media Item Property Keys | Apple Developer Documentation

Upvotes: 35

Related Questions