Upload Video to Server Using Multiparts in iPhone

This blog will help you in recording and uploading video to server using multiparts in iPhone.

We have two methods for sending video data to server:-

1. Video data is encoded before sending data to server.
2. Video data is encoded after receiving complete data to server.

We can encode video data before sending data to server, but at the same time we have some drawbacks like time issues, lagging effects. Thats why we have preferred the second option, where we are recording the video and send video data to server using “multipart”. When data successfully received at server side, then encoding part would be done on server side only. This method will prevent the app from time and lagging effects.

In the case of multiple part messages, in which one or more different sets of data are combined in a single body, a “multipart” Content-Type field must appear in the entity’s header. The body must then contain one or more “body parts,” each preceded by an encapsulation boundary, and the last one followed by a closing boundary. Each part starts with an encapsulation boundary, and then contains a body part consisting of header area, a blank line, and a body area.

Please follow the steps of recording and uploading video to server:-

1. Create a new project in Xcode (Single View Application).
2. Create an Xib having “Post Imageview” , “Add Video” button and “Post” button.
– On click on “Add Video” button, we can capture image and fetch video from device library.
– On click on “Post” button, we can send request to server and start uploading video to data to server.
3. Add UIActionSheetDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate in ViewController.h class and MediaPlayer Framework from Build Phases.
4. Declare in ViewController.h class

	IBOutlet UIImageView*       _postImageView;
    IBOutlet UIView*            _loadingView;

    NSMutableData*              _receivedData;
    NSURLConnection*            _conn;
    NSURL*                      _videoUrl;

5. Click on AddVideo button.

UIActionSheet* photoSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Take Video from Camera",
@"Choose Video from Library", nil];

photoSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[photoSheet showInView:self.view];
_ReleaseObj(photoSheet);

Action Sheet wiil provide you an option to “Take Video from Camera” and “Choose Video from Library”

– on click on “Take Video from Camera”, we can record video from iPhone Camera.
– on click on “Choose Video from Library” we can fetch available video

6. Select Capture Video from Camera. Record Video. After completion of recording, click on compress button.
After completion of compressing, will dismiss image picker controller and imagepickercontroller delegate function will be called.

ImagePicker Delegate Method:

// called when cancel button of image picker controller is clicked.
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
	[picker dismissViewControllerAnimated:YES completion:nil];
}

// called after selecting video successfully from ImagePicker Controller
- (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info
{
	[picker dismissViewControllerAnimated:YES completion:nil]; // dismiss image picker view controller

    NSString *mediaType = info[UIImagePickerControllerMediaType];
    if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) // Media is a video
    {
        NSURL* videoUrl = info[UIImagePickerControllerMediaURL];
        _videoUrl = [[NSURL alloc] initWithString:[videoUrl absoluteString]];
        [self loadVideo:_videoUrl];
    }
}

// implement mpmovie player to load video and get thumbnail image
- (void)loadVideo:(NSURL*)url
{
    // movie player controller to play video corresponding to the url
    MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL:url]autorelease];
    UIImage  *thumbnailImage = [player thumbnailImageAtTime:1.0 timeOption:
                                MPMovieTimeOptionNearestKeyFrame];
    player = nil;
    _ReleaseObj(player);
    _postImageView.image = thumbnailImage; // set thumbnail image to post image view
}

load video will load video from the given url and set thumbnail image of video to “PostImageView”

7. Now click on “Post” button

– Fetch video data from the _videoUrl path using given code:-

NSData* videoData = [NSData dataWithContentsOfFile:[_videoUrl path]];

– Create NSMutableRequest to send request to server using given code:-

 NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:@”www.myurl.com”]]; // add the url

where you need to send request

[request setHTTPMethod:@”POST”]; // write http method name “POST”
NSString *contentType = [NSString stringWithFormat:@”multipart/form-data; boundary=%@”,kBoundary];
[Request addValue:contentType forHTTPHeaderField: @”Content-Type”];

– Now append content data which need to send with request:-For example:-

