![](/img/trans.png)
[英]GPUImage: imageByFilteringImage causes memory pressure resulting app crash
[英]Upload large video via NSURLSession causes memory pressure crash
我使用以下代碼將視頻上傳到服務器,這需要我將視頻格式的視頻轉換為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];
}
ps self.video_url
是UIImagePickerController
提供的文件URL,僅過濾要選擇的視頻。 然后我選擇一個10分鍾的視頻。
ps我AFNetworking
相同的應用程序中獲得了AFNetworking
,它可以幫助進行后台傳輸嗎?
您應該能夠通過使用NSMutableURLRequest並使用其setHTTPBodyStream 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]];
您現在可以將此請求與NSURLConnection一起使用
NSURLConnection *connection =[[NSURLConnection alloc] initWithRequest:request delegate:self];
問題很明顯 - 10分鍾的視頻文件太大,無法存儲在內存中
self.video_data = [NSData dataWithContentsOfURL:self.video_url];
確實。
解決方案不是將所有請求主體存儲在內存中。 最簡單的方法是使用NSURLRequest的HTTPBodyStream屬性。 您可以自己創建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];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.