简体   繁体   English

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

[英]How to detect fullscreen mode using AVPlayerViewController in Swift?

I am trying to detect when the AVPlayerViewController is in full-screen mode, but I'm having a difficult time achieving this.我试图检测AVPlayerViewController何时处于全屏模式,但我很难实现这一点。 I'd like to know when the user selects the expand button to enter full screen as shown here:我想知道用户何时选择展开按钮进入全屏,如下所示:

在此处输入图片说明

I've added the appropriate observer per these suggestions:我已经根据这些建议添加了适当的观察者:

  1. Detect Video playing full screen in Portrait or landscape 检测纵向或横向全屏播放的视频
  2. How to detect fullscreen mode of AVPlayerViewController 如何检测 AVPlayerViewController 的全屏模式

The appropriate code:相应的代码:

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

However, it never seems to reach the code print("Full Screen") .但是,它似乎永远不会到达代码print("Full Screen") It's hitting print("Normal Screen") regardless of whether the player is in normal or full screen mode.无论播放器处于正常模式还是全屏模式,它都会点击print("Normal Screen")

Thanks!谢谢!

Starting from iOS 12 we can use these AVPlayerViewControllerDelegate delegate methods :从 iOS 12 开始,我们可以使用这些AVPlayerViewControllerDelegate委托方法:

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

Updated for Swift 3 :为 Swift 3 更新

Add an observer for the playerViewController object: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")
                }
            }
        }
    }
}

Your code helped me handle switching between full screen and back.您的代码帮助我处理全屏和返回之间的切换。

But for the identification part, I just changed it slightly to my requirement.但是对于识别部分,我只是根据我的要求稍微更改了它。

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

Hope this helps.希望这可以帮助。

In iOS11 your screen's safe area will drop to 0 in the event of an AVPlayer going fullscreen.在 iOS11 中,如果 AVPlayer 全屏显示,您屏幕的安全区域将降至 0。 Though it might be an undocumented feature (and therefor potential bug).虽然它可能是一个未记录的功能(因此有潜在的错误)。 I am having a hard time finding more info on it.我很难找到有关它的更多信息。

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

This is a slightly optimized Swift 4.2 version of @Pangu's answer.这是@Pangu 答案的略微优化的 Swift 4.2 版本。 It only detects the change, otherwise the observer is called also when interacting with the video like fast forwarding.它只检测变化,否则在与视频交互(如快进)时也会调用观察者。 I also replaced the "videoBounds" with the AVPlayerViewController.videoBounds keypath to avoid the string and use the window bounds to determine if it's fullscreen or not.我还用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")
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法检测到全屏AVPlayerViewController过渡 - Can't detect fullscreen AVPlayerViewController transitions 如何使用swift ios以全屏模式播放视频? - how to play a video in fullscreen mode using swift ios? 在swift中,如何在AVPlayerViewController中播放视频时检测触摸 - In swift, how to detect touch while playing video in AVPlayerViewController 如何以全屏模式快速打开 VLC - How to open VLC in fullscreen mode in swift 如何以编程方式将 AVPlayerViewController go 全屏显示? - How to make a AVPlayerViewController go to fullscreen programmatically? 使用 AVPlayerViewController 时如何检测用户对字幕的选择 - How to detect user selection of subtitles when using AVPlayerViewController 在 AVPLayerViewController 中添加活动指示器? (注意:当视频处于全屏模式时) - Add activity indicator in AVPLayerViewController ? (Note: When video is in fullscreen mode) 使用 AVPlayerViewController 在 Swift 中播放视频 - Playing video in Swift using AVPlayerViewController 使用 AVPlayerViewController 快速显示字幕 - Displaying subtitles using AVPlayerViewController with swift 如何在Swift中将cornerRadius添加到AVPlayerViewController? - How to add cornerRadius to AVPlayerViewController in Swift?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM