1. 程式人生 > >斷點續傳和分塊上傳

斷點續傳和分塊上傳

sage release data alt for path type eval etag

#pragma mark 異步上傳

- (void)uploadObjectAsync:(NSString *)FileURL objectKey:(NSString *)objectKey{

OSSPutObjectRequest * put = [OSSPutObjectRequest new];

NSLog(@"objectKey is %@",objectKey);

// required fields

put.bucketName = bucketName;

put.objectKey = objectKey;

put.uploadingFileURL = [NSURL fileURLWithPath:FileURL];

// optional fields

put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {

NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);

dispatch_async(dispatch_get_main_queue(), ^{

float gress = (double)totalByteSent/totalBytesExpectedToSend;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123上傳中");

}

});

};

OSSTask * putTask = [client putObject:put];

[putTask continueWithBlock:^id(OSSTask *task) {

NSLog(@" putTask :%@",putTask.result);

NSLog(@"objectKey: %@", put.objectKey);

uploadputkey = put.objectKey;

if (!task.error) {

NSLog(@"upload object success!");

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

} else {

NSLog(@"upload object failed, error: %@" , task.error);

}

return nil;

}];

}

#pragma mark 同步上傳

- (void)uploadObjectSync:(NSString *)FileURL objectKey:(NSString *)objectKey {

OSSPutObjectRequest * put = [OSSPutObjectRequest new];

// required fields

put.bucketName = bucketName;

put.objectKey = objectKey;

put.uploadingFileURL = [NSURL fileURLWithPath:FileURL];

// optional fields

put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {

NSLog(@"uploadProgress is %lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);

dispatch_async(dispatch_get_main_queue(), ^{

float gress = totalByteSent/totalBytesExpectedToSend;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123");

}

});

};

OSSTask * putTask = [client putObject:put];

[putTask waitUntilFinished]; // 阻塞直到上傳完成

NSLog(@" putTask :%@",putTask.result);

if (!putTask.error) {

NSLog(@"upload object success!");

NSLog(@" putTask :%@",putTask.result);

NSLog(@"objectKey: %@", put.objectKey);

uploadputkey = put.objectKey;

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

} else {

NSLog(@"upload object failed, error: %@" , putTask.error);

}

}

#pragma mark 追加上傳

- (void)appendObject {

OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];

// 必填字段

append.bucketName = @"android-test";

append.objectKey = @"file1m";

append.appendPosition = 0; // 指定從何處進行追加

NSString * docDir = [self getDocumentDirectory];

append.uploadingFileURL = [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"file1m"]];

// 可選字段

append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {

NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);

};

// append.contentType = @"";

// append.contentMd5 = @"";

// append.contentEncoding = @"";

// append.contentDisposition = @"";

OSSTask * appendTask = [client appendObject:append];

NSLog(@" putTask :%@",appendTask.result);

[appendTask continueWithBlock:^id(OSSTask *task) {

NSLog(@"objectKey: %@", append.objectKey);

if (!task.error) {

NSLog(@"append object success!");

OSSAppendObjectResult * result = task.result;

NSString * etag = result.eTag;

long nextPosition = result.xOssNextAppendPosition;

NSLog(@"etag: %@, nextPosition: %ld", etag, nextPosition);

} else {

NSLog(@"append object failed, error: %@" , task.error);

}

return nil;

}];

}

#pragma mark 異步下載

- (void)downloadObjectAsync {

OSSGetObjectRequest * request = [OSSGetObjectRequest new];

// required

request.bucketName = @"android-test";

request.objectKey = @"file1m";

//optional

request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {

NSLog(@"%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);

};

OSSTask * getTask = [client getObject:request];

[getTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"download object success!");

OSSGetObjectResult * getResult = task.result;

NSLog(@"download dota length: %lu", [getResult.downloadedData length]);

} else {

NSLog(@"download object failed, error: %@" ,task.error);

}

return nil;

}];

}

#pragma mark 同步下載

