bigpotato
bigpotato

Reputation: 27507

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)
}

Upvotes: 0

Views: 1191

Answers (1)

JAL
JAL

Reputation: 42449

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.

Upvotes: 1

Related Questions