AVPlayer: Background audio stops when home button is pressed, but plays with locked screen

Stack Overflow is becoming less and less responsive each time... Hopefully it's not so bad for everybody out there. I've found nothing to respond why is it that the video is paused after hitting the Home button, however, I've come with a workaround if it's of help to anyone:

Since the player is playing until the app goes to the background, i've created a timer, to check if the app was playing while it was in the foreground, if so, resume playback:

- (void)applicationWillResignActive:(UIApplication *)application
{
    MainViewController* mainController=self.viewController;
    playerWasPlaying=mainController.player.rate!=0;
}

-(void)resumePlayback {
    MainViewController* mainController=self.viewController;
    if (mainController.player.rate==0&&playerWasPlaying)
        [mainController play:nil];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(resumePlayback) userInfo:nil repeats:NO];
}

Not the best option in my opinion, but for now it's working, with a little jump in the playback while it resumes.


See this link from Apple documentation, and read the Special Considerations for Video Media part. Here is explained why video is pausing and how you can avoid that. It helped me. I tried both options, and both work well.


Swift 3

First register for notification when your app goes to background and comes back:

NotificationCenter.default.addObserver(self, selector: #selector(appEnteredBackgound), name: Notification.Name.UIApplicationDidEnterBackground, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appEnteredForeground), name: Notification.Name.UIApplicationWillEnterForeground, object: nil)

Option 1 - remove/add the AVPlayer from its AVPlayerLayer:

func appEnteredBackgound() {
  playerLayer.player = nil
}

func appEnteredForeground() {
  playerLayer.player = player
}

Option 2 - disable/enable video tracks:

func appEnteredBackgound() {
  if let tracks = player.currentItem?.tracks {
    for track in tracks {
      if track.assetTrack.hasMediaCharacteristic(AVMediaCharacteristicVisual) {
        track.isEnabled = false
      }
    }
  }
}

func appEnteredForeground() {
  if let tracks = player.currentItem?.tracks {
    for track in tracks {
      if track.assetTrack.hasMediaCharacteristic(AVMediaCharacteristicVisual) {
        track.isEnabled = true
      }
    }
  }
}