gpt4 book ai didi

ios - Phasset + AfNetworking 上传多个视频

转载 作者:可可西里 更新时间:2023-11-01 03:05:21 41 4
gpt4 key购买 nike

目前我正在使用以下代码上传视频:

  NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[UploadModel getAssetData:entity.asset resultHandler:^(NSData *filedata) {
NSString *mimeType =[FileHelper mimeTypeForFileAtUrl:entity.fileUrl];
// NSError *fileappenderror;

[formData appendPartWithFileData:filedata name:@"data" fileName: entity.filename mimeType:mimeType];

}];

} error:&urlRequestError];

GetAssetData 方法

+(void)getAssetData: (PHAsset*)mPhasset resultHandler:(void(^)(NSData *imageData))dataResponse{ 

PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;

[[PHImageManager defaultManager] requestAVAssetForVideo:mPhasset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {

if ([asset isKindOfClass:[AVURLAsset class]]) {
NSURL *localVideoUrl = [(AVURLAsset *)asset URL];
NSData *videoData= [NSData dataWithContentsOfURL:localVideoUrl];
dataResponse(videoData);

}
}];
}

这种方法的问题是,只要上传大型/多个视频文件,应用程序就会耗尽内存。我想这是由于请求 NSDATA(又名 filedata )上传文件(见上面的方法)。我尝试使用方法请求文件路径appendPartWithFileURL 代替 appendPartWithFileData它适用于模拟器。并在真实设备上失败,并出现无法通过指定路径读取文件的错误。我在这里描述了这个问题 PHAsset + AFNetworking. Unable to upload files to the server on a real device

=======================================

更新:我修改了我的代码以测试在新的 iPhone 6s+ 上通过本地路径上传文件的方法,如下所示

 NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

NSString *mimeType =[FileHelper mimeTypeForFileAtUrl:entity.fileUrl];
NSError *fileappenderror;

[formData appendPartWithFileURL:entity.fileUrl name:@"data" fileName:entity.filename mimeType:mimeType error:&fileappenderror];

if (fileappenderror) {
[Sys MyLog: [NSString stringWithFormat:@"Failed to append: %@", [fileappenderror localizedDescription] ] ];
}

} error:&urlRequestError];

在 iPhone 6s+ 上测试给出了更清晰的日志警告它是调用方法 appendPartWithFileURL

的结果
 <Warning>: my_log: Failed to  append file: The operation couldn’t be completed. File URL not reachable.
deny(1) file-read-metadata /private/var/mobile/Media/DCIM/100APPLE/IMG_0008.MOV
15:41:25 iPhone-6s kernel[0] <Notice>: Sandbox: My_App(396) deny(1) file-read-metadata /private/var/mobile/Media/DCIM/100APPLE/IMG_0008.MOV
15:41:25 iPhone-6s My_App[396] <Warning>: my_log: Failed to append file: The file “IMG_0008.MOV” couldn’t be opened because you don’t have permission to view it.

这是用于从 PHAsset 获取本地文件路径的代码

if (mPhasset.mediaType == PHAssetMediaTypeImage) {

PHContentEditingInputRequestOptions * options = [[PHContentEditingInputRequestOptions alloc]init];
options.canHandleAdjustmentData = ^BOOL(PHAdjustmentData *adjustmeta){
return YES;
};

[mPhasset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {

dataResponse(contentEditingInput.fullSizeImageURL);

}];
}else if(mPhasset.mediaType == PHAssetMediaTypeVideo){
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;

[[PHImageManager defaultManager] requestAVAssetForVideo:mPhasset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
if ([asset isKindOfClass:[AVURLAsset class]]) {
NSURL *localVideoUrl = [(AVURLAsset *)asset URL];
dataResponse(localVideoUrl);

}



}];
}

所以问题还是一样——上传到服务器的文件是空的

最佳答案

上面提出的解决方案只是部分正确(之前是我自己发现的)。由于系统不允许读取沙箱外的文件,因此无法通过文件路径访问(读/写)文件,只能复制文件。 iOS 9及以上版本Photos Framework提供API(不能通过 NSFileManager ,只能使用Photos framework api)将文件复制到你App的沙箱目录中。这是我在挖掘文档和头文件后使用的代码。

首先复制一个文件到应用程序沙箱目录。

// Assuming PHAsset has only one resource file. 
PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset:myPhasset] firstObject];

+(void)writeResourceToTmp: (PHAssetResource*)resource pathCallback: (void(^)(NSURL*localUrl))pathCallback {
// Get Asset Resource. Take first resource object. since it's only the one image.
NSString *filename = resource.originalFilename;
NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:filename];
NSURL *localpath = [NSURL fileURLWithPath:pathToWrite];
PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new];
options.networkAccessAllowed = YES;
[[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource toFile:localpath options:options completionHandler:^(NSError * _Nullable error) {
if (error) {
[Sys MyLog: [NSString stringWithFormat:@"Failed to write a resource: %@",[error localizedDescription]]];
}

pathCallback(localpath);
}];

} // Write Resource into Tmp

上传任务本身

      NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" 
URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// Assuming PHAsset has only one resource file.

PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset:myPhasset] firstObject];

[FileHelper writeResourceToTmp:resource pathCallback:^(NSURL *localUrl)
{
[formData appendPartWithFileURL: localUrl name:@"data" fileName:entity.filename mimeType:mimeType error:&fileappenderror];

}]; // writeResourceToTmp

}// End Url Request

AFHTTPRequestOperation * operation = [[AFHTTPRequestOperation alloc ] initWithRequest:urlRequest];
//.....
// Further steps are described in the AFNetworking Docs

这种上传方法有一个明显的缺点。如果设备进入“ sleep 模式”,你就完蛋了。因此,这里推荐的上传方法是使用方法。uploadTaskWithRequest:fromFile:progress:completionHandlerAFURLSessionManager.

对于低于 iOS 9 的版本。如果是图像,您可以从 PHAsset 中获取 NSDATA,如我问题的代码所示......并上传。或者在上传之前先将其写入您的应用程序沙箱存储。这种方法在大文件的情况下不可用。或者,您可能希望使用图像/视频选择器将文件导出为 ALAssetALAsset 提供了允许您从存储中读取文件的 api。但是您必须在上传之前将其写入沙盒存储。

关于ios - Phasset + AfNetworking 上传多个视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33278540/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com