2

I am currently using iOS-youtube-player-helper library in our application. There is a view controller, with a YTPlayerView that has an aspect ratio of 16:9, which means it takes only a part of the screen. The video is loaded in medium and no matter how, I could not get it to play in 720P or 1080P. I am certain that these qualities are available, it's just the YTPlayerView forcing the quality based on the video player height. Because this is a library and not direct iframe embed, I cannot use "vq" parameter(specifying vq in playerVars does not seem to work), and setting the quality to be small then change it later does not work either(refer to this issue on GitHub)

Now, given the factor that I cannot make the YTPlayerView to fill up the whole screen, because of UI designing issues. So, is it possible to force the YTPlayerView to play in at least 720P? (Workarounds, changing the library code, ...)

Because this is an app that will be on App Store(and of course we don't want to have any legal disputes with google either), please don't suggest using libraries that are against the Youtube ToC such as XCDYouTubeKit

Many Thanks

Nicholas
  • 747
  • 7
  • 23

1 Answers1

2

I've found a workaround and this works well for me.

First of all, the problems depends by the webView size constructed inside the YTPlayerView. For example if you have a 320x200 playerView, try to forcing your video to 720hd don't work because the iFrame youtube player class re-switch to a better resolution according to your player size (in this case small quality because you have 320x200).

You can see this SO answer that explain this issue.

When you have imported the YTPlayerView class to your project you have two files: YTPlayerView.h and YTPlayerView.m

YTPlayerView.m (Update to work also on iPads)


I've change the function where the webview is initialized with a custom size (4k resolution) and to the last part I've added the possibility to scale the contents and restore the original frame, like this:

- (UIWebView *)createNewWebView {
    CGRect frame = CGRectMake(0.0, 0.0, 4096.0, 2160.0); //4k resolution
    UIWebView *webView = [[UIWebView alloc] initWithFrame:frame];
    //UIWebView *webView = [[UIWebView alloc] initWithFrame:self.bounds];

    webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    webView.scrollView.scrollEnabled = NO;
    webView.scrollView.bounces = NO;

    if ([self.delegate respondsToSelector:@selector(playerViewPreferredWebViewBackgroundColor:)]) {
        webView.backgroundColor = [self.delegate playerViewPreferredWebViewBackgroundColor:self];
        if (webView.backgroundColor == [UIColor clearColor]) {
            webView.opaque = NO;
        }
    }

    webView.scalesPageToFit = YES;
    if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
    {
        CGSize contentSize = webView.scrollView.contentSize;
        CGSize viewSize = self.bounds.size;
        float scale = viewSize.width / contentSize.width;
        webView.scrollView.minimumZoomScale = scale;
        webView.scrollView.maximumZoomScale = scale;
        webView.scrollView.zoomScale = scale;
        // center webView after scaling..
        [webView setFrame:CGRectMake(0.0, self.frame.origin.y/3, 4096.0, 2160.0)];
    } else {
        webView.frame = self.bounds;
    }
    [webView reload];
    return webView;
}

Hope this helps who try to use the Youtube original player in his project.

P.S.: All my tries were did with a swift project and the following vars:

var playerVars:Dictionary =
        ["playsinline":"1",
         "autoplay":"1",
         "modestbranding":"1",
         "rel":"0",
         "controls":"0",
         "fs":"0",
         "origin":"https://www.example.com",
         "enablejsapi":"1",
         "iv_load_policy":"3",
         "showinfo":"0"] 

Using the functions:

self.playerView.load(withVideoId: "Rk6_hdRtJOE", playerVars: self.playerVars)

and the follow method to force the resolution:

self.playerView.loadVideo(byId: "Rk6_hdRtJOE", startSeconds: 0.0, suggestedQuality: YTPlaybackQuality.HD720)

About iPads:

As reported by Edward in comments there was a little problem on iPads, that's because these devices seems don't apply scalesPageToFit. The goal is to check if the device is an iPad, then to scale (zooming out) the scrollView to host the little view bounds. I've tested on my iPad air and it works. Let me know.

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • 1
    Thanks. I'll give it a try tomorrow. – Nicholas Jul 30 '17 at 06:28
  • This solution seems to be only working on iPhones, is there anyway to get it working on iPads as well? – Nicholas Aug 14 '17 at 05:16
  • @Edward You have absolute reason: thank you for your report, I've correct the function to work also on iPads.. – Alessandro Ornano Aug 14 '17 at 15:53
  • Thanks, this new code does work on iPads. However, I am experiencing a problem where the webView of the YTPlayerView is out of the bound of YTPlayerView. In my case, when I inspect the interface, I can see the YTPlayerView being 768 in height and 432 in width, whereas the underlying webView being 2160 and 4096. If I set the YTPlayerView's clipToBounds, the webview is cut, otherwise, my whole screen is filled. Is there anything I might be missing, like a constraint or something? By the way, I'm testing this on both ios 9.0 and 9.3 – Nicholas Aug 15 '17 at 04:17
  • Seems `scalesPageToFit` don't scale the content correctly with iPad devices, let me the time to think to a reasonable workaround to apply manually this scaling.. – Alessandro Ornano Aug 15 '17 at 08:37
  • Have you found a solution yet? – Nicholas Aug 17 '17 at 03:35
  • Yes man, remember that is just a workaround. The scaling is not like the `scalesPageToFit`, maybe the scale calculation could be perfected but it's a good point to start. Let me know your opinion. – Alessandro Ornano Aug 17 '17 at 08:00
  • This is still not working, as my app would crash straight. I managed to embed the webview into a scrollview, then set the zoomscale of the outter scrollview, which also shrank the size of the player controlls, especially on smaller screen. Any suggestions? – Nicholas Aug 19 '17 at 05:26
  • You shouldn't embed the webview into a scrollview, the webview already have the scrollview. The player should be added to a normal view as follow the official [instruction](https://developers.google.com/youtube/v3/guides/ios_youtube_helper?hl=en). Your app crash because the iPad, instead of the iPhone, enlarge and maintain a big size of the webview but stretch the scrollview content. The iPhone replace to the end the webview original size because of `scalePageToFit` function. – Alessandro Ornano Aug 19 '17 at 06:43
  • Please a solution with WKWebView iOS 12 – user924 May 07 '19 at 18:27
  • Be warned: This caused our app to stop responding sometimes. It would get stuck on this line: `UIWebView *webView = [[UIWebView alloc] initWithFrame:frame];` – Jordan H Nov 02 '20 at 20:33