- (void)downloadObjectSync {

OSSGetObjectRequest * request = [OSSGetObjectRequest new];

// required

request.bucketName = @"android-test";

request.objectKey = @"file1m";

//optional

request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {

NSLog(@"%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);

};

// NSString * docDir = [self getDocumentDirectory];

// request.downloadToFileURL = [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"downloadfile"]];

OSSTask * getTask = [client getObject:request];

[getTask waitUntilFinished];

if (!getTask.error) {

OSSGetObjectResult * result = getTask.result;

NSLog(@"download data length: %lu", [result.downloadedData length]);

} else {

NSLog(@"download data error: %@", getTask.error);

}

}

#pragma mark 獲取meta

- (void)headObject {

OSSHeadObjectRequest * head = [OSSHeadObjectRequest new];

head.bucketName = @"android-test";

head.objectKey = @"file1m";

OSSTask * headTask = [client headObject:head];

[headTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

OSSHeadObjectResult * headResult = task.result;

NSLog(@"all response header: %@", headResult.httpResponseHeaderFields);

// some object properties include the ‘x-oss-meta-*‘s

NSLog(@"head object result: %@", headResult.objectMeta);

} else {

NSLog(@"head object error: %@", task.error);

}

return nil;

}];

}

#pragma mark 刪除Object

- (void)deleteObject {

OSSDeleteObjectRequest * delete = [OSSDeleteObjectRequest new];

delete.bucketName = @"android-test";

delete.objectKey = @"file1m";

OSSTask * deleteTask = [client deleteObject:delete];

[deleteTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"delete success !");

} else {

NSLog(@"delete erorr, error: %@", task.error);

}

return nil;

}];

}

#pragma mark 復制Object

- (void)copyObjectAsync {

OSSCopyObjectRequest * copy = [OSSCopyObjectRequest new];

copy.bucketName = @"android-test"; // 復制到哪個bucket

copy.objectKey = @"file_copy_to"; // 復制為哪個object

copy.sourceCopyFrom = [NSString stringWithFormat:@"/%@/%@", @"android-test", @"file1m"]; // 從哪裏復制

OSSTask * copyTask = [client copyObject:copy];

[copyTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"copy success!");

} else {

NSLog(@"copy error, error: %@", task.error);

}

return nil;

}];

}

#pragma mark 簽名URL授予第三方訪問

- (void)signAccessObjectURL {

NSString * constrainURL = nil;

NSString * publicURL = nil;

// sign constrain url

OSSTask * task = [client presignConstrainURLWithBucketName:bucketName

withObjectKey:uploadputkey

withExpirationInterval:60 * 30];

// if (!task.error) {

// constrainURL = task.result;

// NSLog(@"constrainURL is %@",constrainURL);

// postPublicURL = publicURL;

// [self createTranscodeJobFlow];

// } else {

// NSLog(@"error: %@", task.error);

// }

// sign public url

task = [client presignPublicURLWithBucketName:bucketName

withObjectKey:uploadputkey];

if (!task.error) {

publicURL = task.result;

NSLog(@"publicURL is %@",publicURL);

postPublicURL = publicURL;

[self createTranscodeJobFlow];

} else {

NSLog(@"sign url error: %@", task.error);

}

}

#pragma mark 分塊上傳

- (void)multipartUpload:(NSString *)FileURL objectKey:(NSString *)objectKey{

__block NSString * uploadId = nil;

__block NSMutableArray * partInfos = [NSMutableArray new];

NSString * uploadToBucket = bucketName;

NSString * uploadObjectkey = objectKey;

OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];

init.bucketName = uploadToBucket;

init.objectKey = uploadObjectkey;

init.contentType = @"video/x-m4v";

init.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil];

OSSTask * initTask = [client multipartUploadInit:init];

[initTask waitUntilFinished];

if (!initTask.error) {

OSSInitMultipartUploadResult * result = initTask.result;

MUuploadID = result.uploadId;

uploadputkey =objectKey;

NSLog(@"init multipart upload success: %@", result.uploadId);

} else {

NSLog(@"multipart upload failed, error: %@", initTask.error);

return;

}

NSDictionary * pathsize = [self getVideoInfoWithSourcePath:FileURL];

