Wednesday, March 2, 2011

Auto Play youtube video in iPhone / iPad


Playing a youtube video in iOS sdk can be done in two ways:
1) Invoke the native youtube player in the device.
2) Open the youtube video link in a WebView.
3) Autoplay the youtube video using WebView .

Method 1:
This method utilizes the Apple's URLScheme to play youtube video by launching the youtube application on the device. This involves a simple call to the openURL method of UIApplication class as below:

NSURL *url=[NSURL URLWithString:@"http://www.youtube.com/v/IkvXcvb7rkg?f=user_favorites&app=youtube_gdata\"];
[[UIApplication sharedApplication] openURL:url];



This method may seem easy, but it's at the cost that the video will be played in other application
and your application will not be called even after the video playing is finished.
There is no other way to return to your application after video playing is done.

Method 2:
This method involved a little bit of tweak around the UIWebView control.
In this method a youtube embed code is constructed and is loaded in the WebView control in the application.
The WebView displays the video thumbnail and a play button over the thumbnail. As the user taps on the play
button the video is launched in QuickTime player and after the video playing is done, control is returned to the application.



                                                           (YouTube video in WebView with play button )

So, with a little bit of tweak we can retain the control in the application.

    NSString *htmlString =@"<html><head>"
        "<meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = no, width = 212\"/></head>"
        "<body style=\"background:#FFFFF;margin-top:20px;margin-left:0px\">"
        "<div><object width=\"320\" height=\"240\">"
        "<param name=\"wmode\" value=\"transparent\"></param>"
        "<embed src=\"http://www.youtube.com/v/Hu684V2lB3Q?f=user_favorites&app=youtube_gdata\""
        "type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"320\" height=\"240\"></embed>"
        "</object></div></body></html>";

    [webView loadHTMLString:htmlString baseURL:nil];



Method 3:
This method takes takes the 'Method 2' one step ahead by utilizing the delegate methods of WebView control
to auto play the video in QuickTime player as soon as the WebView loading is finished.



(Playing video in QuickTime player)


You need to assign the class as WebView delegate:

webView.delegate=self;

The idea is to find the play button on the WebView and send the button touch event to the control to play the video.

Complete code will look like this:

    NSString *htmlString =@"<html><head>"
        "<meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = no, width = 212\"/></head>"
        "<body style=\"background:#FFFFF;margin-top:20px;margin-left:0px\">"
        "<div><object width=\"320\" height=\"240\">"
        "<param name=\"wmode\" value=\"transparent\"></param>"
        "<embed src=\"http://www.youtube.com/v/Hu684V2lB3Q?f=user_favorites&app=youtube_gdata\""
        "type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"320\" height=\"240\"></embed>"
        "</object></div></body></html>";

    webView.delegate=self;
    [webView loadHTMLString:htmlString baseURL:nil];
   
- (void)webViewDidFinishLoad:(UIWebView *)_webView {
    UIButton *b = [self findButtonInView:_webView];
    [b sendActionsForControlEvents:UIControlEventTouchUpInside];
}

- (UIButton *)findButtonInView:(UIView *)view {
    UIButton *button = nil;
   
    if ([view isMemberOfClass:[UIButton class]]) {
        return (UIButton *)view;
    }
   
    if (view.subviews && [view.subviews count] > 0) {
        for (UIView *subview in view.subviews) {
            button = [self findButtonInView:subview];
            if (button) return button;
        }
    }
    return button;
}

I prefer Method 3 over all the methods but you choose the one that suits your need.
Happy coding...

20 comments:

  1. thanks dude.. it helped me a lot. I am an indian working in london on iOS. keep in touch. vamsi.ac@gmail.com

    ReplyDelete
  2. Vamsi, thanks... :)

    SkyEagle, I have not tested in iOS5, but as there is no change in WebView component in iOS5, I think it should work.

    ReplyDelete
  3. thanks...

    one issue is there how to get Done Button Action Here ...

    if ([[[n userInfo]objectForKey:@"MPAVControllerNewStateParameter"] intValue] == 0) {

    While stop it works but done button not working still Play ..

    jetanikalpesh@gmail.com

    }

    ReplyDelete
  4. thanks... but i can't play it. in my webView doesn't load.. in Simulator?? any idea....

    ReplyDelete
  5. Anonymous, You will need a device to test this. Video won't play in Simulator.

    ReplyDelete
  6. Saroj, thant work. but i video's done button clicked my app doesn't work, can't any event..????

    ReplyDelete
  7. how i get done button action....

    ReplyDelete
  8. can't load
    "<embed src=\"%@\"",path;
    i want to load any link, but doesn't load [self.webView loadHTMLString:styledHTML baseURL:nil];

    ReplyDelete
  9. Thanks Saroj,

    1. how i get done button action....
    2 my present view goes to back on rootview
    I am stuck here pls need your hlep.

    ReplyDelete
    Replies
    1. 2 my present view goes to back on root view when video play to finish or dismis by user.

      Delete
  10. can't load
    "<embed src=\"%@\"",path;
    i want to load any link, but doesn't load [self.webView loadHTMLString:styledHTML baseURL:nil];

    ReplyDelete
  11. it works, thanks a lot!

    ReplyDelete
  12. To Check if the playback is finished i used this:

    set the delegate of your webview to self. Implement this:

    - (void)webViewDidFinishLoad:(UIWebView *)_webView {
    UIButton *b = [self findButtonInView:_webView];
    [b sendActionsForControlEvents:UIControlEventTouchUpInside];
    [[[[[UIApplication sharedApplication] keyWindow] subviews] lastObject] setTag:1234]; //tag it
    }

    then start a timer

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];

    and check:

    BOOL playing;
    - (void)onTimer:(NSTimer *)t {
    id _topView = [[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];
    if ([_topView tag]==1234)
    {
    playing=YES;
    }
    else {
    if (playing==YES) { //was playing, but now not anymore
    //dismiss your view, or do other things.
    [t invalidate];
    playing=NO;
    }
    }
    }

    Greets,
    Dannygrob
    happyCoders.nl

    ReplyDelete
  13. Thanks a lot. one question:- Is it works for iOS 5.1? also for 4.2? 4.3? because for me third method works only in iOS 5.0.

    ReplyDelete
  14. I implemented the third method, but my subclasses are:

    Nº de subVistas: 1
    7 clase de la subVista: UIScrollView
    49 Nº de subVistas: 11
    50 clase de la subVista: UIImageView
    51 Nº de subVistas: 0
    52 clase de la subVista: UIImageView
    55 Nº de subVistas: 0
    56 clase de la subVista: UIImageView
    57 Nº de subVistas: 0
    59 clase de la subVista: UIImageView
    60 Nº de subVistas: 0
    61 clase de la subVista: UIImageView
    65 Nº de subVistas: 0
    66 clase de la subVista: UIImageView
    67 Nº de subVistas: 0
    70 clase de la subVista: UIImageView
    71 Nº de subVistas: 0
    72 clase de la subVista: UIImageView
    74 Nº de subVistas: 0
    75 clase de la subVista: UIImageView
    76 Nº de subVistas: 0
    82 clase de la subVista: UIImageView
    83 Nº de subVistas: 0
    84 clase de la subVista: UIWebBrowserView
    86 Nº de subVistas: 0

    14 Nº de subVistas: 1
    15 clase de la subVista: UIScrollView
    16 Nº de subVistas: 11
    17 clase de la subVista: UIImageView
    19 Nº de subVistas: 0
    23 clase de la subVista: UIImageView
    26 Nº de subVistas: 0
    27 clase de la subVista: UIImageView
    28 Nº de subVistas: 0
    29 clase de la subVista: UIImageView
    31 Nº de subVistas: 0
    32 clase de la subVista: UIImageView
    36 Nº de subVistas: 0
    38 clase de la subVista: UIImageView
    39 Nº de subVistas: 0
    40 clase de la subVista: UIImageView
    42 Nº de subVistas: 0
    43 clase de la subVista: UIImageView
    48 Nº de subVistas: 0
    49 clase de la subVista: UIImageView
    50 Nº de subVistas: 0
    51 clase de la subVista: UIImageView
    53 Nº de subVistas: 0
    54 clase de la subVista: UIWebBrowserView
    66 Nº de subVistas: 0


    Cant find no UIButton class in my youtube webView!!!

    ReplyDelete
  15. This method doesn't work on iOS6 anymore. do you have any alternative solution for iOS 6?

    ReplyDelete
  16. how can i convert only player view in landscape mode after completing video return to portrait again.....

    ReplyDelete