Preparing the Media Playground Application
This exercise will be less about creating a real-world application and more about building a sandbox for testing out the rich media classes. The finished application will show embedded or fullscreen video, record and play audio, browse and display images from the photo library or camera, and browse and select iPod music for playback.
Implementation Overview
Because there is so much going on in this application. We'll start by creating an application skeleton with outlets and actions, and then fill them in to implement the features we've been discussing. There will be four main components to the application. First, a video player that plays an MPEG-4 video file when a button is pressed; fullscreen presentation will be controlled by a toggle switch. Second, we'll create an audio recorder with playback features. Third, we'll add a button that shows the iPhone photo library or camera and a UIImageView that displays the chosen photo. A toggle switch will control the image source. Finally, we'll provide the user the ability to choose songs from the iPod library and start or pause playback. The title of the currently playing song will also be displayed onscreen in a UILabel.
Setting Up the Project Files
Begin by creating a new View-based iPhone Application project in Xcode. Name the new project MediaPlayground.
Within Xcode, open the MediaPlaygroundViewController.h file and update the file to contain the #import directives, outlets, actions, and properties shown in Listing-1.
LISTING-1
#import <UIKit/UIKit.h> #import <MediaPlayer/MediaPlayer.h> #import <AVFoundation/AVFoundation.h> #import <CoreAudio/CoreAudioTypes.h> @interface MediaPlaygroundViewController : UIViewController <MPMediaPickerControllerDelegate,AVAudioPlayerDelegate, UIImagePickerControllerDelegate,UINavigationControllerDelegate> { IBOutlet UISwitch *toggleFullscreen; IBOutlet UISwitch *toggleCamera; IBOutlet UIButton *recordButton; IBOutlet UIButton *ipodPlayButton; IBOutlet UILabel *nowPlaying; IBOutlet UIImageView *chosenImage; AVAudioRecorder *soundRecorder; MPMusicPlayerController *musicPlayer; } -(IBAction)playMedia:(id)sender; -(IBAction)recordAudio:(id)sender; -(IBAction)playAudio:(id)sender; -(IBAction)chooseImage:(id)sender; -(IBAction)chooseiPod:(id)sender; -(IBAction)playiPod:(id)sender; @property (nonatomic,retain) UISwitch *toggleFullscreen; @property (nonatomic,retain) UISwitch *toggleCamera; @property (nonatomic,retain) UIButton *recordButton; @property (nonatomic, retain) UIButton *ipodPlayButton; @property (nonatomic, retain) UILabel *nowPlaying; @property (nonatomic, retain) UIImageView *chosenImage; @property (nonatomic, retain) AVAudioRecorder *soundRecorder; @property (nonatomic, retain) MPMusicPlayerController *musicPlayer; @end
Most of this code should look familiar to you. We're defining several outlets, actions, and properties for interface elements, as well as declaring the instance variables soundRecorder and musicPlayer that will hold our audio recorder and iPod music player, respectively.
There are a few additions that you might not recognize. To begin, we need to import three new interface files so that we can access the classes and methods in the Media Player and AV Foundation frameworks. The CoreAudioTypes.h file is required so that we can specify a file format for recording audio.
Next, you'll notice that we've declared that MediaPlaygroundViewController class must conform to the MPMediaPickerControllerDelegate, AVAudioPlayerDelegate, UIImagePickerControllerDelegate, and UINavigationControllerDelegate protocols. These will help us detect when the user has finished choosing music and photos, and when an audio file is done playing. That leaves UINavigationControllerDelegate. Why do we need this? The navigation controller delegate is required whenever you use an image picker. The good news is that you won't need to implement any additional methods for it!
After you've finished the interface file, save your changes and open the view controller implementation file, MediaPlaygroundViewController.m. Edit the file to include the following @synthesize directives after the @implementation line:
@synthesize toggleFullscreen; @synthesize toggleCamera; @synthesize soundRecorder; @synthesize recordButton; @synthesize musicPlayer; @synthesize ipodPlayButton; @synthesize nowPlaying; @synthesize chosenImage;
Finally, for everything that we've retained, be sure to add an appropriate release line within the view controller's dealloc method:
- (void)dealloc { [toggleFullscreen release]; [toggleCamera release]; [soundRecorder release]; [recordButton release]; [musicPlayer release]; [ipodPlayButton release]; [nowPlaying release]; [chosenImage release]; [super dealloc]; }
Now, we'll take a few minutes to configure the interface XIB file, and then we'll explore the classes and methods that can (literally) make our apps sing.
Creating the Media Playground Interface
Open the MediaPlaygroundViewController.xib file in Interface Builder and begin laying out the view. This application will have a total of six buttons (UIButton), two switches (UISwitch), three labels (UILabel), and a UIImageView. In addition, we need to leave room for an embedded video player that will be added programmatically.
Pepresents a potential design for the application. Feel free to use this approach with your layout, or modify it to suit your fancy. You might want to consider using the Attributes Inspector to set the UIImageView mode to Aspect Fill or Aspect Scale to make sure your photos look right within the view.
Connecting the Outlets and Actions
Finish up the interface work by connecting the buttons and label to the corresponding outlets and actions that were defined earlier.
For reference, the connections that you will be creating are listed in Table-1. Be aware that some UI elements need to connect to both an action and an outlet so that we can easily modify their properties in the application.
TABLE-1 Interface Elements and Actions
Element Name (Type) | Outlet/Action | Purpose |
---|---|---|
Play Movie (UIButton) | Action: playMedia: | Initiates playback in an embedded movie player, displaying a video file |
Fullscreen On/Off Switch (UISwitch) | Outlet: toggleFullscreen | Toggles a property of the movie player, embedding it or presenting the video fullscreen |
Record Audio (UIButton) | Action: recordAudio: Outlet: recordButton: | Starts and stops audio recording |
Play Audio (UIButton) | Action: playAudio: | Plays the currently recorded audio sample |
Pick Image | Action: chooseImage | Opens a pop-over displaying the user's photo library |
Camera On/Off Switch (UISwitch) | Outlet: toggleCamera | Toggles a property of the image selector, presenting either the photo library or camera |
UIImageView | Outlet: chosenImage | The image view that will be used for displaying a photo from the user's photo library |
Choose iPod Music (UIButton) | Action: chooseiPod: | Opens a pop-over displaying the user's music library for creating a playlist. |
Play iPod Music (UIButton) | Action: playiPod: Outlet: ipodPlayButton | Plays or pauses the current playlist |
No Song Playing (UILabel) | Outlet: nowPlaying | Displays the title of the currently playing song (if any) |
After creating all the connections to and from the File Owner's icon, save and close the XIB file. We've now created the basic skeleton for all the media capabilities we'll be adding in the rest of the exercise.