如何在Swift中使用AVPlayerViewController检测全屏模式?

时间:2016-05-09 02:39:37

标签: ios swift avplayer avplayerviewcontroller

我正在尝试检测AVPlayerViewController何时处于全屏模式,但我很难实现这一目标。我想知道用户何时选择展开按钮进入全屏,如下所示:

enter image description here

我根据这些建议添加了适当的观察者:

  1. Detect Video playing full screen in Portrait or landscape
  2. How to detect fullscreen mode of AVPlayerViewController
  3. 适当的代码:

    var avWidth:CGFloat = 375
    var avHeight:CGFloat = 300
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
    
        let path = NSBundle.mainBundle().pathForResource("cable pressback", ofType: "mp4")
        let url = NSURL.fileURLWithPath(path!)
        let player = AVPlayer(URL: url)
    
        playerViewController.player = player
    
        playerViewController.view.frame = CGRectMake(0, 100, self.view.frame.size.width, 300)
    
        playerViewController.view.translatesAutoresizingMaskIntoConstraints = true
    
        view.addSubview(playerViewController.view)
    
        self.addChildViewController(playerViewController)
    
        [playerViewController .addObserver(self, forKeyPath:"videoBounds" , options: NSKeyValueObservingOptions.New, context: nil)]
    
    }
    
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)
    {
        print("playerViewController.view.frame = \(playerViewController.view.frame)")
    
        if keyPath == "videoBounds"
        {
            let rect = change!["new"]! as! NSValue
    
            if let newrect = rect.CGRectValue() as CGRect?
            {
                if newrect.width > 0 || newrect.height > 0
                {
                    if avWidth > 0 || avHeight > 0
                    {
                        if newrect.width > avWidth || newrect.height > avHeight
                        {
                            print("Full Screen")
                        }
                        else if newrect.width < avWidth || newrect.height < avHeight
                        {
                            print("Normal screen")
                        }
                    }
                    avWidth = newrect.width
                    avHeight = newrect.height
                }
            }
        }
    }
    

    然而,它似乎永远不会到达代码print("Full Screen")。无论播放器处于正常模式还是全屏模式,它都会print("Normal Screen")

    谢谢!

5 个答案:

答案 0 :(得分:3)

更新了Swift 3

playerViewController对象添加观察者:

playerViewController(self, forKeyPath: "videoBounds", options: NSKeyValueObservingOptions.new, context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{
    if keyPath == "videoBounds"
    {
        if let rect = change?[.newKey] as? NSValue
        {
            if let newrect = rect.cgRectValue as CGRect?
            {
                // 200 is height of playerViewController in normal screen mode
                if newrect.size.height <= 200
                {
                    print("normal screen")
                }
                else
                {
                    print("full screen")
                }
            }
        }
    }
}

答案 1 :(得分:0)

您的代码帮助我处理全屏和背景之间的切换。

但是对于识别部分,我只是稍微改变了我的要求。

let rect = change!["new"] as! NSValue

if let playerRect: CGRect = rect.CGRectValue() as CGRect {         
   if playerRect.size == UIScreen.mainScreen().bounds.size {
      print("Video in full screen")
   } else {
      print("Video not in full screen")
   }
}

希望这有帮助。

答案 2 :(得分:0)

在iOS11中,如果AVPlayer全屏显示,屏幕的安全区域将降至0。虽然它可能是一个未记录的功能(因此可能存在bug)。我很难找到更多信息。

::shadow

答案 3 :(得分:0)

这是@Pangu答案的经过稍微优化的Swift 4.2版本。它仅检测到更改,否则在与视频进行交互(如快速转发)时也会调用观察者。我还用AVPlayerViewController.videoBounds键路径替换了“ videoBounds”以避免字符串,并使用窗口边界确定其是否为全屏显示。

avPlayerViewController.addObserver(self, forKeyPath: #keyPath(AVPlayerViewController.videoBounds), options: [.old, .new], context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == #keyPath(AVPlayerViewController.videoBounds) {
        // detect only changes
        if let oldValue = change?[.oldKey] as? CGRect, oldValue != CGRect.zero, let newValue = change?[.newKey] as? CGRect {
            // no need to track the initial bounds change, and only changes
            if !oldValue.equalTo(CGRect.zero), !oldValue.equalTo(newValue) {
                if newValue.size.height < UIScreen.main.bounds.height {
                   print("normal screen")
                } else {
                   print("fullscreen")
                }
            }
        }
    }
}

答案 4 :(得分:0)

从iOS 12开始,我们可以使用以下AVPlayerViewControllerDelegate委托方法:

func playerViewController(AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: UIViewControllerTransitionCoordinator)
func playerViewController(AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator: UIViewControllerTransitionCoordinator)