NSInteger videoSize = [pathsize[@"size"]integerValue];

//要上傳的文件

chuckCount = 100; // 10塊 好區分圖譜

//分片上傳數量

uint64_t offset = videoSize/chuckCount;

for (int i = 1; i <= chuckCount; i++) {

@autoreleasepool {

OSSUploadPartRequest * uploadPart = [OSSUploadPartRequest new];

uploadPart.bucketName = uploadToBucket;

uploadPart.objectkey = uploadObjectkey;

uploadPart.uploadId = uploadId;

uploadPart.partNumber = i; // part number start from 1

NSString * docDir = FileURL;

uploadPart.uploadPartFileURL = [NSURL URLWithString:docDir];

NSFileHandle* readHandle = [NSFileHandle fileHandleForReadingAtPath:FileURL];

[readHandle seekToFileOffset:offset * (i -1)];

NSData* data = [readHandle readDataOfLength:offset];

uploadPart.uploadPartData = data;

// uploadPart.uploadPartProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {

// NSLog(@"%lld %lld %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);

// dispatch_async(dispatch_get_main_queue(), ^{

// float gress = (double)totalBytesSent/totalBytesExpectedToSend;

// if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

// [self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

// NSLog(@"gress123上傳中");

// }

// });

// };

OSSTask * uploadPartTask = [client uploadPart:uploadPart];

[uploadPartTask waitUntilFinished];

if (!uploadPartTask.error) {

OSSUploadPartResult * result = uploadPartTask.result;

uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:uploadPart.uploadPartFileURL.absoluteString error:nil] fileSize];

[partInfos addObject:[OSSPartInfo partInfoWithPartNum:i eTag:result.eTag size:fileSize]];

[self listParts:MUuploadID PartNumber:uploadPart.partNumber];

} else {

NSLog(@"upload part error: %@", uploadPartTask.error);

return;

}

}

}

// OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];

// complete.bucketName = uploadToBucket;

// complete.objectKey = uploadObjectkey;

// complete.uploadId = uploadId;

// complete.partInfos = partInfos;

//

// OSSTask * completeTask = [client completeMultipartUpload:complete];

//

// [completeTask waitUntilFinished];

//

// if (!completeTask.error) {

// NSLog(@"multipart upload success!");

//

// } else {

// NSLog(@"multipart upload failed, error: %@", completeTask.error);

// return;

// }

}

#pragma mark 羅列分塊

- (void)listParts:(NSString *)uploadId PartNumber:(int)partNumber{

OSSListPartsRequest * listParts = [OSSListPartsRequest new];

listParts.bucketName = bucketName;

listParts.objectKey = uploadputkey;

listParts.uploadId = uploadId;

OSSTask * listPartTask = [client listParts:listParts];

[listPartTask continueWithBlock:^id(OSSTask *task) {

if (!task.error) {

NSLog(@"list part result success!");

OSSListPartsResult * listPartResult = task.result;

dispatch_async(dispatch_get_main_queue(), ^{

float gress = (double)partNumber/chuckCount;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123上傳中");

}

if (gress == 1.0) {

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

}

});

NSLog(@"listPartResult is%@",listPartResult);

for (NSDictionary * partInfo in listPartResult.parts) {

NSLog(@"partInfoeachpart: %@", partInfo);

}

} else {

NSLog(@"list part result error: %@", task.error);

}

return nil;

}];

}

#pragma mark ----// 斷點續傳 ----