/ / please mention these string in defines class
		#define kStartTag   @"--%@\r\n"
		#define kEndTag     @"\r\n"
		#define kContent    @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n"
		#define kBoundary   @"---------------------------14737809831466499882746641449"

		NSMutableData* content = [NSMutableData data];

	    // Username parameter
    	[body appendData:[[NSString stringWithFormat:kStartTag, kBoundary]dataUsingEncoding:NSUTF8StringEncoding]];
    	[body appendData:[[NSString stringWithFormat:kContent, @"Username"] dataUsingEncoding:NSUTF8StringEncoding]];
    	[body appendData:[userName dataUsingEncoding:NSUTF8StringEncoding]];
    	[body appendData:[[NSString stringWithFormat:kEndTag] dataUsingEncoding:NSUTF8StringEncoding]];

		// video file
    	[body appendData:[[NSString stringWithFormat:kStartTag, kBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    	[body appendData:[@"Content-Disposition: form-data; name=\"uploadedVideo\"; filename=\"flv\"\r\n"
			dataUsingEncoding:NSUTF8StringEncoding]];
   		 [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    	[body appendData:[NSData dataWithData:data]];
   		[body appendData:[[NSString stringWithFormat:kEndTag] dataUsingEncoding:NSUTF8StringEncoding]];

    	// close form
    	[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", kBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

Every appended data need a start tag and end tag and boundary.

“Username” is the unique key to identify username at server side, means we are send username using this keyword (“Username”) and server team identifying username using the same key.”uploadVideo” is a key to identify video data for our end and server end.

NOTE :- Please do not ignore start and end tag while appending text and video data. Key should be same for both end. If we write different key like “name”, Server unable to identify “Username” and we did not get correct response from server.

9. After sending request successfully, will get response from server. For that Http Connection delegate function will be called mentioned below :-

          – (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

Here, will receive data from server. Append server data to _receivedData using code given below.
[_receivedData appendData:data];

– (void) connectionDidFinishLoading:(NSURLConnection *) connection
Here will parse _receivedData using code given below :-

NSXMLDocument* xmlDoc = [[NSXMLDocument alloc] initWithData:_receivedData options:0 error:nil];
NSXMLElement* rootElement = [xmlDoc rootElement];

Here will check the “status code” using the code

if (![rootElement integerValueForNode:@"status_code"]) // status code not valid gives an error message
       {
          [UIUtils messageAlert:nil title:[rootElement stringValueForNode:@"error_message"] delegate:self];
       }
	   else
       {
          // message shows video posted successfully
          [UIUtils messageAlert:nil title:@"Video posted successfully" delegate:self];
           _postImageView.image = nil;
       }

10. Please click here download the attachment with full code.

Written By: Neha Gupta, Software Developer, Mindfire Solutions

Advertisements

6 thoughts on “Upload Video to Server Using Multiparts in iPhone

  1. Hi,
    Finally i got any working tutorial. Thanks for this tutorial.
    I have a question!
    I got a success message of, successfully uploaded.
    I worked with this demo only, haven’t change any server url.. so where can i check my video,which is uploaded..? Where it is uploaded actually?

  2. Server side code for handling Multipart image upload request…Language C#..

    public async Task UploadPhoto()
    {
    // Check if request is of multipart type
    if (!Request.Content.IsMimeMultipartContent())
    {
    return Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, MessageBox.UnsupportedType);
    }

    string extension = string.Empty;
    byte[] data = null;
    var filename = string.Empty;
    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);

    foreach (var file in provider.Contents)
    {
    filename = file.Headers.ContentDisposition.FileName.Trim(‘\”‘);
    extension = Path.GetExtension(filename).ToLower();
    data = file.ReadAsByteArrayAsync().Result;
    }

    string[] AllowedFileExtensions = new string[] { “.jpg”, “.gif”, “.png”, “.jpeg” };

    //Matches the extension of uploaded file for that of image
    if (!AllowedFileExtensions.Contains(extension))
    {
    return Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, “Unsupported file type”);
    }

    //uploads the image corressponding to the user id
    **************************************************************
    //Code for uploading file data (in byte[]) to database
    var success = UploadToDb(data, userId);
    **************************************************************

    if (success)
    {
    return Request.CreateResponse(HttpStatusCode.OK, “Image Updated”);
    }
    else
    {
    return Request.CreateErrorResponse(HttpStatusCode.BadRequest, MessageBox.AnErrorOccured);
    }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s