Create a Simple App for Video Recording and Playback
Update: The post has been updated to support Xcode 5 and iOS 7.
In the previous post we covered how to create a simple camera app. In this post, we’re going to create a similar application but for video recording and playback.
The iOS API for recording and playing videos can be a little bit confusing for newcomers, as there are several options available. If you just want to play a video, you can use the MediaPlayer framework, which allows us to play a video stored locally in our device, or from a remote location. However, if you need advanced features such as media asset management, media editing, track management, and others, you have to use the AVFoundation framework. We’ll keep thing simple and start off by covering the MediaPlayer framework.
On top of that, the MediaPlayer framework brings us two main classes to display videos or movies. If you want to display a video immediately and inline (e.g. a subview smaller than the full screen), you should use the MPMoviePlayerController. By using MPMoviePlayerController, playback occurs in a view owned by the movie player. You can incorporate a movie player’s view into a view owned by your app. On the contrary, if you want to play a full screen video, for example by presenting the video modally, you should use the MPMoviePlayerViewController class. The MPMoviePlayerViewController class is designed to present a simple view controller for displaying full-screen movies.
In this tutorial, we will focus on the MPMoviePlayerController. If you grasp the basics, however, you should have no problem utilizing the MPMoviePlayerViewController class.
Demo App Overview
Like any other tutorials, we’ll build a simple demo app to walk you through the concept. The demo app is very simple without fancy user interface. Once opened, the app displays a screen with a single “Capture” button. When you tap the button, it’ll bring up the video camera for video recording. Once finished the recording, the video is automatically shown in the main screen. Users are allowed to play back the video inline. Pretty simple, right?
Creating Xcode Project
Open Xcode and create a new Project, choose the Single View Application template. Name the project as VideoApp and set the class prefix as Video. Click next to create and save the project.
Designing User Interface
Next, let’s design the user interface of the app. Go to the Main.storyboard. Add a button and place it at the bottom of the screen centered. Change its title to “Capture”. Your design should look like below.
Again, the next thing to do is to establish a connection between the Capture button and code. In order to do that, switch to the Assistant Editor mode. Create an action method in the VideoViewController.h for the Capture button. Name the method as “captureVideo”.
Implementing the VideoViewController
Open the VideoViewController.h file and add the following code to include the necessary header files:
1 2 |
#import <MediaPlayer/MediaPlayer.h> #import <MobileCoreServices/MobileCoreServices.h> |
In the previous tutorial, we use the UIImagePickerController class to take static photo. The same class is also capable to capture video. If you’re not forgetful, you should still remember how to use UIImagePickerController. Here, the VideoViewController has to implement both the UIImagePickerControllerDelegate and UINavigationControllerDelegate protocols.
On top of that, we’ll add two properties (videoURL and videoController) in the VideoViewController.h. The videoURL property stores the URL of the current video, while the videoController property is dedicated for video play back.
If you did everything correctly, your VideoViewController.h file should be something like below:
1 2 3 4 5 6 7 8 9 10 11 12 |
#import <UIKit/UIKit.h> #import <MediaPlayer/MediaPlayer.h> #import <MobileCoreServices/MobileCoreServices.h> @interface VideoViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> @property (strong, nonatomic) NSURL *videoURL; @property (strong, nonatomic) MPMoviePlayerController *videoController; - (IBAction)captureVideo:(id)sender; @end |
Implementing Picker Controller for Video Recording
When the user taps the “Capture” button, the captureVideo: method is called. This method is responsible to create, configure and display the image picker for video recording. We’ll implement the method using the below code:
1 2 3 4 5 6 7 8 9 10 11 12 |
- (IBAction)captureVideo:(id)sender { if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.allowsEditing = YES; picker.sourceType = UIImagePickerControllerSourceTypeCamera; picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil]; [self presentViewController:picker animated:YES completion:NULL]; } } |
If you’ve read the previous tutorial, you should have a basic idea of UIImagePickerController. The above code shouldn’t be new to you. It’s almost the same as the one we use for taking photo, except that we set the picker’s media types to kUTTypeMovie. Depending on the media types, the picker displays different interface for photos or videos. By default the media type is set to kUTTypeImage, which designates the photo camera interface. As we need the picker to launch the video capture interface, we set the media type to kUTTypeMovie.
Implementing Video Playback
Once user finishes recording and confirm to save the video, the app will automatically play back the video in the main screen. In order to implement the video playback, there are a few things to be done:
- Get the system URL of the video just captured
- Remove the UImagePickerController
- Play the video by using the MPMoviePlayerController class, which is a built-in class for the playback of a video from a file (or a network stream)
As you know, the didFinishPickingMediaWithInfo: method will be called when user confirms to use the video. The file URL of the video is bundled in the info parameter. So in this method, we first get the URL of the video (please note that this video is not saved in the photo library unless we do it explicitly). Secondly, we dismiss the picker. Lastly, we instantiate the MPMoviePlayerController class and pass it with the video URL for playback. We also change the size of the view to leave some free space for the “Capture” button. And finally, we present the view and play the video.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { self.videoURL = info[UIImagePickerControllerMediaURL]; [picker dismissViewControllerAnimated:YES completion:NULL]; self.videoController = [[MPMoviePlayerController alloc] init]; [self.videoController setContentURL:self.videoURL]; [self.videoController.view setFrame:CGRectMake (0, 0, 320, 460)]; [self.view addSubview:self.videoController.view]; [self.videoController play]; } |
There is still one thing left. We should implement the imagePickerControllerDidCancel: method. We mentioned this method in the previous chapter. The method is invoked when user cancels the video recording. In this case, we simply dismiss the picker.
1 2 3 4 5 |
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [picker dismissViewControllerAnimated:YES completion:NULL]; } |
Compile and Test the App
OK, it is time to compile and test our application. Like the Camera app we developed in the previous chapter, you can’t test it using the built-in iPhone Simulator. You have to use a real device for the testing as the iPhone simulator doesn’t have a camera.
If you compile and run the app on your iPhone, you should be able to bring up the video camera interface after tapping the “Capture” button. Once capturing the video, it’s automatically played back in the main screen.
Using the Movie Player Notifications
A nice feature of the MPMoviePlayerController is that it has a collection of notifications that we can use to control the video playback. For example, when the video has finished playing, the MPMoviePlayerPlaybackDidFinishNotification will be sent. Add the following code to the didFinishPickingMediaWithInfo: method, just before the [self.videoController play] statement:
1 2 3 4 |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoPlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.videoController]; |
You may be new to NSNotificationCenter. Simply think of it as a centralized hub of notifications within an app. Through it, any part of your app can notify or be notified by other parts of the app. In the above code, it tells the NSNotificationCenter to listen for the MPMoviePlayerPlaybackDidFinishNotification and calls up the videoPlayBackDidFinish: method accordingly.
In this case, the videoPlayBackDidFinish: method will stop the video, remove its view and display an alert message. Of course, we’ll remove the notification. Otherwise, it will be called twice! Add the following code in the VideoAppController.m:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- (void)videoPlayBackDidFinish:(NSNotification *)notification { [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; // Stop the video player and remove it from view [self.videoController stop]; [self.videoController.view removeFromSuperview]; self.videoController = nil; // Display a message UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Playback" message:@"Just finished the video playback. The video is now removed." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } |
Now compile and test the app again. Try to record a video. The app will automatically play back the video but it’s removed the player from the view once the play back completes.
Summary
By now, you should have a better idea about implementing video recording and playback in iOS. The UIImagePickerController makes it simple to bundle video capturing feature in your app. With a few lines of code, you can bring up the built-in video camera and capture video. On the other hand, the MediaPlayer framework provides handy facilities for video or movie playback. The use of framework is not limited to video playback. It allows developers to access the iPod library, play music, podcast and audio book files. So don’t stop here, check out Apple’s official reference to learn more about the framework.
For your complete reference, you can download the source code for the sample Xcode project here.
As always, leave us comment and share your thought about the tutorial.
Comments
Osvaldo Cipriano
AuthorGreat tutorial as always 🙂
jadacoast
AuthorThanks for this 🙂 I’m having an issue with receiving a SIGABRT warning though however no warnings/issues are being reported in the code. I’ve also tried running the full source code which doesn’t get the error however only appears as a black screen when running it on a device.
Any help on this?
K
AuthorIm having the same issue. Even the source code is giving me this issue? any help would be greatly appreciated.
Avi
AuthorRemove the “copy” part from the properties in the ViewController.h file. Seems those controls don’t conform to the NSCopying protocol, so the call to copy them fails.
Example:
@property (nonatomic) NSURL *movieURL;
jadacoast
AuthorJust on the below, I added a breakpoint before running on the device and it’s highlighted a the below line of code from the AppDelegate.h file:
[self.window makeKeyAndVisible];
jadacoast
Author**AppDelegate.m file
jadacoast
AuthorFixed the SIGABRT error! Had connected the Button twice and hadn’t destroyed the previous connection 🙂
Now just appearing with a black screen like the Full Source Code..
jadacoast
AuthorJust in case anyone else has the same problem- I fixed the black screen by changing the parameters for CGRectMake; think the ones given were taking up the whole display on my device hence the black screen.
Thanks again for the tut!
Sandeep Chavarkar
AuthorThanks for solving the black screen problem. You need to change parameters for CGRectMake. I used (0, 0, 320, 380) and it worked.
Yves Dufour
Authorso many iPhone generations now, … !!
insert in application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
after :
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
insert :
self.window.frame = CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, [[UIScreen mainScreen]bounds].size.height);
Greg
AuthorGreat tutorial, thanks for posting!
Vedit
Authorself.movieURL = info[UIImagePickerControllerMediaURL];
i got the error here that Array subscript is not an integer
Chainsaw
AuthorIs it possible to have this app default to the front camera instead of the rear?
Thank you for this wonderful tutorial!
Madhavan
AuthorIs it possible to mute the audio for MPMovieplayer controller
Gary Stewart
AuthorHow can I set the frames per second? I want to drop the rate to give a blur effect when capturing? Thanks!
pd
AuthorWhen a user clicks on a URI in a browser that points to a video, how can I register my app to receive the intent in iOS?
amayalore
AuthorGreat tutorial! My issue is I’m trying to use MoviePlayerController in a UITableViewCell. I am having trouble figuring this one out — is there a way to create a class for a particular cell? Or must I use selectRowAtIndexPath? I’m new to this and am not clear how to do so. Any suggestions?
Reakol
AuthorEverything is easy except from the easiest part lol, how do you the associate the code with the button?
dubsyrop
Authorits good tutorial, but can you say, how can i record device screen as a video ??
Er Ritesh Singh
Authorit is good but i just wanna play a saved .mp4 file.
BananenSiroop
AuthorSimply change the sourceType of the picker
Steve
AuthorHello, I downloaded your source code project to try to run on my iphone. I’m running iOS 7.1. I built and ran it, and all I got was a black screen. Any thoughts as to why?
ShanghaiTimes
AuthorHey guys. Ancient tutorial … anyone got the time to update it to Xcode 5.2/iOS7.2 etc. Like Steve, all I get is a black screen. The Take Video appears briefly, then is overlaid by black screen
Simon Ng
AuthorIt’s now updated to support Xcode 5 and iOS 7. Please try again.
ShanghaiTimes
AuthorWarning Will robinson….
2014-05-02 07:59:20.822 VideoApp[78278:60b] *** Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.’
*** First throw call stack:
ShanghaiTimes
AuthorThanks Simon, you’re the man. Thanks for fixing that. #AppCoda tutes are the best.
HARSH MEHROTRA
AuthorYour code worked well! But I need to put a check on the size of video. Like if I have recorded 10 MB video, it should get stopped. How can I achieve that?
Greg Lee
AuthorMight be really obvious but solved my “SIGABRT warning” issue by removing the line “picker.sourceType = UIImagePickerControllerSourceTypeCamera” line (as I am using the simulator)
Arvin Sanmuga Rajah
AuthorWorked like a charm! Thank you so much. The only thing I changed is the frame dimension 🙂
Bhavin Joshi
Authorwell it shows error – ”
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
booksargag
Authorhttp://mashable.com/2012/05/24/ios-video-apps/#kFLr6pqAmuqc
d.dwyer
AuthorConventionally, making a good video used to mean taking out an expensive video camera and have editing suite. But, now we can do lots of same things by an iOS device without huge expenses or a lot of training. Recording high-definition video right (from your living room to outdoor) is now possible with great video apps available on the iTunes store. Even if you are interested to add your favorite music on the same video, then it is also possible through the app like Shimmeo https://itunes.apple.com/us/app/shimmeo-music-video-creator/id974747911?mt=8. Share a masterpiece with your loved ones, and get thousands of likes and comments within minute.
John Oldman
AuthorThank you very much! It is really an interesting thing) I’d also like to share with one article, including overpriced secrets about how to develop something like Instagram for videos)
https://yalantis.com/blog/video-recording-app-development-how-we-built-instagram-for-videos/
Монастырский Сергей
AuthorHi, in your project I find bug: sound volume in preview mode is quieter than in original.
I have this problem in my project too – if I start project first Record video VC (use AVFoundation) and later try to play any saved video files sound has minimal volume. Why?