MightyMeta

youtube-b

Embedding YouTube Within iPhone Apps

Here is a method I devised for getting YouTube videos to work in a useable and clean way within iPhone Apps. It assumes a basic familiarity with Xcode 4 and Objective-C.

NOTE: I am no longer able to develop/support the code posted in this article, but have left it up here for archive purposes. If anyone is looking for a current way to embed video within their app, they might want to try Mario Hahn’s MHVideoPhotoGallery

 

Embed YouTube in iPhone App

Sample Video “Cycles” by Cyriak Harris

Download Source (.zip package, 33KB)

What This Method Does

There are several offerings out there for embedding YouTube into your app, most of which are variations on the code provided by YouTube themselves, and this is no different. What is new about this approach is that it positions the thumbnail centrally in all device orientations using some tweaked CSS, places the thumbnail against a black background (which is trickier to work out than it sounds), and enables you to pass a video URL dynamically to the embed code.

The example I give launches the video in a modal view, which is useful if you are working with a Tab Bar application or Navigation Controller stack with a portrait-only orientation, but still want to have videos displayed landscape. Using a modal gets around the issue of all views in a Tab Bar application needing to adhere to the same orientation as outlined by Matt Long, or any other orientation problems. You could, of course, adapt the code to remove the use of a modal if you so wished.

The Launcher View

In this example I am using two view controller classes, one that manages a XIB with some ‘view video’ buttons, and then one for the display of the actual video.

First, create a UIViewController subclass with an associated XIB called “VideoLauncherViewController”. In the interface file, add the following:

#import <UIKit/UIKit.h>
#import "VideoViewController.h"

@interface VideoLauncherViewController : UIViewController {

    NSString *videoURL;

}

@property (nonatomic, retain) NSString *videoURL;

- (IBAction) launchVideo;

@end

Nothing too complex here, just a property to hold the URL for the video and a method declaration. Once the property has been synthesized and released, this is how the method should be implemented in VideoLauncherViewController.m:

- (IBAction) launchVideo {

self.videoURL = @"http://youtube.com/embed/-0Xa4bHcJu8";

VideoViewController *videoViewController = [[[VideoViewController alloc] initWithNibName:nil bundle:nil] retain];

videoViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
videoViewController.videoURL = self.videoURL;

[self presentModalViewController:videoViewController animated:YES];

[videoViewController release];
}

You’ll get an error about videoViewController not having a videoURL property, but this will get sorted out once it is added in the next step.

The last section of the URL string, found directly after youtube.com/embed/, can be substituted for that of any YouTube video. Just use the ‘share’ button on the YouTube page to get the relevant code:

Getting a Video URL

Passing this URL value to the next view in the way shown above means you could extend the class to make the choice of video user selected, or altered programatically, for instance.

In the XIB, make a button, and bind it to the method, as shown below (click to enlarge):

Launch Screen XIB

The Video View

Now create a second UIViewController subclass and XIB called “VideoViewController”. Here’s the interface:

#import <UIKit/UIKit.h>

@interface VideoViewController : UIViewController {

    IBOutlet UIWebView *videoView;
    NSString *videoURL;
    NSString *videoHTML;

}

@property(nonatomic, retain) IBOutlet UIWebView *videoView;
@property(nonatomic, retain) NSString *videoURL;
@property(nonatomic, retain) NSString *videoHTML;

- (void) embedYouTube;
- (IBAction) closeModal;

@end

Again, synthesize and release the properties in the implementation, then add these methods:

- (void)embedYouTube {

videoHTML = [NSString stringWithFormat:@"\
<html>\
<head>\
<style type=\"text/css\">\
iframe {position:absolute; top:50%%; margin-top:-130px;}\
body {background-color:#000; margin:0;}\
</style>\
</head>\
<body>\
<iframe width=\"100%%\" height=\"240px\" src=\"%@\" frameborder=\"0\" allowfullscreen></iframe>\
</body>\
</html>", videoURL];

[videoView loadHTMLString:videoHTML baseURL:nil];
}

- (IBAction) closeModal {
[self dismissModalViewControllerAnimated:YES];
}

Lets go through some of that.

