我正在iOS上实现画中画。我添加了后台模式功能。当我调用isPictureInPicturePossible时,它返回false并返回错误:
pictureInPictureController failedToStartPictureInPictureWithError Error Domain=AVKitErrorDomain Code=-1001 "Failed to start picture in picture." UserInfo={NSLocalizedDescription=Failed to start picture in picture., NSLocalizedFailureReason=The UIScene for the content source has an activation state other than UISceneActivationStateForegroundActive, which is not allowed.}
但当我记录activationState时,我可以看到它实际上是foregroundActive。知道是什么原因吗?
(在此之前,isPictureInPictureActive返回true,isPictureInPictureSuspended返回false,isPictureInvictureActive返回false。(
我不知道你是否还需要这个。但我遇到了同样的问题,我设法用AVPlayerLayer
解决了它。
这是我的代码(在AVPlayerViewController
中,但也适用于普通的UIViewController(:
extension PlayerContainerViewController: AVPictureInPictureControllerDelegate {
func setupPictureInPicture() {
if AVPictureInPictureController.isPictureInPictureSupported() {
let playerLayer: AVPlayerLayer = AVPlayerLayer()
playerLayer.player = player // player is your AVPlayer
self.view.layer.addSublayer(playerLayer) // <-- Very important
playerLayer.videoGravity = .resizeAspect
playerLayer.frame = self.view.bounds
pipController = AVPictureInPictureController(playerLayer: playerLayer)
pipController?.delegate = self
}
}
func pictureInPictureController(
_ pictureInPictureController: AVPictureInPictureController,
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
) {
completionHandler(true)
}
func pictureInPictureControllerWillStartPictureInPicture(
_ pictureInPictureController: AVPictureInPictureController) {
// Pip starting
}
func pictureInPictureControllerDidStopPictureInPicture(
_ pictureInPictureController: AVPictureInPictureController) {
// Pip stopped
}
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
print("[PIP] (error)")
}
func startPip() {
pipController?.startPictureInPicture()
}
func stopPip() {
pipController?.stopPictureInPicture()
}
}
希望这能有所帮助。
在不访问代码和不了解版本的情况下发表意见有点困难。
我的建议:
检查应用程序是否真的在前台。您可以通过查看内容源的UIScene的激活状态来验证这一点。如果它不是foregroundActive,则无法启动图像中的图像。如果使用的是UISceneDelegate,则可以在sceneWillEnterForeground:方法中检查场景的激活状态。如果使用AppDelegate,则可以在applicationDidBecomeActive:方法中检查场景的激活状态。
如果您使用UISceneDelegate而不是AppDelegate。将其更改为AppDelegate。
在AppDelegate.swift文件中将sceneActivationState设置为foregroundActive:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13.0, *) {
let scene = UIApplication.shared.connectedScenes.first
if let sceneDelegate = scene?.delegate as? SceneDelegate {
sceneDelegate.window?.windowScene?.activationState = .foregroundActive
}
}
return true
}
如果没有要验证的选项。我们将向您提供有关该问题的更多信息。