【问题标题】:How to detect fullscreen mode using AVPlayerViewController in Swift?如何在 Swift 中使用 AVPlayerViewController 检测全屏模式?
【发布时间】:2018-06-07 19:02:59
【问题描述】:

我试图检测AVPlayerViewController 何时处于全屏模式,但我很难做到这一点。我想知道用户何时选择展开按钮进入全屏,如下所示:

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

  1. Detect Video playing full screen in Portrait or landscape
  2. How to detect fullscreen mode of AVPlayerViewController

相应的代码:

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")

谢谢!

【问题讨论】:

  • 您好,我也遇到了同样的问题,您已经解决了吗?谢谢

标签: ios swift avplayer avplayerviewcontroller


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    为 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")
                    }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      但是对于标识部分,我只是根据我的要求稍微改变了它。

      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")
         }
      }
      

      希望这会有所帮助。

      【讨论】:

      • 但全屏尺寸与 UIScreen.mainScreen().bounds.size 不匹配
      【解决方案4】:

      在 iOS11 中,如果 AVPlayer 进入全屏状态,您屏幕的安全区域将降至 0。尽管它可能是一个未记录的功能(因此是潜在的错误)。我很难找到有关它的更多信息。

      [UIApplication sharedApplication].keyWindow.safeAreaLayoutGuide.layoutFrame.size.height == 0?

      【讨论】:

        【解决方案5】:

        这是@Pangu 答案的略微优化的 Swift 4.2 版本。它只检测变化,否则在与视频交互时也会调用观察者,例如快进。我还将“videoBounds”替换为AVPlayerViewController.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")
                        }
                    }
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-08-29
          • 2013-05-21
          • 1970-01-01
          • 2013-09-30
          • 2019-11-03
          • 1970-01-01
          相关资源
          最近更新 更多