First of all we assign a string of HTML code to the videoHTML property, which will be used to embed the video within a UIWebView. The HTML contains some inline CSS for centering the video correctly on the screen. Note that some characters in the string need to be escaped, notably double quotation marks with a backslash ‘\’ and the percent sign with an extra ‘%’. New lines also need to be preceded with a backslash.

Because this is a stringWithFormat, we can also insert dynamic values, so the %@ symbols found within the src=”” attribute are replaced by whatever value is held by the videoURL property, as sent through from the Launcher view, and identified there at the end of the message.

The next step is to add the following to the - (void)viewDidLoad method:

videoView.backgroundColor = [UIColor blackColor];
videoView.opaque = NO;

[self embedYouTube];

This code sorts out the black background mentioned earlier (trying to achieve this in Interface Builder doesn’t work), plus there is a message to run the embed method.

Finally you need to alter - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation so it is simply returning YES to allow for all orientations:

    // Return YES for supported orientations
    return YES;

VideoView XIB

Open the VideoViewController.xib, and drag a UIWebView instance from the library onto the canvas. It should scale to fill the full width and height of the canvas.

Next, download and unzip this button graphic, and add both sizes of the ‘close-dark.png’ image to your project.

Drag a Round Rect Button from the library and place it roughly in the top left corner of your main view.

In the Attributes Inspector, set the Type to ‘Custom’, and the background image for the button as ‘close-dark.png’. Also change the Title to ‘Close’, the text colour to white and the font size to 14.0.

In the Size Inspector, set the X position to 36, the Y position to 24, the width to 60 and the height to 30.

Select File’s Owner and bind the videoView outlet to the UIWebView instance and the closeModal action to the ‘Close’ button.

When you are done, it should look like the example below (click to enlarge):

Edited XIB in Interface Builder

The Result

This should work both in the simulator and an actual device.

When you build and run and tap the button on the launch screen, the modal view is presented with the static video thumbnail.

YouTube Thumbnail

Tapping the thumbnail will play the video fullscreen, which can be viewed in either landscape or portrait orientations. Pressing the blue ‘Done’ button will return the user to the thumbnail screen. Pressing the ‘Close’ button on the thumbnail screen will dismiss this modal view.

YouTube Player Portrait

YouTube Landscape

Conclusion

This method provides a clean and extensible way of embedding YouTube videos in your apps, which should work in most situations.

The source code is released under the BSD 3-Clause License.

If you have any problems with the code, or have improved it in some way, feel free to leave a comment below.

If you enjoyed this post, please consider sharing it using the above buttons, leaving a comment or subscribing to the RSS feed.

