iOS | How-To Develop an AVPlayer iPAD Application and AirPlay

AirPlay is not new, it was introduced with the IOS 4.3 version of the SDK. What is new is the enhancements and various other improvements that were made to the AirPlay API. One of new features that is really interesting is the abillity to interface content from your iOS on iPAD application with Apple TV 2 or mirror content from an iPad 2 device with an Apple TV 2.

In a nutshell, AirPlay is AV content streaming to a high definition display (television definition audio system. Apple TV 2 is required to provide the interface between the iOS device or iTunes and the high definition devices.

With the release of iOS 5, any application that uses the AV Foundation classes can stream audio and video content from the application to an Apple TV. You could also use the MPMoviePlayerController to display the "Now Playing" information directly to a high definition television set or other video display that displays in high definition through the AirPlay. The other enhancement is to stream video from an UIWebView, which is pretty exciting considering you could stream live video or audio from the web directly to your television set via AirPlay and an Apple TV 2.

Streaming Content with AVFoundation

To be able to use AirPlay from an application that uses AVFoundation, you need to implement the AVPlayer and set the allowsAirPlayVideo to YES to explicitly enable AirPlay or NO is turn off the AirPlay service as in Listing 1.

Code Listing 1-Create a Method to Set AirPlay On

-(BOOL)setAirPlay:(BOOL)airplayMode{
   return self.player.allowsAirPlayVideo=airplayMode;
}

Create the Application

To demonstrate how to create an AVPlayer app and implement Airplay, we will create a Single View application that implements the AVPlayer class and AirPlay features.

  • To begin create a Single View application. You can choose target either an iPhone, iPod or iPad device. Once the project is created you will need to import the AV Foundation framework.
  • Next add a new class, called Player, as a sub class of the UIView class. In the header file, add the AVPlayer class and create an AVPlayer instance variable as in listing 2.

Code Listing 2-Create an AirPlay object in Header File

@class AVPlayer;
@interface Player : UIView
@property(nonatomic, strong) AVPlayer * player;
  • The rest of the work to create the Player class will be done in the implementation file.
  • We will need to implement a minimum of four methods to properly implement the bare bones AVPlayer and also provide a method to toggle our AirPlay on or off.
  • First we will need a wrapper for an instance of the AVLayerClass. This class is a subclass of the CALayer which manages the visual output of the media content. Create the wrapper class as in Listing 3.

Code Listing 3-Wrapper for AVPlayerLayer class

+ (Class)layerClass {
	return [AVPlayerLayer class];
}
  • The next step is to provide a method to instantiate the AVPlayer UIView object that we defined in the header. We will accomplish that with the next method outlined in listing 4.

Code Listing 4-Add Method to Instantiate AVPlayer View Object

-(AVPlayer *) player{
    return [(AVPlayerLayer *)[self layer] player];
}
  • The setPlayer method, listing 5, has an AVPlayer argument which will used to actually add an AVPlayer instance to the UIView when we implement this sub class of the UIView in the main View Controller which will as the Controller to the View Controller UI in the Storyboard.

Code Listing 5 - Define a Method to Add an AVPlayer to UIView

- (void)setPlayer:(AVPlayer*)player {
	[(AVPlayerLayer*)[self layer] setPlayer:player];
}
  • The last method in our class, setAirPlay, will provide an argument to set the allowsAirPlayVideo property of our AVPlayer UIView (Player). See listing 6 below.

Code Listing 6- Create setAirPlay boolean method

-(BOOL)setAirPlay:(BOOL)airplayMode{
   return self.player.allowsAirPlayVideo=airplayMode;
}

When defining layers (ACPlayerLayer) for your video output you can set any arbitrary amount of layers as you see fit to control the display of the content. Like for instance to manage the time between to video and audio playback. Within the setDisplayMode you would set the display layers by creating a AVPlayerLayer instance method and setting one or more of its properties. The default is the AVLayerVideoGravityResizeAspect attribute. The other options are: AVLayerVideoGravityResizeAspectFill and AVLayerVideoGravityResize. The former or default option maintains the video aspect ratio and fits the content within the player's bounds. The second option is similar to the first, except it would fill rather than fit the content to the player's bounds. Finally the last option would stretch the content to fit the content bounds.

The complete code listing is in code listing 7 below for the Player class.

Code Listing 7 - Complete Code for Player AVPlayer UIView

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@class AVPlayer;
@interface Player : UIView
@property(nonatomic, strong) AVPlayer * player;
-(BOOL) setAirPlay:(BOOL) airplayMode;
@end

#import "Player.h"
#import <AVFoundation/AVFoundation.h>

@implementation Player

+ (Class)layerClass {
	return [AVPlayerLayer class];
}
-(AVPlayer *) player{
    return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer*)player {
	[(AVPlayerLayer*)[self layer] setPlayer:player];
}
//Enable or disable AirPlay mode
-(BOOL)setAirPlay:(BOOL)airplayMode{
   return self.player.allowsAirPlayVideo=airplayMode;
}
@end

Implement Player View Class in Application

The code listing 7 above is the contents of the header file and the implementation of our Player AVPlayer UIView. To implement this AVPlayer view in an UIViewController, open the storyboard and select the UIView (not the UIViewController) and set the custom class to Player. You can either type in the name in the Custom Class field in the Identity inspector or choose from the drop down list.

  • Next open the Assistant Editor and create an IBOutlet for the Player view by perform a control drag from the view to the open header file. Figure 1.

Figure 1 - Define IBActions and IBOutlets
Figure 1 - Define IBActions and IBOutlets
  • Also you will add an delegate to the klViewController by right clicking on the Player view in storyboard and dragging a connection line from the IBOutlet to the klViewController proxy (the yellow globe in the dock) as in Figure 2.

Figure 2 - Adding a Delegate to the klViewController
Figure 2 - Adding a Delegate to the klViewController

While in the storyboard, add a Toolbar and two buttons, labeling them Play and Pause respectively and add a Switch object to toggle our AirPlay on or off. Also create IBActions for all three. At this point you can close the Assistant Editor. The rest of the work will be done in the klViewController custom class files.

  • Open the klViewController header and a @class directive for the Player view class and the AVPlayer. Also import the AVFoundation framework and the Player class like the listing 8 shows.

Code Listing 8 - Add Player and AVPlayer @class directive

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "Player.h"

@class Player;
@class AVPlayer;

@interface klViewController : UIViewController
  • Next add a variable for an AVPlayer in the header file which will load in the Player view.
  • Also add a NSURL variable for the video content. Then we will need an IBOutlet for our Switch UIControl. To add the IBOutlet, open the Assistant Editor alongside the Storyboard and perform a control drag grom the UISwitch to the header.
  • Once done your header should look something like the following listing 9 shows:

Code Listing 9-Player definition in the klViewController UIViewController

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import Player.h

@class Player;
@class AVPlayer;

@interface klViewController : UIViewController
@property(nonatomic, strong) AVPlayer * myPlayer;
@property(nonatomic, strong) NSURL * avContentUrl;

@property (strong, nonatomic) IBOutlet Player *airPlayView;
@property (nonatomic, retain) IBOutlet UISwitch * AirPlaySwitch;

- (IBAction)PlayVideo:(id)sender;
- (IBAction)PauseVideo:(id)sender;
- (IBAction)isAirPlayOn:(id)sender;

@end 
  • Now we will implement everything in the implementation file. In the viewDidLoad method instantiate the avContentUrl, passing in a video URL as listing 10.

Code Listing 10-Instantiating video URL

avContentUrl = [[NSURL alloc] initWithString:@"http://somedomain.yourvideo.mp4"];
  • Next add the video URL, avContentUrl to your AVPlayer variable, which I called myPlayer in the header, and add the myPlayer to the airPlayView which is an instance of our Player view. See listing 11.

Code Listing 11 - Add Content and AVPlayer to UIView

self.myPlayer = [AVPlayer playerWithURL:avContentUrl];
[airPlayView setPlayer:[self myPlayer]];
  • Now all that is needed is to play the video and pause it using our buttons and to enable our Switch, isAirPlayOn, to turn on and off the AirPlay. For the PlayVideo button add the following code as in listing 12.

Code Listing 12 - Add Code to Play Video

- (IBAction)PlayVideo:(id)sender {
    [self.myPlayer play];
}
  • Likewise, for the PauseVideo button add the following listing 13 code:

code Listing 13 - Add Code to Pause Video Playback

- (IBAction)PauseVideo:(id)sender {
    [self.myPlayer pause];
}
  • Finally add the following code, listing 14, for the AirPlaySwitchSwitch in the isAirPlayOn IBAction:

Code Listing 14 - Set isAirPlayOn toggle Method Code

- (IBAction)isAirPlayOn:(id)sender {
    AirPlaySwitch = (UISwitch *) sender;
    if (AirPlaySwitch.on) {
        [airPlayView setAirPlay:NO];
    }else
    {
       
        [airPlayView setAirPlay:YES];
    }
}

In Conclusing

Another useful property related to AirPlay is the usesAirPlayVideoWhileAirPlayScreenIsActive which will switch the AVPlayer to to AirPlay automatically during playback but only if AirPlay is enabled. The default is false.

That is it for the example. To actually test the AirPlay functionality you will need to deploy the app to an iPad and connect it via Wi-Fi with an Apple TV device and add a proper video resource URL. Otherwise the code as is will play videos in the Simulator but the AirPlay functionality won't enabled.

klViewController Header

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "Player.h"

@class Player;
@class AVPlayer;

@interface klViewController : UIViewController


@property(nonatomic, strong) AVPlayer * myPlayer;
@property(nonatomic, strong) NSURL * avContentUrl;



@property (strong, nonatomic) IBOutlet Player *airPlayView;
@property (nonatomic, retain) IBOutlet UISwitch * AirPlaySwitch;

- (IBAction)PlayVideo:(id)sender;

- (IBAction)PauseVideo:(id)sender;

- (IBAction)isAirPlayOn:(id)sender;

@end

klViewController Implementation

#import "klViewController.h"


@implementation klViewController
@synthesize airPlayView;
@synthesize avContentUrl, myPlayer, AirPlaySwitch;



                           

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    //This is an Apple sample video
    avContentUrl = [[NSURL alloc] initWithString:@"http://somedomain.yourvideo.mp4"];
    self.myPlayer = [AVPlayer playerWithURL:avContentUrl];
    [airPlayView setPlayer:[self myPlayer]];
   
     [self.myPlayer play];
      
}

- (void)viewDidUnload
{

    [self setAirPlayView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}




- (IBAction)PlayVideo:(id)sender {
    [self.myPlayer play];

}

- (IBAction)PauseVideo:(id)sender {
    [self.myPlayer pause];

}

- (IBAction)isAirPlayOn:(id)sender {
    AirPlaySwitch = (UISwitch *) sender;
    if (AirPlaySwitch.on) {
        [airPlayView setAirPlay:NO];
    }else
    {
       
        [airPlayView setAirPlay:YES];
    }
}





@end

More by this Author


Comments

No comments yet.

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working