检测 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。它总是调用成为全屏或存在全屏的两个事件
因为我们应该使用didBecomeVisibleNotification
和didBecomeHiddenNotification
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 的答案非常适合检测出现在包含UIWebView
的UIViewController
顶部的任何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 上变为全屏的主要内容,如果未能解决你的问题,请参考以下文章
为啥 HTML5 视频不能在 IOS 8 WebApp(webview) 中播放?