簡體   English   中英

通過NSURLSession上傳大型視頻會導致內存壓力崩潰

[英]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_urlUIImagePickerController提供的文件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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM