Как определить полноэкранный режим с помощью AVPlayerViewController в Swift?

Я пытаюсь определить, когда AVPlayerViewController находится в полноэкранном режиме, но мне трудно это сделать. Я хотел бы знать, когда пользователь выбирает кнопку расширения, чтобы войти в полноэкранный режим, как показано здесь:

введите здесь описание изображения

Я добавил соответствующего наблюдателя в соответствии с этими предложениями:

  1. Обнаружение воспроизведения видео в полноэкранном режиме в книжной или альбомной ориентации
  2. Как определить полноэкранный режим 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") независимо от того, находится ли проигрыватель в обычном или полноэкранном режиме.

Спасибо!


person Pangu    schedule 09.05.2016    source источник
comment
Здравствуйте, у меня такая же проблема, вы ее уже исправили? Спасибо   -  person Evana    schedule 04.07.2019


Ответы (5)


Обновлено для 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")
                }
            }
        }
    }
}
person Pangu    schedule 05.03.2017

Начиная с iOS 12 мы можем использовать следующие методы делегата AVPlayerViewControllerDelegate:

func playerViewController(AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: UIViewControllerTransitionCoordinator)
func playerViewController(AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator: UIViewControllerTransitionCoordinator)
person Lawliet    schedule 11.11.2019

Ваш код помог мне справиться с переключением между полноэкранным режимом и обратно.

Но что касается части идентификации, я просто немного изменил ее в соответствии со своим требованием.

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

Надеюсь это поможет.

person Vipin Johney    schedule 25.07.2016
comment
но полный размер экрана не соответствует UIScreen.mainScreen().bounds.size - person Vinu David Jose; 15.11.2017

В iOS11 безопасная область вашего экрана упадет до 0 в случае перехода AVPlayer в полноэкранный режим. Хотя это может быть недокументированная функция (и, следовательно, потенциальная ошибка). Мне трудно найти больше информации об этом.

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

person Albert Renshaw    schedule 04.12.2017

Это слегка оптимизированная версия ответа @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")
                }
            }
        }
    }
}
person palme    schedule 07.02.2019