48 Comments

  1. Thank you very much!!! it’s great tutorial!!!

    • Glad you found it useful Osman. I’m not entirely satisfied with the result, so will update the post if I come up with any improvements.

  2. Hi, Great tutorial. The problem I am having is this:

    Once I open up the modal view I see the youtube image of the video but once I start playing it all I hear is the audio, no video.

    I basically just grabbed your VideoViewcontroller.h, .m and .xib files and imported them into my workspace. In my own viewcontroller class I call your VideoViewController. Any ideas?

    Your xcode project when I compile and link it runs as expected.

    If you can email me at the supplied email with any insights that would be great!

    Thanks!
    –Chris

    • Hi Chris,

      without seeing your source, if the video is playing but with only audio (and presumably works fine on YouTube), I would have to guess that the issue lies how the video is being decoded. Check that your iPhone Simulator and/or physical device is running the most recent version of iOS.

    • when i click on the play button it not play the video it show
      your browser does not currently recognize any of the video formats available
      please send me suggestion

  3. How could i autorun the video without display a thumbnail ? I used the autorun param but it didn’t work.

    • Not sure there is a way, because of how iOS deals with YouTube videos. You either get to use the in-app thumbnail method as shown in this post, or you provide a http link, which opens in the iOS YouTube app, but doesn’t give you an easy way for the user to return to yours.

      If anyone knows of a solution, let me know!

  4. hi~James Brocklehurst,i’m a new iOS developer,as i wan’t to download your source on this websit,but it doesn’t work,will you please send this sourcecode to my emailbox. laofoot@gmail.com

  5. When i try to view the embedded youtube clip on the simulator or on my iPhone i keep getting the message:
    “Your browser does not currently recognise any of the video formats available. Click here to visit our frequently asked questions about HTML5 Video“
    Anyone else having the same problem or know how to fix it?
    Thanks

  6. worked!! thanks for your help!

  7. The video is playing but won’t rotate to landscape to allow the video to show fullscreen (as shown in the last picture)
    my method:
    – (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
    // Return YES for supported orientations
    return YES;
    }

    Anyone else having the same problem or know how to fix it?
    Thanks

    • Looks like your code is fine, just tried it on the latest SDK and it’s rotating for me.

      Make sure you are editing the method in VideoViewController.m, not VideoLauncherController.m

      Hope that helps.

  8. Thx James your code works fine! But, could you pls tell me how to just use iframe code like: “”?

    In other words, if I am coding for an iPad, your method seems not able to allow me to customize the resolution of the video? Am I right? If not, would you pls tell me how to? Really appreciate your help!!!!

    • The code used in the example above is the iFrame embed code provided by YouTube. It looks different because backwards slashes need to be used to escape certain characters in Objective-C. If you want to change the resolution, you can adjust the width and height attributes, but you will also need to play around with the CSS to get the thumbnail to appear in the right place in both landscape and portrait orientations.

      • I definitely have noticed the “width”&“height”, but they just control the size of the player screen, not the resolution. So how can we switch among different resolution of a particular video? Please help me out… Thank you very much James!!

  9. The iframe code was blocked by the website.
    I mean I want to use the iframe instead of the HTML inline code. The iframe code is what you get once you click on “share” and then “Embed”.

    • The embed code from YouTube doesn’t appear to have any ‘resolution’ parameters, just width and height. If you choose an HD version of the video, you are effectively enlarging the scale of the video since the pixel density of an individual iOS device remains fixed.

      If you are wanting to serve up a higher resolution video for retina display devices, then perhaps CSS media queries will help — WebKit, the engine used to render HTML content on iOS has some queries for detecting retina screens, which allows you to then show or hide blocks of HTML.

      http://www.interactivebynature.net/blog/wordpress/2011.02.23.retina-display-for-mobile-web

      Have tried this with images (works fine), but not with video, so there may be issues. There may be ways out there of doing this using JavaScript too, but I’ve not explored that.

      Good luck!

      • Thank you for your patient reply. But I guess you have misunderstood my meaning. My problem is not unable to get the resource of HD resolution source of a particular video. Your method would bring a default low-definition version of a video to the player (even if this video has an HD version). The video player XCode provides doesn’t allow users to choose resolution. Could you pls help me out? Thx!

  10. @takingf — have looked into this a bit and as far as I can see, you are right, YouTube videos in iOS only play at a low quality, even if a higher res version is available. Presumably this is to save on data charges and battery life, something that Apple are quite keen on promoting in their guidelines.

    I did find this though that might help:

    https://github.com/hellozimi/HCYoutubeParser

    which appears to download the video as an MP4, then play it using the MPMediaPlayer class like you would with a local video file.

  11. Thanks James. Could I ask two more questions? lol
    1. In this method we have to click on two “play” buttons to play the video. One is the blue and white button, and another is the YouTube red and white play button. I wonder if we can set the video autoplay so that we don’t have to click on the YouTube red and white play button.
    2. I wanna show a html at the end of the video, and the size is just the same as player player, so that the html appears like an “ad” when the video finishes playing. Could you pls give me some instuctions about this?

    Really appreciate your great help!!! :)

    • Hi takingf

      This method uses the default iOS implementation of the YouTube API. The options are limited, so basically an autoplay function or some sort of callback for when the video ends (allowing you to trigger a new method) isn’t available. Maybe iOS 6 will introduce some new possibilities.

      So this leaves you with building or extending a custom videoplayer class, much like HCYoutubeParser that I mentioned earlier. That’s beyond the scope of this article, but if you have any luck with it, let us know.

  12. Great Work!

    Works for me, but:

    Is there anyway to make the video autoplay on fullscreen (without the thumbnail screen)?

    I also can’t rotate to landscape. Is there any way to make only this viewController “rotatable” and the others just work on portait?

    • Hi Fábio

      No, you can’t make the video play fullscreen without the thumbnail, as this is the way iOS deals with YouTube at the moment. Seems like a lot of people would like this feature!

      Rotation should work with this method:

      – (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
      {
      // Return YES for supported orientations
      return YES;
      }
      

      but make sure you are setting this in VideoViewController.m, (not VideoLauncherController.m)

  13. when i click on the play button it not play the video it show
    your browser does not currently recognize any of the video formats available
    please send me suggestion its urgent

  14. LOL… It doesn’t work with FLASH on my IPOD. It saids “The Adobe Flash Player or an HTML5 supported browswer is required for video playback”. I clicked it. It showed up Error.

    I knew it. APPLE doesn’t support FLASH.

    • it works fine in ios5 but in ios6 it is not working.movieplayer automatically closed.i got this error.can you please help me?

      2012-10-03 16:20:38.188 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Disabling autoplay for pause
      2012-10-03 16:20:38.188 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Disabling autoplay
      2012-10-03 16:20:38.201 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Skipping autoplay, disabled (for current item: 1, on player: 0)
      2012-10-03 16:20:38.204 lcc-cocos[5020:1bb03] –[CCES2Renderer resizeFromLayer:] : cocos2d: surface size: 480x320
      2012-10-03 16:20:38.502 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Enabling autoplay
      2012-10-03 16:20:38.526 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Likely to keep up or full buffer: 0
      2012-10-03 16:20:38.526 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Skipping autoplay, not enough buffered to keep up.
      2012-10-03 16:20:38.562 lcc-cocos[5020:1bb03] [MPCloudAssetDownloadController] Prioritization requested for media item ID: 0
      2012-10-03 16:20:38.607 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Enabling autoplay
      2012-10-03 16:20:38.627 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Disabling autoplay for pause
      2012-10-03 16:20:38.628 lcc-cocos[5020:1bb03] [MPAVController] Autoplay: Disabling autoplay
      2012-10-03 16:20:38.632 lcc-cocos[5020:1bb03] –[CCES2Renderer resizeFromLayer:] : cocos2d: surface size: 320x450

  15. Hi!!
    When I click on play button it shows “The Adobe Flash Player or an HTML5 supported browswer is required for video playback” even i have installed in my mac.

  16. Hello all.

    It seems that because Apple has removed the YouTube app in iOS6, this method no longer works. Although looking at the dates of some comments it stopped working before iOS6 went live. A quick scout of the web hasn’t offered up any answers so it looks like we’re left hanging until someone produces an alternative.

    If I find one, I’ll post it here.

    If someone else finds or invents a solution, feel free to provide a link.

    • Thanku james.…..the only solution for youtube video displaying in ios6 is using UIWebview????.is it right james?

      • Not sure anymore now that the YouTube app has been removed from iOS6. No obvious solution at present.

  17. Great App and Tutorial, Well Done!

    I have been using similar code with IOS 3, however if doesn’t seem to work with 4.3.

    Two questions:

    What are all of the verbose messages in the log about? Any way to suspend these?

    Is there anyway return to the prior screen in the app when you hit done vs. showing other YouTube video selection.

    Thanks Again

    John

  18. I am using very similar code except when I embed a video I get a play button that is not red but instead grayed out and can’t be clicked. Is anyone else having this problem?

  19. I dont want play button means at the time of url load you tube video automatically plays the video means user dont want to click on the play button

  20. Thank you :)
    You saved me with the /embed/id link :)

  21. Awesome work! Best implementation of this method I have seen and worked flawlessly! Thank you!

  22. Hai to all,

    I requierd code for playing you tube urls for ipad in my application. If any one has code for please forward to me. It really would help to me.

    In the above tutotrial it’s not playing all urls of youtube so please provide any updated codes for me.

    Thanks

  23. Except your given url it’s not working for any other urls of youtube why ? Do we have any other chances .……?

  24. Can this code play live youtube videos?

  25. Cool man… thanks to u i can finish one of my feature on my app…

  26. how to embed multiple videos?

  27. any idea how to auto play video? i set url+?autoplay=1 but still no luck!

  28. Hi, how could I make this work with storyboard?

  29. it is not working now can you help me to know why?

  30. Hi, any one help me from this issues,
    i developed app using json from youtube channel to play inside app,when i play video inside my app it showing this content owner has been blocked this video show watch in youtube. So how to play blocked youtube video inside apple app?

MightyMeta, 8 St Lawrence Lane, Ashburton, Devon, UK, TQ13 7DD

Powered by WordPress | Theme Derived From "Yoko" by by Elmastudio

Scroll To Top