How to autoplay a YouTube video in a UIWebView
Asked Answered
W

5

34

I have seen a lot of posts in here about this issue, but still couldn't find a perfect answer for this problem.

So I have a tableview, and each cell has a play button inside it. When the user tap the play button, I add a UIWebView to this cell, and play a YouTube video.

static NSString *youTubeVideoHTML = @"<html>\
    <body style=\"margin:0;\">\
        <iframe class=\"youtube-player\" type=\"text/html\" width=\"%0.0f\" height=\"%0.0f\" src=\"http://www.youtube.com/embed/%@\" frameborder=\"0\">\
        </iframe>\
    </body>\
    </html>";


- (void)playVideoWithId:(NSString *)videoId {
    NSString *html = [NSString stringWithFormat:youTubeVideoHTML, self.frame.size.width, self.frame.size.height, videoId];

    [self loadHTMLString:html baseURL:nil];
}

The problem:

This code doesn't actually play the video like I want, it just initiate the YouTube player and show it with the YouTube red play button. Only when user tap the red button, the video will start playing.
So user has to tap two buttons until the video starts - not the best user experience...

Like I said I saw many posts about this issue, some not work at all, and some works but with some issues that bugs me.

One of the working solutions I found was in this post by @ilias, he shows how to get this working with loading the HTML from a file (instead of a string like I do), problem with this approche is that for every video I play I need to:
load the htm file -> embed the video Id in it -> write the file to disc -> only now I can play the video.

Strange thing is that this solution only work when you load the web view request from a file, if I try to load the request from a string equal to the file content, that doesn't work.

Weiser answered 30/3, 2013 at 10:59 Comment(5)
<iframe width=\"%f\" height=\"%f\" src=\"%@\" id='videoSize' frameborder=\"0\" autoplay=\"autoplay\" allowfullscreen></iframe>Shipway
include Auto Play in that iFrame TagShipway
@Manohar that does't workWeiser
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStateDidChange:) name:@"MPAVControllerPlaybackStateChangedNotification" object:nil]; Once let me know that you are receiving this notificationShipway
@Manohar: What say using a delegate instead ?Corrective
W
49

Apparently the problem was with the nil base url, when I changed it to resourceURL the autoplay worked.

[self loadHTMLString:html baseURL:[[NSBundle mainBundle] resourceURL]];  

The full code for autoplay youtube videos (again this code mostly based on this post I just changed it to load from a string instead of a file):

static NSString *youTubeVideoHTML = @"<!DOCTYPE html><html><head><style>body{margin:0px 0px 0px 0px;}</style></head> <body> <div id=\"player\"></div> <script> var tag = document.createElement('script'); tag.src = \"http://www.youtube.com/player_api\"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; function onYouTubePlayerAPIReady() { player = new YT.Player('player', { width:'%0.0f', height:'%0.0f', videoId:'%@', events: { 'onReady': onPlayerReady, } }); } function onPlayerReady(event) { event.target.playVideo(); } </script> </body> </html>";  

- (void)playVideoWithId:(NSString *)videoId {
    NSString *html = [NSString stringWithFormat:youTubeVideoHTML, self.frame.size.width, self.frame.size.height, videoId];

    [self loadHTMLString:html baseURL:[[NSBundle mainBundle] resourceURL]];
}
Weiser answered 30/3, 2013 at 18:4 Comment(9)
Hi Eyal: I'm having a problem with your solution. Autoplay isn't working (if I remove the call to playVideo(), things work, but without autoplay). It seems my problem is similar to the one found here: groups.google.com/forum/?fromgroups#!topic/youtube-api-gdata/… . Any ideas? I've tried on Simulator and Device. I just get a "video loading" indicator indefinitely.Linettelineup
Figured it out! Make sure the mediaPlaybackRequiresUserAction property on your UIWebView is set to NO (default is YES)!Linettelineup
It is auto-playing nicely, but the video still opening the Youtube video as full screen (vertical) on my iPhone 5, using iOS6..any other ideas? Just to be clear, the small window appears first, then goes full screen once it begins playing.Cleopatracleopatre
@Weiser Thanks a lot after searching a lot I got this link and it worked for me. Also appreciate your question style. :)Clerihew
Hi Eyal: how could I make the player size auto resize when the orientation is changed? As currently when the page is not playing, and the orientation changed, the view size is not changing. Thank you.Marji
@Weiser can we make this fullscreen on startUndertrick
Autoplay is working for me. Can we make the player full screen and hide the title link of the video?Undertrick
I get "This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release." warning after the video has started. Any ideas?Normand
@Weiser Thanks a lot after searching a lot I got this link and it worked for me. Also appreciate your question style. :) – The iCoder Oct 4 '13 at 6:59 how this one is working for you?can you please help me?Enthusiastic
H
14

The key here is to set playsinline=1 in your iFrame player, and allowsInlineMediaPlayback = true and mediaPlaybackRequiresUserAction = false for your UIWebView. Here's my implementation in Swift:

// Set up your UIWebView
let webView = UIWebView(frame: self.view.frame) // or pass in your own custom frame rect

self.view.addSubview(webView)
self.view.bringSubviewToFront(webView)

// Set properties
webView.allowsInlineMediaPlayback = true
webView.mediaPlaybackRequiresUserAction = false

// get the ID of the video you want to play
let videoID = "zN-GGeNPQEg" // https://www.youtube.com/watch?v=zN-GGeNPQEg

