AVPlayerViewController 从全屏返回后停止

AVPlayerViewController stops after returning from full screen

我有一个 AVPlayerViewController,我用 AVPlayer 和一些 AVPlayerItem (iOS 10, Xcode 8, Objective C ). AVPlayerViewController 在某些子视图中呈现 "inline",一切都与本机播放控件完美配合。

当我按下本机全屏按钮时,它也能正常工作并切换到全屏模式(左上角有完成按钮)。

我的问题是,当我从全屏按完成按钮 return 时,播放器出于某种原因停止播放,自行重置,如果我选中 .currentItem,我看到它是 nil.

这里发生了什么?为什么不能 AVPlayerViewController 在切换 from/to 全屏之间保持其 AVPlayerItem

使用@matt 的参考,我看到我所做的不同是设置 AVPlayerViewControllerplayer 属性 没有 AVPlayerItem,并且只之后设置它(依赖于 replaceCurrentItemWithPlayerItem().

换句话说-根据我的经验,您应该使用 URL 或任何 AVPlayerItem 初始化 AVPlayerViewControllerAVPlayer,然后才添加 AVPlayerViewController 作为子视图控制器。

不使用 AutoLayout 的代码:

if let playerView = self.playerView {
    let playerItem = AVPlayerItem(url: self.url)
    let player = AVPlayer(playerItem: playerItem)

    let playerVc = AVPlayerViewController()
    playerVc.player = player

    self.addChildViewController(playerVc)
    playerVc.view.frame = playerView.bounds
    playerView.addSubview(playerVc.view)
    playerVc.didMove(toParentViewController: self)

    player.play()
}

由于AVPlayerViewController的当前行为看起来是在退出全屏时暂停,我们可以通过实现委托在退出时调用play()

class VideoView {

    private var playerViewController: AVPlayerViewController?

    func something() {

        playerViewController = AVPlayerViewController()

        // Other setups

        playerViewController?.delegate = self
    }
}

extension VideoView: AVPlayerViewControllerDelegate {

    func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {

        // The system pauses when returning from full screen, we need to 'resume' manually.
        coordinator.animate(alongsideTransition: nil) { transitionContext in
            self.playerViewController?.player.play()
        }
    }
}

根据上述回答 and the comment

如果您想知道 AVPlayerViewController 是否正在播放,我发现使用此扩展程序很有效

extension AVPlayer {
    var isPlaying: Bool {
        rate != 0 && error == nil
    }
}

 @objc func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        let isPlaying = self.playerViewController.player?.isPlaying ?? false
        // The system pauses when returning from full screen, we need to 'resume' manually.
        coordinator.animate(alongsideTransition: nil) { _ in
            if isPlaying {
                self.playerViewController.player?.play()
            }
        }
    }

以上解决方案将始终在退出全屏时播放视频,即使暂停也是如此。

添加这个来修复它:

func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    let 获取播放状态 = self.parent.player.isPlaying
    
       // The system pauses when returning from full screen, we need to 'resume' manually.
       coordinator.animate(alongsideTransition: nil) { transitionContext in
           if 获取播放状态 {
               self.parent.player.play()
           }
       }
   }

extension AVPlayer {
    var isPlaying: Bool {
        return rate != 0 && error == nil
    }
}