Downloading large video via NSURLSession causes memory crash

I use the following codes to upload video to a server, which requires me to convert video from video format to NSData . However, when the video is large (for example, a 10-minute video), the application crashes due to memory pressure. How can i solve this?

 - (void)uploadVideo { NSDictionary *params = nil; NSString *NSURLSessionIdentifier = [NSString stringWithFormat:@"%@%@",@"my.bundle.identifier.",[self getTimeString]]; NSURLSessionConfiguration *sessionConfig; // SessionConfiguration With iOS Version if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:NSURLSessionIdentifier]; } else { sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:NSURLSessionIdentifier]; } sessionConfig.HTTPMaximumConnectionsPerHost = 1; NSURLSession *uploadSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue new]]; OMGMultipartFormData *multipartFormData = [OMGMultipartFormData new]; NSString *url = @"SOME_UPLOAD_URL"; // ========= PROBLEMATIC LINE below ========= self.video_data = [NSData dataWithContentsOfURL:self.video_url]; // ========= PROBLEMATIC LINE above ========= [multipartFormData addFile:self.video_data parameterName:@"file" filename:@"file.mp4" contentType:@"video/mp4"]; NSURLRequest *rq = [OMGHTTPURLRQ POST:url:multipartFormData]; id path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"upload.NSData"]; [rq.HTTPBody writeToFile:path atomically:YES]; [[uploadSession uploadTaskWithRequest:rq fromFile:[NSURL fileURLWithPath:path]] resume]; } 

ps self.video_url is the URL of the file specified by UIImagePickerController , which filters only the video to be selected. Then I select a 10 minute video.

ps I got AFNetworking in the same application, can it help with background AFNetworking ?

+7
ios uiimagepickercontroller nsdata nsurlsession
source share
2 answers

You should be able to do this using NSMutableURLRequest and using setHTTPBodyStream .

Below are snippets adapted from my code. He did a great job with the video stream in 10 minutes. mostly large videos from 60 to 90 minutes.

 NSData *movieData = [NSData dataWithContentsOfFile:theMovieSourceString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:@"video/quicktime" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"attachment; filename=\"%@\"",yourMovieSourceString] forHTTPHeaderField:@"Content-Disposition"]; [request setValue:[NSString stringWithFormat:@"%ld",(unsigned long)[movieData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBodyStream:[NSInputStream inputStreamWithFileAtPath:yourMovieSourceString]]; 

Now you can use this query with NSURLConnection

 NSURLConnection *connection =[[NSURLConnection alloc] initWithRequest:request delegate:self]; 
+1
source share

The problem is obvious - the 10-minute video file is too large to hold in memory, which

 self.video_data = [NSData dataWithContentsOfURL:self.video_url]; 

does.

The solution is not to store the entire request body in memory. The easiest way is to use the NSURLRequest HTTPBodyStream property. You can create NSInputStream yourself, but since you already have AFNetworking, it is much easier to use. In my project, I do it as follows:

 // data.fields is a dictionary with params NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[url absoluteString] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [data.fields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [formData appendPartWithFormData:[obj dataUsingEncoding:NSUTF8StringEncoding] name:key]; }]; [formData appendPartWithFileURL:fileURL name:@"file_0" error:&error2]; } error:&error]; 
0
source share

All Articles