AVPictureInPictureController在应用进入后台时不会自动启动画中画功能。

11
使用AVPlayer+AVPlayerLayer+AVPictureInPictureController在运行iOS 14(beta 7)的iPhone上创建自定义视频播放器时,当从UIButton操作调用player.start()后,该视频不会自动进入画中画模式,即使应用程序进入后台。
使用AVPlayerViewController时未能复制此问题,这似乎表明iOS 14中的AVPictureInPictureController存在问题,但我想知道是否有其他人遇到了这个问题并且知道任何解决方法。 我还将此问题提交给了苹果公司,编号为rdar://8620271 示例代码。
import UIKit
import AVFoundation
import AVKit

class ViewController: UIViewController {
    private let player = AVPlayer(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
    private var pictureInPictureController: AVPictureInPictureController!
    private var playerView: PlayerView!
    private var playButton: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        playerView = PlayerView(frame: CGRect(x: 0, y: 44, width: view.bounds.width, height: 200))
        playerView.backgroundColor = .black
        playerView.playerLayer.player = player
        view.addSubview(playerView)

        playButton = UIButton(frame: CGRect(x: view.bounds.midX - 50, y: playerView.frame.maxY + 20, width: 100, height: 22))
        playButton.setTitleColor(.blue, for: .normal)
        playButton.setTitle("Play", for: .normal)
        playButton.addTarget(self, action: #selector(play), for: .touchUpInside)
        view.addSubview(playButton)

        pictureInPictureController = AVPictureInPictureController(playerLayer: playerView.playerLayer)

        do {
            let audioSession = AVAudioSession.sharedInstance()
            try audioSession.setCategory(.playback)
            try audioSession.setMode(.moviePlayback)
            try audioSession.setActive(true)
        } catch let e {
            print(e.localizedDescription)
        }
    }

    @objc func play() {
        player.play()
    }
}

class PlayerView: UIView {
    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer! {
        return layer as? AVPlayerLayer
    }
}
2个回答

12
问题的根本原因实际上有两个:
  1. 在初始化AVPictureInPictureController之前必须调用AVAudioSession.sharedInstance().setActive(true)

  2. AVPlayerLayer的帧大小的宽高比不能大于16:9(作为一个单独的错误进行了记录,rdar://8689203)。

  3. 对于iPad,视频必须与设备的宽度相同(无论是横向还是纵向)。并没有单独的rdar,因为苹果已经承认了其他错误。

(以上示例中不存在第二个问题)
苹果已经承认这些错误,并回复称它们已经或将会得到修复(这是一个罕见的雷达实际上得到答复的案例!)。

1
如何检查AVPlayerLayer的画框尺寸?仍然无法工作。 - ScottyBlades
1
这是非常有趣的见解。我已经注意到我需要设置 playerController.videoGravity = .resizeAspectFill 才能让它正常工作(我的视频是一个竖屏 iPhone 屏幕录制,所以我认为这与纵横比问题有关)。 - DeveloBär

11

从iOS 14.2开始,苹果公司公开了一个API,可以在应用程序进入后台时启动PIP:

if #available(iOS 14.2, *) {
   pictureInPictureController.canStartPictureInPictureAutomaticallyFromInline = true
}

此外,值得注意的是,苹果公司禁止在用户没有手动点击按钮的情况下启动画中画功能。否则将导致应用被拒绝。最好的方法是使用上面提到的苹果API,以避免被拒绝。

1
该死!!!非常感谢!我一整个星期都在尝试找出如何正确地让它工作!! - vanlooverenkoen
这解决了我的一个问题。另外,我必须澄清使用 canStartPictureInPictureAutomaticallyFromInline 不应该导致您的应用被拒绝,因为您实际上没有在用户手动点击按钮之前启动画中画,正如苹果所要求的那样 - iPadOS会这样做,而用户可以在系统设置中禁用此行为。实际上,您应该使用此属性,因为苹果在 WWDC 21 会议的 AVKit 新功能 视频中介绍了它。 - kikiwora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接