检测 webview 视频何时在 ios8 上变为全屏

Posted

技术标签:

【中文标题】检测 webview 视频何时在 ios8 上变为全屏【英文标题】:Detect when a webview video becomes fullscreen on ios8 【发布时间】:2014-11-04 03:47:49 【问题描述】:

我有一个应用程序,用户可以在其中打开 UIWebview 的视频,包括 Youtube 视频。 在 ios7 中,我能够在开始播放或全屏播放时收到通知,这对我向用户显示某些选项和修改界面至关重要。

我以前用这个:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoExitFullScreen:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoEnterFullScreen:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];

但是,从 iOS8 开始,我无法做到这一点。就像 UIWebview 视频不再触发通知一样。但是,正如我测试过的,它仍然是由普通视频、非 Webview 触发的。

知道发生了什么变化吗?

【问题讨论】:

【参考方案1】:

这是我为此找到的解决方法..

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(VideoExitFullScreen:)
                                                 name:UIWindowDidBecomeVisibleNotification
                                               object:self.view.window];

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(VideoEnterFullScreen:)
                                                 name:UIWindowDidBecomeHiddenNotification
                                               object:self.view.window];

【讨论】:

我发现当视频开始全屏播放时会调用 UIWindowDidBecomeVisibleNotification。当视频消失时调用 UIWindowDidBecomeHiddenNotification 我正在 iOS 10 中尝试这个,但这些通知从来没有被我调用过。其他人有同样的问题吗? @BerryBlue 是的。同样的问题。你有没有找到其他方法? @BerryBlue 删除对象:self.view.window,并替换为对象:nil]【参考方案2】:

斯威夫特 5.1:

NotificationCenter.default.addObserver(
    forName: UIWindow.didResignKeyNotification,
    object: self.view.window,
    queue: nil
)  notification in
    print("Video is now fullscreen")


NotificationCenter.default.addObserver(
    forName: UIWindow.didBecomeKeyNotification,
    object: self.view.window,
    queue: nil
)  notification in
    print("Video stopped")

【讨论】:

好吧,它不适用于UIWebView 内的 YouTube iFrame。它总是调用成为全屏或存在全屏的两个事件 因为我们应该使用didBecomeVisibleNotificationdidBecomeHiddenNotification Swift 5 ``` NotificationCenter.default.addObserver(forName: UIWindow.didResignKeyNotification, object: self.view.window, queue: nil) _ in print("Video is now fullscreen") NotificationCenter.default.addObserver(forName: UIWindow.didBecomeKeyNotification, object: self.view.window, queue: nil) _ in print("视频停止") `` 为 swift 5 更新【参考方案3】:

Swift 4.2、iOS 12.1 和 WKWebView 的更新:

override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    // listen for videos playing in fullscreen
    NotificationCenter.default.addObserver(self, selector: #selector(onDidEnterFullscreen(_:)), name: UIWindow.didBecomeVisibleNotification, object: view.window)

    // listen for videos stopping to play in fullscreen
    NotificationCenter.default.addObserver(self, selector: #selector(onDidLeaveFullscreen(_:)), name: UIWindow.didBecomeHiddenNotification, object: view.window)


override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)

    // remove video listeners
    NotificationCenter.default.removeObserver(self, name: UIWindow.didBecomeVisibleNotification, object: view.window)
    NotificationCenter.default.removeObserver(self, name: UIWindow.didBecomeHiddenNotification, object: view.window)


@objc func onDidEnterFullscreen(_ notification: Notification) 
    print("video is now playing in fullscreen")


@objc func onDidLeaveFullscreen(_ notification: Notification) 
    print("video has stopped playing in fullscreen")

【讨论】:

对象:view.window 有时意味着通知不会被观察到。我们可以为对象参数传递 nil,以始终接收通知。【参考方案4】:

@NorthBlast 的答案非常适合检测出现在包含UIWebViewUIViewController 顶部的任何UIWindow。不幸的是,很难过滤出UIWindow 是什么类型的(因为,嗯......你无法真正知道它是视频还是其他类型的窗口)。

我更喜欢过滤 3 种特殊情况,您确定它们是不是视频播放器窗口,它们是:

1) _UIAlertControllerShimPresenterWindow,这是一种在使用警报时出现的窗口(如UIAlertView)。

2) UITextEffectsWindow,在呈现特殊的 iOS 窗口时出现(如共享窗口,UIActivityViewController)。

3) UIRemoteKeyboardWindow 在展示键盘时出现(由于某种原因,这个类只在我使用 Swift 时出现,但在 Objective-C 上却没有......不知道为什么会这样)。

所以要订阅通知,我使用(就像@NorthBlast 所说):

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(windowDidBecomeActive:)
                                             name:UIWindowDidBecomeVisibleNotification
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(windowDidBecomeHidden:)
                                             name:UIWindowDidBecomeHiddenNotification
                                           object:nil];

然后是实现:

- (void)windowDidBecomeActive:(NSNotification *)notification 
    if ( [self isVideoPlayerWindow:notification.object] ) 
        // Do what's needed if it is a video
        // For example, on a live streaming radio app, I would stop the audio if a video is started
    


- (void)windowDidBecomeHidden:(NSNotification *)notification 
    if ( [self isVideoPlayerWindow:notification.object] ) 
        // Do what's needed if it is a video
    


- (BOOL)isVideoPlayerWindow:(id)notificationObject 
    /*
     Define non video classes here, add more if you need it
    */
    static NSArray *nonVideoClasses = @[
        @"_UIAlertControllerShimPresenterWindow",
        @"UITextEffectsWindow",
        @"UIRemoteKeyboardWindow"
    ];

    BOOL isVideo = YES;
    for ( NSString *testClass in nonVideoClasses ) 
        isVideo = isVideo && ! [notificationObject isKindOfClass:NSClassFromString(testClass)];
    

    return isVideo;

【讨论】:

【参考方案5】:

对于快速:

NotificationCenter.default.addObserver(self, selector: #selector(xxx), name: NSNotification.Name.MPMoviePlayerDidExitFullscreen, object: nil)

【讨论】:

这将不再适用于 iOS 9 等。现在已弃用。

以上是关于检测 webview 视频何时在 ios8 上变为全屏的主要内容,如果未能解决你的问题,请参考以下文章

Android webview如何检测何时重新加载

为啥 HTML5 视频不能在 IOS 8 WebApp(webview) 中播放?

检测 UIWebView 何时加载引用文件失败

如何检测 Cordova WebView 何时完全完成加载?

如何检测 UIScrollView 何时变为可滚动?

每次检测 WKWebView 何时完成加载