Record and Upload videos to server in iOS

Posted By : Anuj Vashistha | 12-Jul-2013



In this blog you will see how to record videos and upload them to server in iPhone.

I have attached a download link to download the Sample app for ease of use, but i will suggest you to read the blog once as it will help you understand the code better.

Please follow the steps below to successfully create an iOS app which will record and upload videos to the server.

 

  • First of all create a new project in Xcode (single view application), don't forget to select Use storyboards option.
  • As this application is built only for iPhone device, delete the iPad storyboard from project explorer and info.plist file. Although you can build it for iPad too if required. Set Target device family to "iPhone"
  • Please set the deployment target to 5.0, certain libraries and frameworks we are using works for 5.0 and above.
  • Now select the project in project explorer, now select project target, and under "Build phases" in "Link Binary With Libraries" menu add certain frameworks which are required for the functionality we will implement, named : SystemConfiguration.framework, CFNetwork.framework, AVFoundation.framework, MobileCoreServices.framework, MediaPlayer.framework, CoreMedia.framework
  • You gotta download a library http://allseeing-i.com/ASIHTTPRequest/ to send video request to the server. Download it and add it to your project root folder
  • Now, coming to the UI of the app. Select the iPhone_storyboard. Add two UIButtons "Choose from gallery" and "RecordAndUpload" on the view controller. I have also added a label at the top describing the features of the app. "Choose from gallery" allows you to select a video from your video gallery and upload it to the server, "Record" allows you to record a video and upload it to the server at the same time.
  • Create "New Referencing Outlets" for both the buttons and add "Sent events" in it's parent file "ViewController.h" (from Utilities menu or manually).
  • Open your ViewController.h file and replace all the content with the code below :
#import <UIKit/UIKit.h>
#import "ASIFormDataRequest.h"

@interface ViewController : UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate>{
    UIView * aProgressView ;
    UIProgressView *progressIndicator;
    ASIFormDataRequest *request;
    
}
- (IBAction)ChooseFromGallery:(id)sender;  // sent event for choose from gallery button
- (IBAction)RecordAndPlay:(id)sender;      // sent event for record and upload button

- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
                                   usingDelegate: (id <UIImagePickerControllerDelegate,
                                                   UINavigationControllerDelegate>) delegate;
- (void)video: (NSString *) videoPath didFinishSavingWithError: (NSError *) error contextInfo:(void*)contextInfo;

@property (strong, nonatomic) IBOutlet UIButton *ChooseFromGallery; // referencing outlet for choose from gallery button
@property (strong, nonatomic) IBOutlet UIButton *RecordAndPlay;     // referencing outlet for record and upload button
@property (strong,nonatomic) IBOutlet UILabel *progressLabel;
@property(strong,nonatomic)IBOutlet  UIProgressView *progressIndicator;

@end

 

  • Now open your ViewController.m file and replace it with the code below :
#import "ViewController.h"
#import "ASIFormDataRequest.h"
#import <MediaPlayer/MediaPlayer.h>
#import <MobileCoreServices/UTCoreTypes.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <AVFoundation/AVFoundation.h>
#import <AVFoundation/AVAsset.h>
#import <AVFoundation/AVPlayer.h>
#import <AVFoundation/AVPlayerItem.h>
#import <CoreMedia/CoreMedia.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewWillAppear:(BOOL)animated
{
    progressIndicator.hidden =YES;
    [super viewWillAppear:animated];
}

