Detect When a Webview Video Becomes Fullscreen on iOS8

Detect when a webview video becomes fullscreen on ios8

This is the work around I found for this..

[[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];

How to intercept video when going to fullscreen in a UIWebView?

There is no public API method to get a pointer to the video player in a UIWebView.

There is, however, an unsafe way to access the video player. Using reflection, you can iterate through the subviews of a UIWebView and attempt to find the player:

- (UIView *)getViewInsideView:(UIView *)view withPrefix:(NSString *)classNamePrefix {
UIView *webBrowserView = nil;
for (UIView *subview in view.subviews) {
if ([NSStringFromClass([subview class]) hasPrefix:classNamePrefix]) {
return subview;
} else {
if((webBrowserView = [self getViewInsideView:subview withPrefix:classNamePrefix])) {
break;
}
}
}
return webBrowserView;
}

- (UIViewController *)movieControllerFromWebView:(UIWebView *)webview {
UIViewController *movieController = nil;
@try {
UIView *movieView = [self getViewInsideView:webview withPrefix:[NSString stringWithFormat:@"MP%@oView", @"Vide"]];
SEL mpavControllerSel = NSSelectorFromString([NSString stringWithFormat:@"mp%@roller", @"avCont"]);
if ([movieView respondsToSelector:mpavControllerSel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
movieController = (UIViewController *)[movieView performSelector:mpavControllerSel];
#pragma clang diagnostic pop
}
}
@catch (NSException *exception) {
NSLog(@"Failed to get movieController: %@", exception);
}

return movieController;
}

This code has been adopted from YouTubeHacks.m.

Your milage may vary, as Apple tends to change the name of their player objects with the different SDKs (MPMoviePlayerController, UIMovieView, MPVideoView, UIMoviePlayerController, etc.). I would look at the MediaPlayer.framework private headers for reference.

How to receive Notification in UIWebView Player for full screen mode in iOS 8?

Below stuff is worked for me.
I hope it will help others!

In your AppDelegate.m class,

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

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

return YES;
}

And receive it by this,

- (void)windowBecameHidden:(NSNotification *)notification {

UIWindow *window = notification.object;

if (window != self.window) {
NSLog(@"Online video on full screen.");
}
}

Thank You!

UIMoviePlayerControllerDidEnterFullscreenNotification doesn't work in iOS8

The implementation by markussvensson has some false alarms, since any UIWindowDidBecomeVisibleNotification is considered as a full screen video playback which is not true.

The implementation "AVPlayerItemBecameCurrentNotification" by Selvin can catch movie playback start, but cannot catch movie playback stop.

So I combined both implementations and it works as expected.

  1. Add observer to both AVPlayerItemBecameCurrentNotification & UIWindowDidBecomeHiddenNotification;

  2. When AVPlayerItemBecameCurrentNotification happens, set a flag;

  3. When UIWindowDidBecomeHiddenNotification happens, check the flag to see if it is a "video stop playing event".

BTW, AVPlayerItemBecameCurrentNotification is undocumented and might be broken for the next iOS major release.

WKWebView Media Player fullscreen detection

This workaround seems to work on iOS8 & iPhone 6

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

...

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

return TRUE;
}

- (void)windowBecameHidden:(NSNotification *)notification {

UIWindow *window = notification.object;

if (window != self.window) { // Not my own window: assuming the video window was hidden, maybe add some more checks here.

// Add code here
}
}

iOS hotspot messes with fullscreen video player status bar

Try this

[[UIApplication sharedApplication] setStatusBarHidden:YES];

Allow UIInterfaceOrientationLandscape during UIWebView video playback

I figured it out. In my 2 methods:

-(void)youTubeStarted:(NSNotification *)notification{
// Entered Fullscreen code goes here..
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = YES;
}

-(void)youTubeFinished:(NSNotification *)notification{
// Left fullscreen code goes here...
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = NO;

//CODE BELOW FORCES APP BACK TO PORTRAIT ORIENTATION ONCE YOU LEAVE VIDEO.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
}

I accessed my App delegate in the above methods by setting the BOOL property of my AppDelegate. Then I called the application method below in my AppDelegate.m:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (self.fullScreenVideoIsPlaying == YES) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else {
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];

}
return orientations;
}
}

The self.fullScreenVideoIsPlaying is a BOOL that I set as a property in my AppDelegate.h file.

I hope this helps others the 5 hours I lost figuring it out.

Webview playback control programmatically for YouTube video in iOS

In viewDidLoad

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

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

and for catch the full screen

#pragma mark - UIMoviePlayerController notification handle

- (void)VideoExitFullScreen:(id)sender{
NSLog(@"Exit from Full Screen..");
}

- (void)VideoEnterFullScreen:(id)sender {
NSLog(@"Enter in Full Screen..");
[web goBack]; //back to notmal webview.. or pause the video
}

Properly force or allow Landscape mode for Youtube embedded video in iOS 8 without NSNotificationCenter

So, after some research and looking more in-depth to this problem.. I came to a solution using the UIWebView delegates, plus I had to solve another issue in terms of my function - (void)playerEnded which it wasn't working properly in the new iPhone 6 devices..

This is how I did it.. First, in my webViewDidFinishLoad method I have added to my webview a javascript evaluation to check when this video player goes into fullscreen mode..

- (void)webViewDidFinishLoad:(UIWebView*)webView
{
// adding listener to webView
[_webView stringByEvaluatingJavaScriptFromString:@" for (var i = 0, videos = document.getElementsByTagName('video'); i < videos.length; i++) {"
@" videos[i].addEventListener('webkitbeginfullscreen', function(){ "
@" window.location = 'videohandler://begin-fullscreen';"
@" }, false);"
@""
@" videos[i].addEventListener('webkitendfullscreen', function(){ "
@" window.location = 'videohandler://end-fullscreen';"
@" }, false);"
@" }"
];
}

Then, in my - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType method, I check when my request url matches the state of the youtube player, like this..
This will fire our function to allow landscape mode or force back to portrait mode.. or maybe any other type of work you might want to do..

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{
// allows youtube player in landscape mode
if ([request.URL.absoluteString isEqualToString:@"ytplayer://onStateChange?data=3"])
{
[self playerStarted];

return NO;
}
if ([request.URL.absoluteString isEqualToString:@"ytplayer://onStateChange?data=2"])
{
[self playerEnded];

return NO;
}
}

And finally, I needed to adjust my playerEnded function to force back portrait mode for iPhone 6 devices..

- (void)playerEnded
{
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];

((AppDelegate*)[[UIApplication sharedApplication] delegate]).videoIsInFullscreen = NO;

[self supportedInterfaceOrientations];

[self shouldAutorotate:UIInterfaceOrientationPortrait];

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
}

Almost, missed I also added these two other functions..

- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotate:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

So, finally I am able to catch the state of the actual player and fire my functions to do some work or whatever I want at the right moment, in my case changing the orientation..

I hope this helps someone else..



Related Topics



Leave a reply



Submit