[iOS 14] My App's AVPlayer has been paused when did enter background

iOS 14 has weird problem.
My App uses AVPlayer and provides background play.
But in iOS 14 AVPlayer has been paused when entering background.
However I tried to it after lock screen it works well only once.

Sometimes start playing in lock screen.

How can solve this problem??


Answered by Media Engineer in 633860022
Does the problem occur in iOS 13? You may want to file a bug report using the feedback assistant.
Code Block
if AVPictureInPictureController.isPictureInPictureSupported(), let player = self.player{
      let layer = AVPlayerLayer.init(player: player);
      self.pipController = AVPictureInPictureController.init(playerLayer: layer);
      self.pipController?.delegate = self;
      print("[\(#function)] create pip player[\(self.player?.description ?? "")] pip[\(self.pipController?.description ?? "")] allow]\(self.playerViewController.allowsPictureInPicturePlayback)]");
      if self.pipController?.isPictureInPicturePossible ?? false{
        self.pipController?.startPictureInPicture();
        print("[\(#function)] start pip[\(self.pipController?.description ?? "")]");
      }
      self.pipObserver = self.pipController?.observe(\AVPictureInPictureController.isPictureInPicturePossible, options: [.new], changeHandler: { (pip, change) in //.initial,
        print("[\(#function)] isPictureInPicturePossible[\(change.newValue.debugDescription ?? "")]");
      });
      //
    }


=>

[startPlayingInPIP()] create pip player[<AVPlayer: 0x281a7f920>] pip[<AVPictureInPictureController: 0x283ce5020>] allow]true]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(true)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(false)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(true)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(false)]
....
[startPlayingInPIP()] isPictureInPicturePossible[Optional(true)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(false)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(true)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(false)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(true)]
[startPlayingInPIP()] isPictureInPicturePossible[Optional(false)]

what's this??
Accepted Answer
Does the problem occur in iOS 13? You may want to file a bug report using the feedback assistant.
I have the same issue with iOS 14, tested on iPhone XR.
BTW, iOS 13 does NOT has this issue.
I have same issue. This is my test code.

Code Block swift
import AVFoundation
import UIKit
final class ViewController: UIViewController {
/* view customed to PlayerView */
  @IBOutlet var playerView: PlayerView!
   
  override func viewDidLoad() {
    super.viewDidLoad()
     
    do {
      try AVAudioSession.sharedInstance().setCategory(.playback)
      try AVAudioSession.sharedInstance().setActive(true)
    } catch {
      print(error)
    }
  }
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
     
    self.playerView.player?.play()
  }
}
final class PlayerView: UIView {
  private var player: AVPlayer?
  private var playerLayer: AVPlayerLayer {
    self.layer as! AVPlayerLayer
  }
   
  override static var layerClass: AnyClass {
    AVPlayerLayer.self
  }
   
  required init?(coder: NSCoder) {
    super.init(coder: coder)
     
    self.addNotificationObserver()
    self.setupPlayer()
  }
   
  func play() {
    self.player?.play()
  }
   
  private func setupPlayer() {
    guard let url = URL(string: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8")
    else { return }
    self.player = AVPlayer(url: url)
    self.playerLayer.player = self.player
  }
}
 
extension PlayerView {
  private func addNotificationObserver() {
    NotificationCenter.default.addObserver(
      self,
      selector: #selector(willEnterForeground(_:)),
      name: UIApplication.willEnterForegroundNotification,
      object: nil
    )
    NotificationCenter.default.addObserver(
      self,
      selector: #selector(didEnterBackground(_:)),
      name: UIApplication.didEnterBackgroundNotification,
      object: nil
    )
  }
   
  @objc
  private func willEnterForeground(_ notification: Notification) {
    self.playerLayer.player = self.player
  }
  @objc
  private func didEnterBackground(_ notification: Notification) {
    self.playerLayer.player = nil
  }
}

I have same issue for my app. It works well in watchOS 6.

I wants to play next audio in WatchOS7, but AVPlayer couldn't play next audio or just play few seconds.
I have never seen this problem at iOS 13
I also had the same problem and I have never seen this problem at iOS 13. Is there a way to solve this problem?
I had the same problem, the app plays the video, goes into the background, comes back a few minutes later, the video goes black, it doesn't work in any way, the phone is XR iOS14
Removing the player on UIApplication.willResignActiveNotification partially fixes the issue

Code Block
    @objc private func onAppWillResignActive() {
        playerLayer.player = nil
    }


This will work almost as in iOS 13 when the app is moved to background, BUT if user locks the device with the app in foreground, the playback will stop.
The only workaround i found for the lock screen issue is to force the player to play shortly after moving to background:

Code Block
    @objc private func onAppDidEnterBackground() {
        playerLayer.player = nil
        if #available(iOS 14, *), player.isPlaying {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                if !self.player.isPlaying { self.player.play() }
            }
        }
    }


However, there are some problems with this approach:
1) There will be a small gap in the playback when moved to background
2) If the media file is not available locally but it's loaded from a remote URL, this approach mai fail, depending on the current buffer state.
3) ...

I had the same problem in iOS14, it works fine in iOS13. I need to reset the video and then fast-forward to the last viewing time, but that's not a good experience for user, any solutions?
We have the exact same issue and what @StaSB prosed works for us, but this bug should be addressed without this workaround.
Is this a bug with iOS 14?


move ***.player = nil;
from applicationDidEnterBackground
to applicationWillResignActive

works with this solution
https://stackoverflow.com/questions/64055966/ios-14-play-audio-from-video-in-background
I had the same problem, the app plays the video, goes into the background, comes back a few minutes later, the video goes black, it doesn't work in any way, the phone is iOS 14

by the way,the video format is m3u8
[iOS 14] My App's AVPlayer has been paused when did enter background
 
 
Q