#pragma UIImagePicker Method:::
// For responding to the user tapping Cancel.
- (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker {
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)ChooseFromGallery:(id)sender {
    
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.allowsEditing = YES;
    imagePicker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    [self presentModalViewController:imagePicker animated:YES];
}

- (IBAction)RecordAndPlay:(id)sender {
    [self startCameraControllerFromViewController: self
                                    usingDelegate: self];
}

- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
                                   usingDelegate: (id <UIImagePickerControllerDelegate,
                                                   UINavigationControllerDelegate>) delegate {
    
    if (([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypeCamera] == NO)
        || (delegate == nil)
        || (controller == nil))
        return NO;
    
    
    UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
    cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
    
    // Displays a control that allows the user to choose movie capture
    cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
    
    // Hides the controls for moving & scaling pictures, or for
    // trimming movies. To instead show the controls, use YES.
    cameraUI.allowsEditing = NO;
    
    cameraUI.delegate = delegate;
    
    [controller presentViewController:cameraUI animated:YES completion:nil];
    return YES;
}

// For responding to the user accepting a newly-captured picture or movie
- (void) imagePickerController: (UIImagePickerController *) picker
 didFinishPickingMediaWithInfo: (NSDictionary *) info {
    
    [picker dismissViewControllerAnimated:YES completion:nil];
    [self progressIndicatorView];
    self.ChooseFromGallery.hidden =YES;
    NSURL *urlvideo = [info objectForKey:UIImagePickerControllerMediaURL];
    NSLog(@"urlvideo is :::%@",urlvideo);
    
    NSError *error = nil;
    NSDictionary * properties = [[NSFileManager defaultManager] attributesOfItemAtPath:urlvideo.path error:&error];
    NSNumber * size = [properties objectForKey: NSFileSize];
    NSLog(@"size: %@", size);
    
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:urlvideo];
    CMTime duration = playerItem.duration;
    float seconds = CMTimeGetSeconds(duration);
    NSLog(@"duration: %.2f", seconds);
    
    /*urlvideo contains the URL of that video file that has to be uploaded. Then convert the url into NSString type because setFile method requires NSString as a parameter
     */
    NSString *urlString=[urlvideo path];
    
    NSString *username = @"xxxxxx";
    NSString *password = @"xxxxxx";
    
    NSString *videoName = urlString.lastPathComponent;
    
    NSString *urlpath = [NSString stringWithFormat:@"http://enteryoururl"];
    urlpath = [urlpath stringByAppendingString:@"username="];
    urlpath = [urlpath stringByAppendingString:username];
    urlpath = [urlpath stringByAppendingString:@"&password="];
    urlpath = [urlpath stringByAppendingString:password];
    
    
    NSURL *url = [NSURL URLWithString:[urlpath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    
    request = [ASIFormDataRequest requestWithURL:url];
    
    [request setPostValue:videoName forKey:@"Filename"];
    [request setFile:urlString forKey:@"videoFile"];
    [request setRequestMethod:@"POST"];
    [request setDelegate:self];
    [request setDidStartSelector:@selector(requestStarted:)];
    [request setDidFinishSelector:@selector(requestFinished:)];
    [request setDidFailSelector:@selector(requestFailed:)];
    [request setUploadProgressDelegate:self];
    [request setTimeOutSeconds:50000];
    [request startAsynchronous];
    NSLog(@"responseStatusCode %i",[request responseStatusCode]);
    NSLog(@"responseStatusCode %@",[request responseString]);
    progressIndicator.hidden=NO;
}

- (void)requestStarted:(ASIHTTPRequest *)theRequest {
    NSLog(@"response started new::%@",[theRequest responseString]);
    //[self showProgress];
}

- (void)requestFinished:(ASIHTTPRequest *)theRequest {
    NSLog(@"response finished new ::%@",[theRequest responseString]);
    //[self hideProgress];
    progressIndicator.hidden = YES;
    [aProgressView removeFromSuperview];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Video upload to server successfully!"  delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert show];
    self.ChooseFromGallery.hidden =NO;
}


- (void)requestFailed:(ASIHTTPRequest *)theRequest {
    NSLog(@"response Failed new ::%@, Error:%@",[theRequest responseString],[theRequest error]);
    //[self hideProgress];
    progressIndicator.hidden = YES;
    [aProgressView removeFromSuperview];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failed" message:@"Video Upload to server failed, please try again"  delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert show];
    self.ChooseFromGallery.hidden =NO;
    
}

#pragma mark Upload Progress Tracking


- (void)setProgress:(float)newProgress {
    
    [progressIndicator setProgress:newProgress];
    NSString* formattedNumber = [NSString stringWithFormat:@"%.f %@", [progressIndicator progress]*100, @"%"];
    
    self.progressLabel.text = formattedNumber;
    self.progressLabel.textColor = [UIColor blackColor];
    [self.progressLabel setFont:[UIFont fontWithName:@"Arial" size:12]];
    
}

- (void)video:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo
{
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Save failed, please try again"  delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil, nil];
        [alert show];
    }else{
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Saved" message:@"Saved To Photo Album"  delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alert show];
    }
}


#pragma UserDefined Method:::
-(void)progressIndicatorView{
    
    //self.Record_button.hidden =YES;
    CGRect UploadProgressFrame = CGRectMake(60, 150, 200,100);
    aProgressView = [[UIView alloc] initWithFrame:UploadProgressFrame];
    [aProgressView setBackgroundColor:[UIColor whiteColor]];
    [aProgressView.layer setCornerRadius:10.0f];
    [aProgressView.layer setBorderWidth:1.0f];
    [aProgressView.layer setBorderColor:[UIColor blackColor].CGColor];
    
    UILabel *progressTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, 25, 150, 30)];
    progressTitleLabel.backgroundColor = [UIColor whiteColor];
    [progressTitleLabel setFont:[UIFont fontWithName:@"Arial" size:15]];
    progressTitleLabel.text = @"Uploading Video";
    progressTitleLabel.textColor = [UIColor blackColor];
    
    self.progressLabel = [[UILabel alloc]initWithFrame:CGRectMake(90, 80, 70, 15)];
    [self.progressLabel setBackgroundColor:[UIColor whiteColor]];
    progressIndicator = [[UIProgressView alloc] init];
    progressIndicator.frame = CGRectMake(30,65,140,20);
    [aProgressView addSubview:progressTitleLabel];
    [aProgressView addSubview:self.progressLabel];
    [aProgressView addSubview:progressIndicator];
    [self.view addSubview:aProgressView];
    
}

- (void)viewDidUnload {
    [self setChooseFromGallery:nil];
    [self setRecordAndPlay:nil];
    [super viewDidUnload];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

Download sample app

Hope it helps :)

About Author

Author Image
Anuj Vashistha

Request for Proposal

Name is required

Comment is required

Sending message..