bdalziel bdalziel - 2 months ago 6x
iOS Question

How to white list iOS app for playback of my own restricted videos

We own the YouTube account we're trying to play content from, but playback within our iOS app using the YouTube Helper is being restricted:

iOS playback error

Is this perhaps because of the anonymity of the web view created by the helper?

Can I configure the helper or account differently to unblock the content? I guess I could serve a web view from a whitelisted host, essentially bypassing/re-writing the YouTube helper, but that would not be ideal - extra http request etc..

Thanks in advance


Here is my current understanding and work around.

The Problem

Any kind of access restriction on a channel (whitelist/blacklist etc.) requires that the parent of the iframe be served from a real host. The iOS YouTube Helper Library manually creates a webview into which the iframe is loaded, and so the channel block playback because it isn't possible to restrict playback within the parent (anonymous webview).

This is easily verified for a given channel by pasting an embed for a video from the channel into a simple local HTML page, and loading it into your browser. Playback will be blocked.

The Solution

So, we need a web page that uses the iFrame API served from a not-blacklisted/whitelisted (depending on your channel access control) host. I took the HTML template from the youtube helper library, and parameterized the URL to fill in the params to the template initialization:

new YT.Player('player', %@);

So now rather than loading data from a template HTML string in the helper, I now load a request:

[self.webView loadRequest:req];

The final gotcha is that the "handleHttpNavigationToUrl" condition in the following block was causing Safari to open on page load, so comment out or handle that better:

- (BOOL)webView:(UIWebView *)webView
    shouldStartLoadWithRequest:(NSURLRequest *)request
                navigationType:(UIWebViewNavigationType)navigationType {
  if ([request.URL.scheme isEqual:@"ytplayer"]) {
    [self notifyDelegateOfYouTubeCallbackUrl:request.URL];
    return NO;
  } else if ([request.URL.scheme isEqual: @"http"] || [request.URL.scheme isEqual:@"https"]) {
    return [self handleHttpNavigationToUrl:request.URL];
  return YES;

The New Problem

This work around adds one more delay into the flow of loading a video for the user. The new HTTP request to serve the initial page joins the existing steps of:

  1. Load YouTube iFrame API JS
  2. Load iFrame of player
  3. Begin stream of video initialized into player

All of this, rather than just initializing a native player with a stream URL. Not a great user experience for sure.

I plan on working around it by preloading the page, API and iframe ready for initialization with a video ID on user request.