10

While playing audio in background mode player controls appears on the lockscreen. How to remove it when the audio has stopped? If try to set:

MPNowPlayingInfoCenter.default().nowPlayingInfo = nil

player is still on the lockscreen, but the fields artist/song are empty

enter image description here

UPD (my code for audiosession):

in AppDelegate:

func setupAudioSession() {

    let audioSession = AVAudioSession.sharedInstance()

    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayback)
        try audioSession.setActive(true)

    } catch {
        print("Setting category to AVAudioSessionCategoryPlayback failed.")
    }
}

in Player class:

private func clearRemotePlayerInfo() { // call after stop button pressed
    try? AVAudioSession.sharedInstance().setActive(false)
    MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
}
Max
  • 636
  • 3
  • 13
  • 28
  • Do you mean by "*when the audio has stopped*" that the audio has finished playing (until the end of the audio file)? – ielyamani Sep 15 '18 at 11:16

2 Answers2

20

TL;DR

Example on Github: https://github.com/JakubMazur/SO52243428


You shouldn't assign nil to this nowPlayingInfo.

What you should do to achieve this is:

  1. Stop your playback (not necessary but it's good to clean up what you've created)
  2. Set your session inactive
  3. Clear nowPlayingInfo

So the code will look like:

self.player?.stop() // Where self.player is AVAudioPlayer
try? self.session?.setActive(false, with: .notifyOthersOnDeactivation) // Where self.session is AVAudioSession. You should do it with do-catch to good error catching.
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]

And it will behave like this:

enter image description here

EDIT:

I've wrote as simple as possible example for try it out. It's available on Github https://github.com/JakubMazur/SO52243428. Feel free to check it out and it it matches your case.

Jakub
  • 13,712
  • 17
  • 82
  • 139
  • thanks a lot for your answer. But I can't get the same result. Fields are cleared but the player area didn't disappear. I will update my question now – Max Sep 14 '18 at 06:16
  • Please see updated answer, I did provide as simple as possible example, it's only in `AppDelegate` for this case and starting point for this will be `didFinishLaunchingWithOptions` – Jakub Sep 14 '18 at 07:53
  • Jakub, look at this: https://streamable.com/0g7ih (launch your project on my device) – Max Sep 14 '18 at 09:31
  • Interesting! Is that iOS 10 or 11? – Jakub Sep 14 '18 at 09:36
  • ios 11 (11.2.5) – Max Sep 14 '18 at 10:03
  • Strange, I cannot reproduce it on iOS 11.4.1 even on slowest device. and unfortunately you can't test it on simulator. I don't have access to 11.2.5 – Jakub Sep 14 '18 at 10:31
  • I'll test it in other version iOS a bit later ) – Max Sep 14 '18 at 10:39
  • It doesn't matter to assign nil or [:] to nowPlayingInfo - result the same. Set session inactive is optional too. It just doesn't work in iOS 11.2.5 and works in 11.4 ) – Max Sep 15 '18 at 10:50
  • Unfortunately, this doesn't seem to work with AVQueuePlayer. – Blago Sep 18 '19 at 19:28
1

It's work for me.

func setupNowPlaying() {
    var nowPlayingInfo = [String : Any]()
    nowPlayingInfo[MPMediaItemPropertyTitle] = "my video"
    if let image = UIImage(named: "video image") {
        nowPlayingInfo[MPMediaItemPropertyArtwork] =
            MPMediaItemArtwork(boundsSize: image.size) { size in
                return image
        }
    }
    let playerItem = self.player?.currentItem
    
    nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = playerItem?.currentTime().seconds
    nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = playerItem?.asset.duration.seconds
    nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = self.player?.rate
 
    
    MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    
    UIApplication.shared.beginReceivingRemoteControlEvents()
    
}


func closeVideo() {
    self.player?.pause()
    
    let sessionAV = AVAudioSession.sharedInstance()
    try? sessionAV.setActive(false, options: AVAudioSession.SetActiveOptions.notifyOthersOnDeactivation)
    
    
    MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
    
    UIApplication.shared.endReceivingRemoteControlEvents()
}
Jake
  • 11
  • 2