Ios 通过NSURLSession上传大型视频会导致内存压力崩溃
我使用以下代码将视频上传到服务器,这需要我将视频从视频格式转换为Ios 通过NSURLSession上传大型视频会导致内存压力崩溃,ios,uiimagepickercontroller,nsdata,nsurlsession,Ios,Uiimagepickercontroller,Nsdata,Nsurlsession,我使用以下代码将视频上传到服务器,这需要我将视频从视频格式转换为NSData。但是,当视频较大(例如10分钟视频)时,应用程序会因内存压力而崩溃。我如何解决这个问题 - (void)uploadVideo { NSDictionary *params = nil; NSString *NSURLSessionIdentifier = [NSString stringWithFormat:@"%@%@",@"my.bundle.identifier.",[self getTimeS
NSData
。但是,当视频较大(例如10分钟视频)时,应用程序会因内存压力而崩溃。我如何解决这个问题
- (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];
}
p、 s.self.video\u url
是由UIImagePickerController
提供的文件url,它只过滤要选择的视频。然后我选择一个10分钟的视频
p、 我在同一个应用程序中也得到了
AFNetworking
,它能帮助后台传输吗?问题很明显-10分钟视频文件太大,无法存储在内存中什么
self.video_data = [NSData dataWithContentsOfURL:self.video_url];
是的
解决方案不是将所有请求体存储在内存中。最简单的方法是使用NSURLRequest的属性。您可以自己创建NSInputStream,但由于您已经有了AFNetworking,所以使用它要容易得多。在我的项目中,我是这样做的:
// 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];
//data.fields是带有参数的字典
NSMutableURLRequest*请求=[[AFHTTPRequestSerializer序列化程序]
multipartFormRequestWithMethod:@“POST”
url字符串:[url绝对字符串]
参数:零
构造体WithBlock:^(id formData)
{
[data.fields enumerateKeysAndObjectsUsingBlock:^(id键、id对象、布尔*停止){
[formData appendPartWithFormData:[obj DataUsingEncode:NSUTF8StringEncoding]名称:键];
}];
[formData appendPartWithFileURL:fileURL名称:@“文件0”错误:&error2];
}
错误:&错误];
您应该能够通过使用和使用其setter来实现这一点
下面是根据我的一些代码改编的代码片段。它在10分钟的视频播放过程中表现良好。大部分是60-90分钟的大型视频
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]];
现在,您可以将此请求用于
你需要将视频分成2mb的部分,然后将这些部分上传到服务器。我想是这样的,但如何修改我的上传代码以添加2MB块呢?您需要将Base64发送到服务器,并带有部件号,服务器可以收集所有部件,一旦完成所有部件,则将其全部Base64转换为MP4。为什么您要尝试在内存中加载整个视频并发送它?你的应用程序崩溃是完全正常的。应使用多部分/表单数据发送所有文件,这将确保您的应用程序在上载时不会内存崩溃。AFnetworking做得很简单。这在后台模式下无法工作,连接将被断开。与InputStream(数据:data)相比,我有确切的内存使用率,而且使用上面的方法发送速度要慢得多。
NSURLConnection *connection =[[NSURLConnection alloc] initWithRequest:request delegate:self];