- (void)resumableUpload:(NSString *)FileURL objectKey:(NSString *)objectKey{

__block NSString * recordKey;

// NSString * docDir = [self getDocumentDirectory];

NSString * filePath =FileURL;

// NSString * bucketName = bucketName;

// objectKey = @"uploadKey";

[[[[[[OSSTask taskWithResult:nil] continueWithBlock:^id(OSSTask *task) {

// 為該文件構造一個唯一的記錄鍵

NSURL * fileURL = [NSURL fileURLWithPath:filePath];

NSDate * lastModified;

NSError * error;

[fileURL getResourceValue:&lastModified forKey:NSURLContentModificationDateKey error:&error];

if (error) {

return [OSSTask taskWithError:error];

}

recordKey = [NSString stringWithFormat:@"%@-%@-%@-%@", bucketName, objectKey, [OSSUtil getRelativePath:filePath], lastModified];

// 通過記錄鍵查看本地是否保存有未完成的UploadId

NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];

return [OSSTask taskWithResult:[userDefault objectForKey:recordKey]];

}] continueWithSuccessBlock:^id(OSSTask *task) {

if (!task.result) {

// 如果本地尚無記錄,調用初始化UploadId接口獲取

OSSInitMultipartUploadRequest * initMultipart = [OSSInitMultipartUploadRequest new];

initMultipart.bucketName = bucketName;

initMultipart.objectKey = objectKey;

initMultipart.contentType = @"video/x-m4v";

return [client multipartUploadInit:initMultipart];

}

OSSLogVerbose(@"An resumable task for uploadid: %@", task.result);

return task;

}] continueWithSuccessBlock:^id(OSSTask *task) {

NSString * uploadId = nil;

if (task.error) {

return task;

}

if ([task.result isKindOfClass:[OSSInitMultipartUploadResult class]]) {

uploadId = ((OSSInitMultipartUploadResult *)task.result).uploadId;

} else {

uploadId = task.result;

}

if (!uploadId) {

return [OSSTask taskWithError:[NSError errorWithDomain:OSSClientErrorDomain

code:OSSClientErrorCodeNilUploadid

userInfo:@{OSSErrorMessageTOKEN: @"Can‘t get an upload id"}]];

}

// 將“記錄鍵:UploadId”持久化到本地存儲

NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];

[userDefault setObject:uploadId forKey:recordKey];

[userDefault synchronize];

return [OSSTask taskWithResult:uploadId];

}] continueWithSuccessBlock:^id(OSSTask *task) {

// 持有UploadId上傳文件

_resumableUpload = [OSSResumableUploadRequest new];

_resumableUpload.bucketName = bucketName;

_resumableUpload.objectKey = objectKey;

_resumableUpload.uploadId = task.result;

_resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:filePath];

_resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {

NSLog(@"%lld %lld %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);

dispatch_async(dispatch_get_main_queue(), ^{

float gress = (double)totalBytesSent/totalBytesExpectedToSend;

if([self.dclickDelegate respondsToSelector:@selector(WaveProgressPlus:)]){

[self.dclickDelegate performSelector:@selector(WaveProgressPlus:) withObject:@(gress)];

NSLog(@"gress123上傳中");

}

});

};

return [client resumableUpload:_resumableUpload];

}] continueWithBlock:^id(OSSTask *task) {

if (task.error) {

if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) {

// 如果續傳失敗且無法恢復,需要刪除本地記錄的UploadId,然後重啟任務

[[NSUserDefaults standardUserDefaults] removeObjectForKey:recordKey];

}

} else {

NSLog(@"%@",task.result);

NSLog(@"%@",self->_resumableUpload.objectKey);

NSLog(@"upload completed!");

uploadputkey = _resumableUpload.objectKey;

// 上傳成功,刪除本地保存的UploadId

[[NSUserDefaults standardUserDefaults] removeObjectForKey:recordKey];

NSLog(@"upload object success!");

if([self.dclickDelegate respondsToSelector:@selector(dissbackView)]){

[self.dclickDelegate performSelector:@selector(dissbackView)];

}

[self signAccessObjectURL];

}

return nil;

}];

}

-(void)cannelUpdate{

[_resumableUpload cancel];

// _resumableUpload = nil;

NSLog(@"取消網絡操作");

// [OSSTask cancelledTask];

}

#pragma mark --檢查數據大小---

- (NSDictionary *)getVideoInfoWithSourcePath:(NSString *)path{

NSLog(@"%@",path);

AVURLAsset * asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];

CMTime time = [asset duration];

int seconds = ceil(time.value/time.timescale);

NSInteger fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize;

return @{@"size" : @(fileSize),

@"duration" : @(seconds)};

}

斷點續傳和分塊上傳