Ikai Lan, YouTube Developer Relations – April 2014
The youtube-ios-player-helper
is an open source library that helps you embed a YouTube iframe player into an iOS application. The library creates a UIWebView
and a bridge between your application’s Objective-C code and the YouTube player’s JavaScript code, thereby allowing the iOS application to control the YouTube player. This article describes the steps to install the library and get started using it from your iOS application.
Contents
This guide contains the following sections:
Installation
This article assumes you have created a new Single View Application iOS project targeting iOS 7, and that you have the following files in addition to the other files added when creating this project:
Main.storyboard
ViewController.h
ViewController.m
There are two ways to install the library. The library is available to install via CocoaPods, which has seen adoption as the iOS developer community’s dependency management tool of choice. Alternatively, the library and source files are available via the project’s GitHub page and can be copied into an existing project.
Installing the library via CocoaPods
If your project is using CocoaPods for dependency management, installing the library is just a matter of adding the following line to your Podfile:
pod "YouTube-Player-iOS-Helper", "~> 0.1"
At the command line prompt, type pod install
to update your workspace with the dependencies.
Tip: Remember that when using CocoaPods, you must open the .xcworkspace
file in Xcode, not the .xcodeproj
file.
To learn more about CocoaPods, check out their tutorial.
Manually installing the library
The helper library is also easy to install manually. Either download the source via GitHub’s download link or clone the repository. Once you have a local copy of the code, follow these steps:
Open the sample project in Xcode or Finder.
Select
YTPlayerView.h
,YTPlayerView.m
, and the Assets folder. If you are opening the workspace in Xcode, these will be available under Pods -> Development Pods -> YouTube-Player-iOS-Helper and Pods -> Development Pods -> YouTube-Player-iOS-Helper -> Resources. In the Finder, these are available in the project's root directory in the Classes and Assets directories.Drag these files and folders into your project. Make sure the Copy items into destination group’s folder option is checked. When dragging the Assets folder, make sure that the Create Folder References for any added folders option is checked:
The library should now be installed.
Adding a YTPlayerView via Interface Builder or the Storyboard
To add a YTPlayerView
via Interface Builder or the Storyboard:
-
Drag a
UIView
instance onto your View. -
Select the Identity Inspector and change the class of the view to
YTPlayerView
. -
Open
ViewController.h
and add the following header:#import “YTPlayerView.h”
Also add the following property:
@property(nonatomic, strong) IBOutlet YTPlayerView *playerView;
-
In Interface Builder, create a connection from the View element that you defined in the previous step to your View Controller's
playerView
property. -
Now open
ViewController.m
and add the following code to the end of yourviewDidLoad
method:[self.playerView loadWithVideoId:@"M7lc1UVf-VE"];
Build and run your application. When the video thumbnail loads, tap the video thumbnail to launch the fullscreen video player.
Controlling playback
The ViewController::loadWithVideoId:
method has a variant, loadWithVideoId:playerVars:
, that allows developers to pass additional player variables to the view. These player variables correspond to the player parameters in the JavaScript Player API. The playsinline
parameter enables the video to play directly in the view rather than playing fullscreen. When a video is playing inline, the containing iOS application can programmatically control playback.
Replace the loadWithVideoId:
call with this code:
NSDictionary *playerVars = @{ @"playsinline" : @1, }; [self.playerView loadWithVideoId:@"M7lc1UVf-VE" playerVars:playerVars];
Open up the storyboard or Interface Builder. Drag two buttons onto your View, labeling them Play and Stop. Open ViewController.h
and add these methods, which will be mapped to the buttons
- (IBAction)playVideo:(id)sender; - (IBAction)stopVideo:(id)sender;
Now open ViewController.m
and define these two functions:
- (IBAction)playVideo:(id)sender { [self.playerView playVideo]; } - (IBAction)stopVideo:(id)sender { [self.playerView stopVideo]; }
Most of the JavaScript Player API functions have Objective-C equivalents, though some of the naming may differ slightly to more closely match Objective-C coding guidelines. Notable exceptions are methods controlling the volume of the video, since these are controlled by the phone hardware or with built in UIView
instances designed for this purpose, such as MPVolumeView
.
Open your storyboard or Interface Builder and control-drag to connect the Play and Stop buttons to the playVideo:
and stopVideo:
methods.
Now build and run the application. Once the video thumbnail loads, you should be able to play and stop the video using native controls in addition to the player controls.
Handling player callbacks
It can be useful to programmatically handle playback events, such as playback state changes and playback errors. In the JavaScript API, this is done with event listeners. In Objective-C,this is done with a delegate.
The following code shows how to update the interface declaration in ViewController.h
so the class conforms to the delegate protocol. Change ViewController.h
’s interface declaration as follows:
@interface ViewController : UIViewController<YTPlayerViewDelegate>
YTPlayerViewDelegate
is a protocol for handling playback events in the player. To update ViewController.m
to handle some of the events, you first need to set the ViewController
instance as the delegate of the YTPlayerView
instance. To make this change, add the following line to the viewDidLoad
method in ViewController.h
.
self.playerView.delegate = self;
Now add the following method to ViewController.m
:
- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state { switch (state) { case kYTPlayerStatePlaying: NSLog(@"Started playback"); break; case kYTPlayerStatePaused: NSLog(@"Paused playback"); break; default: break; } }
Build and run the application. Watch the log output in Xcode as the player state changes. You should see updates when the video is played or stopped.
The library provides the constants that begin with the kYT*
prefix for convenience and readability. For a full list of these constants, look at YTPlayerView.m
. Other useful methods include:
- (void)playerViewDidBecomeReady:(YTPlayerView *)playerView; - (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state; - (void)playerView:(YTPlayerView *)playerView didChangeToQuality:(YTPlaybackQuality)quality; - (void)playerView:(YTPlayerView *)playerView receivedError:(YTPlayerError)error;
Best practices and limitations
The library builds on top of the iframe player API by creating a UIWebView and rendering the HTML and JavaScript required for a basic player. The library's goal is to be as easy-to-use as possible, bundling methods that developers frequently have to write into a package. There are a few limitations that should be noted:
- The library does not support concurrent video playback in multiple
YTPlayerView
instances. If your application has multipleYTPlayerView
instances, a recommended best practice is to pause or stop playback in any existing instances before starting playback in a different instance. In the example application that ships with the project, the ViewControllers make use ofNSNotificationCenter
to dispatch notifications that playback is about to begin. Other ViewControllers are notified and will pause playback in theirYTPlayerView
instances. - Reuse your existing, loaded
YTPlayerView
instances when possible. When a video needs to be changed in a View, don't create a newUIView
instance or a newYTPlayerView
instance, and don't call eitherloadVideoId:
orloadPlaylistId:
. Instead, use the thecueVideoById:startSeconds:suggestedQuality:
family of functions, which do not reload theUIWebView
. There is a noticeable delay when loading the entire iframe player. - This player cannot play private videos, but it can play unlisted videos. Since this library wraps the existing iframe player, the player's behavior should be nearly identical to that of a player embedded on a webpage in a mobile browser.
Open Source
The library's best feature is that it is open source. Prefer a different way of doing something? Fork the code! If you have any questions about this code or anything related to the API, ask away using the youtube-api tag on StackOverflow.