如何检测 AVPlayerViewController 的全屏模式

Posted

技术标签:

【中文标题】如何检测 AVPlayerViewController 的全屏模式【英文标题】:How to detect fullscreen mode of AVPlayerViewController 【发布时间】:2014-10-12 21:41:42 【问题描述】:

如何检测用户何时按下 AVPlayerViewController 的展开图标? 我想知道电影播放什么时候进入全屏模式。

【问题讨论】:

你有这方面的 Swift 代码吗? ***.com/a/58809976/7113238 可以工作。 【参考方案1】:

也可以观察playerViewController.contentOverlayView 中的bounds 并将其与[UIScreen mainScreen].bounds 进行比较,例如:

self.playerViewController = [AVPlayerViewController new];
// do this after adding player VC as a child VC or in completion block of -presentViewController:animated:completion:
[self.playerViewController.contentOverlayView addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];

...

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context 
    if (object == self.playerViewController.contentOverlayView) 
        if ([keyPath isEqualToString:@"bounds"]) 
            CGRect oldBounds = [change[NSKeyValueChangeOldKey] CGRectValue], newBounds = [change[NSKeyValueChangeNewKey] CGRectValue];
            BOOL wasFullscreen = CGRectEqualToRect(oldBounds, [UIScreen mainScreen].bounds), isFullscreen = CGRectEqualToRect(newBounds, [UIScreen mainScreen].bounds);
            if (isFullscreen && !wasFullscreen) 
                if (CGRectEqualToRect(oldBounds, CGRectMake(0, 0, newBounds.size.height, newBounds.size.width))) 
                    NSLog(@"rotated fullscreen");
                
                else 
                    NSLog(@"entered fullscreen");
                
            
            else if (!isFullscreen && wasFullscreen) 
                NSLog(@"exited fullscreen");
            
        
    

【讨论】:

@PavanMore 在 ios 10 上运行良好,但我仅使用 iOS 9 SDK 对其进行了测试【参考方案2】:

您可以使用 KVO 观察您的 AVPlayerViewController 实例的 videoBounds 属性。

编辑 最基本的例子是

[_myPlayerViewController addObserver:self forKeyPath:@"videoBounds" options:0 context:nil];

【讨论】:

ChrisH 虽然我可以找到注册 KVO 以获取播放器状态的代码,但我似乎找不到将通知 videoBounds 更改的 keyPath。 [self.playerViewController.player addObserver:self forKeyPath:@"status" options:0 context:nil]; - 你用什么代替@"status"? @JohnStewart 你说的是观察playerViewController.playerstatus 属性——你需要观察playerViewControllervideoBounds 属性 ChrisH - 我一直在试验这个解决方案,虽然它确实适用于视频文件,但我发现使用 AVPlayerViewController 播放音频文件时,videoBounds 属性不会改变(合理地如此,因为实际上没有任何视频)。所以我试图找到一种方法来检测在这种情况下对全屏的更改。到目前为止,尝试在 playerViewController.player 的“帧”上进行 KVO 无效。在这种情况下,您可能有什么建议来检测它何时进入全屏状态? 我的应用程序只是处于纵向模式。我必须在播放器全屏后启用所有方向模式才能在横向模式下启用视频。但退出全屏显示一些问题。应用程序处于横向模式,并在播放器从全屏关闭后重置。【参考方案3】:

在 swift 中,无论是音频还是视频:

将此观察者添加到初始化函数中,例如 viewDidLoad 或 didMoveToSuperview:

//Observe if player changed bounds and maybe went to fullscreen
playerController.contentOverlayView!.addObserver(self, forKeyPath: "bounds", options: NSKeyValueObservingOptions.New, context: nil)

这个函数在类上:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) 

    if keyPath == "bounds"        
        let rect = change!["new"] as! NSValue

        if let playerRect: CGRect = rect.CGRectValue() as CGRect 
            if playerRect.size == UIScreen.mainScreen().bounds.size 
                print("Player in full screen")
                isVideoInFullScreen = true
             else 
                print("Player not in full screen")
            
        
    

【讨论】:

最好使用NSKeyValueChangeKey.newKey 而不是new【参考方案4】:

斯威夫特 2.2 创建和使用 AVPlayerViewController 的子类。

class YouVideoPlayer: AVPlayerViewController 

    override func viewDidLayoutSubviews() 
        super.viewDidLayoutSubviews()
        if view.bounds == contentOverlayView?.bounds 
            //code
        
    

【讨论】:

来自文档:“重要的是不要继承 AVPlayerViewController。不支持覆盖此类的方法,并导致未定义的行为。” @Ilya 只要不弄乱内部结构,子类化是可以的【参考方案5】:
self.frameChecker = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkContetnOverlay) userInfo:nil repeats:YES];



    -(void)checkContetnOverlay

        BOOL currentPlayerIsFullscreen = (self.avVideoPlayer.contentOverlayView.frame.size.width>1000 || self.avVideoPlayer.contentOverlayView.frame.size.height>1000);
    //works with these values only for iPad    


        if (((PlayerViewController*)self.parentViewController).playerIsInfullScreen != currentPlayerIsFullscreen) 
            if (currentPlayerIsFullscreen) 
                NSLog(@"CUSTOM PLAYER (av) : changed to fullscreen");

                 self.avVideoPlayer.showsPlaybackControls = YES;
            else
                NSLog(@"CUSTOM PLAYER (av) : changed to minimised");

                self.avVideoPlayer.showsPlaybackControls = YES;
            
        
    

【讨论】:

以上是关于如何检测 AVPlayerViewController 的全屏模式的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 SD 卡何时插入?

如何在张量流对象检测中仅检测特定类别的对象

如何使用 TextRecognizer 检测单词?它只能检测 TextBlocks

如何快速入门深度学习目标检测?

如何计算 OpenCV 人脸检测器的检测分数?

业务系统弱口令如何检测