I'm trying to upload a video from an iOS device's library to AWS.
I have a method called uploadVideo that gets passed an ALAsset asset which I then try to upload as follows:
- (void)uploadVideo:(ALAsset *)asset :(UIImage*)image{
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = @"test";
NSString *assetFilename = [[asset defaultRepresentation] filename];
if(!assetFilename){
NSDate *now = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
[dateFormat setDateFormat:@"MM-dd-yyyy_HH-mm-ss-SS"];
assetFilename = [dateFormat stringFromDate:now];
}
uploadRequest.key = assetFilename;
uploadRequest.body = asset.defaultRepresentation.url.absoluteURL;
NSLog(@"uploadRequest.body: %@", asset.defaultRepresentation.url.absoluteString);
[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor]
withBlock:^id(AWSTask *task) {
if (task.error) {
if ([task.error.domain isEqualToString:AWSS3TransferManagerErrorDomain]) {
switch (task.error.code) {
case AWSS3TransferManagerErrorCancelled:
case AWSS3TransferManagerErrorPaused:
break;
default:
NSLog(@"Error: %@", task.error);
break;
}
} else {
// Unknown error.
NSLog(@"Error: %@", task.error);
}
}
if (task.result) {
AWSS3TransferManagerUploadOutput *uploadOutput = task.result;
// The file uploaded successfully.
NSLog(@"uploaded the file to aws successfully with task result %@", task.result);
}
return nil;
}];
}
I am receiving the error:
Error: Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be completed. (Cocoa error 260.)" UserInfo=0x1706686c0 {NSFilePath=/asset.mp4, NSUnderlyingError=0x170256170 "The operation couldn’t be completed. No such file or directory"}
But when I log the uploadRequest.body path, it seems to be the full path:
uploadRequest.body: assets-library://asset/asset.mp4?id=01DD578D-6320-430E-BAB4-F339B3EB4D5C&ext=mp4
How do I properly set the body of a selected asset to upload to AWS?
Edit: It looks like you can't upload an ALAsset directly to AWS. To try to resolve this issue, I tried saving a temporary video file (as described in Getting video from ALAsset), but I'm still running into problems. I get the error that no file exists at the created path. Here is my code:
NSString *vidTmpPath = [self videoAssetURLToTempFile:asset.defaultRepresentation.url];
NSLog(@"vidTmpPath: %@", vidTmpPath);
if ([[NSFileManager defaultManager] fileExistsAtPath:vidTmpPath])
{
NSLog(@"video file exists at path");
}else{
NSLog(@"no video exists at path");
}
uploadRequest.body = [NSURL URLWithString: vidTmpPath];
And the videoAssetURLToTempFile method:
-(NSString*) videoAssetURLToTempFile:(NSURL*)url
{
NSLog(@"in videoAssetURLToTempFile");
NSString * surl = [url absoluteString];
NSString * ext = [surl substringFromIndex:[surl rangeOfString:@"ext="].location + 4];
NSTimeInterval ti = [[NSDate date]timeIntervalSinceReferenceDate];
NSString * filename = [NSString stringWithFormat: @"%f.%@",ti,ext];
NSString * tmpfile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation * rep = [myasset defaultRepresentation];
NSUInteger size = [rep size];
const int bufferSize = 8192;
NSLog(@"Writing to %@",tmpfile);
FILE* f = fopen([tmpfile cStringUsingEncoding:1], "wb+");
if (f == NULL) {
NSLog(@"Can not create tmp file.");
return;
}
Byte * buffer = (Byte*)malloc(bufferSize);
int read = 0, offset = 0, written = 0;
NSError* err;
if (size != 0) {
do {
read = [rep getBytes:buffer
fromOffset:offset
length:bufferSize
error:&err];
written = fwrite(buffer, sizeof(char), read, f);
offset += read;
} while (read != 0);
}
fclose(f);
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(@"Can not get asset - %@",[myerror localizedDescription]);
};
if(url)
{
NSLog(@"saving at url: %@", url);
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:url
resultBlock:resultblock
failureBlock:failureblock];
}
return tmpfile;
}