Edmund Edmund - 1 year ago 97
Swift Question

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

I'm trying to add a button to the video player that gets added to the view when a video becomes fullscreen from inside of an embedded web browser.

I saw this: Detect when a webview video becomes fullscreen on ios8. However, I think at that point we won't have a pointer to the video player. Perhaps there's a way to loop through all the subviews of the window's view and grab whatever is an instance of AVPlayer?

Ideally I could do something like this:

NSNotificationCenter.defaultCenter().addObserverForName(
UIWindowDidResignKeyNotification,
object: self.view.window,
queue: nil
) { notification in
let window = whatever the window is now
let player = window.methodThatReturnsVideoPlayer
// do stuff with player
let button = UIButton(...)
window.view.addSubView(button)
}

JAL JAL
Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download