// Set up your HTML.  The key URL parameters here are playsinline=1 and autoplay=1
// Replace the height and width of the player here to match your UIWebView's  frame rect
let embededHTML = "<html><body style='margin:0px;padding:0px;'><script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>function onYouTubeIframeAPIReady(){ytplayer=new YT.Player('playerId',{events:{onReady:onPlayerReady}})}function onPlayerReady(a){a.target.playVideo();}</script><iframe id='playerId' type='text/html' width='\(self.view.frame.size.width)' height='\(self.view.frame.size.height)' src='http://www.youtube.com/embed/\(videoID)?enablejsapi=1&rel=0&playsinline=1&autoplay=1' frameborder='0'></body></html>"

// Load your webView with the HTML we just set up
webView.loadHTMLString(embededHTML, baseURL: NSBundle.mainBundle().bundleURL)
Haya answered 25/6, 2015 at 21:22 Comment(9)
I followed your code exactly but it does not autoplay, has something changed since you write this answer?Interblend
@Interblend what platform/ios version are you using?Haya
@Interblend hmm, let me see if I can reproduce and fix the issue. I've mostly been using YouTube's official YTPlayerView class for things like this, but I can try to fix this answer if it's broken.Haya
@Haya Have you been able to autoplay a fullscreen video with YTPlayerView? If yes, can you tell me how? I'm struggling to find a solution using the YT SDK :\Parasitology
I think something has changed since this answer. I used this code and it displays correctly but it isn't playing automatically.Fabriane
@Fabriane are you using iOS 10? Some users are reporting automatic playback issues on that iOS version.Haya
After some minor tweaks it is playing automatically now. :-)Fabriane
@ryantxr, What are those minor tweaks. Please share.Allegorical
in 2018, iOS 11 where iOS 12 launching is very close, it works like charm. thanksCoot
H
8

Here is full solution:

//
//  S6ViewController.m
//  
//
//  Created by Ökkeş Emin BALÇİÇEK on 11/30/13.
//  Copyright (c) 2013 Ökkeş Emin BALÇİÇEK. All rights reserved.
//

#import "S6ViewController.h"

@interface S6ViewController ()

@end

@implementation S6ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self playVideoWithId:@"sLVGweQU7rQ"];

}




- (void)playVideoWithId:(NSString *)videoId {

     NSString *youTubeVideoHTML = @"<html><head><style>body{margin:0px 0px 0px 0px;}</style></head> <body> <div id=\"player\"></div> <script> var tag = document.createElement('script'); tag.src = 'http://www.youtube.com/player_api'; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; function onYouTubePlayerAPIReady() { player = new YT.Player('player', { width:'768', height:'1024', videoId:'sLVGweQU7rQ', events: { 'onReady': onPlayerReady } }); } function onPlayerReady(event) { event.target.playVideo(); } </script> </body> </html>";

    NSString *html = [NSString stringWithFormat:youTubeVideoHTML, videoId];

    UIWebView *videoView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
    videoView.backgroundColor = [UIColor clearColor];
    videoView.opaque = NO;
    //videoView.delegate = self;
    [self.view addSubview:videoView];

    videoView.mediaPlaybackRequiresUserAction = NO;

    [videoView loadHTMLString:youTubeVideoHTML baseURL:[[NSBundle mainBundle] resourceURL]];
}

@end
Hilltop answered 30/11, 2013 at 18:29 Comment(1)
it's "html" parameter in, isnt it ? : [videoView loadHTMLString:html baseURL:[[NSBundle mainBundle] resourceURL]];Chirlin
S
4
- (void)playVideoWithId:(NSString *)videoId {

NSString *youTubeVideoHTML = @"<html><head><style>body{margin:0px 0px 0px 0px;}</style></head> <body> <div id=\"player\"></div> <script> var tag = document.createElement('script'); tag.src = 'http://www.youtube.com/player_api'; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; function onYouTubePlayerAPIReady() { player = new YT.Player('player', { width:'768', height:'1024', videoId:'%@', events: { 'onReady': onPlayerReady } }); } function onPlayerReady(event) { event.target.playVideo(); } </script> </body> </html>";

NSString *html = [NSString stringWithFormat:youTubeVideoHTML, videoId];

UIWebView *videoView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
videoView.backgroundColor = [UIColor clearColor];
videoView.opaque = NO;
//videoView.delegate = self;
[self.view addSubview:videoView];

videoView.mediaPlaybackRequiresUserAction = NO;

[videoView loadHTMLString:html baseURL:[[NSBundle mainBundle] resourceURL]];
}

I did some correction to the code above.

Supersession answered 8/8, 2014 at 19:32 Comment(0)
V
2

Use following code to play a youtube video in the UIWebView

Here we required "embed link" :

  • Just open your youtube link in browser
  • Right click on video
  • Select option "Get embed code"
  • You'll get output like -

    <iframe width="640" height="390" src="https://www.youtube.com/embed/xtNXZA4XMBY" frameborder="0" allowfullscreen></iframe>
    
  • copy the link in "src" field, this is your embed link

    Now just put this embed link on the place of "YOU_TUBE LINK" in the following code:

    NSString *htmlString = [NSString stringWithFormat:@"<html><head><meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = yes, width = 320\"/></head><body style=\"background:#00;margin-top:0px;margin-left:0px\"><div><object width=\"320\" height=\"480\"><param name=\"movie\" value=\"YOUTUBE_LINK\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"YOUTUBE_LINK\"type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"320\" height=\"480\"></embed></object></div></body></html>"];
    
    [self.webView_youTube loadHTMLString:htmlString baseURL:nil];
    
Venessavenetia answered 15/6, 2015 at 5:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.