檔案上傳是指將媒體檔案(本地檔案或網路檔案)從用戶端上傳至點播儲存。在iOS端上,檔案上傳通過上傳執行個體(VODUploadClient)完成。本文介紹如何使用iOS端上傳SDK完成媒體上傳。
前提條件
您已經整合ApsaraVideo for VOD提供的iOS上傳SDK。具體操作,請參見整合iOS SDK。
上傳流程
用戶端上傳SDK封裝了OSS上傳邏輯。在用戶端上傳媒體檔案時,會直接將檔案上傳到點播儲存(基於OSS),不會再經服務端進行中轉,故用戶端上傳必須進行鑒權,也就是需要您在應用伺服器上部署授權服務以擷取上傳地址和憑證。目前用戶端上傳SDK支援兩種授權方式:
上傳地址和憑證方式上傳流程詳解
以整合點播服務端SDK擷取上傳地址和憑證為例,完整的上傳流程如下圖所示:
使用者在上傳應用伺服器部署授權服務(如整合點播服務端SDK)用於擷取上傳地址和憑證。
用戶端向上傳應用伺服器發起請求擷取上傳地址和憑證。
上傳應用伺服器向ApsaraVideo for VOD服務發起請求擷取上傳地址和憑證。
點播服務返回上傳地址和憑證。
說明 點播服務在下發上傳地址和憑證時還會自動建立媒資資訊,即媒體ID(MediaId),用於媒資生命週期管理或ApsaraVideo for Media Processing。
擷取視頻上傳地址和憑證返回的VideoId
即媒體ID。
擷取圖片上傳地址和憑證返回的ImageId
即媒體ID。
擷取輔助媒資上傳地址和憑證返回的MediaId
即媒體ID。
請妥善儲存媒體ID,作為媒資管理、音視頻播放、ApsaraVideo for Media Processing等的輸入。
上傳應用伺服器向用戶端下發上傳地址和憑證。
用戶端使用上傳地址和憑證初始化上傳執行個體。
用戶端構造上傳參數發起上傳請求。
OSS服務返回上傳結果。
說明 上傳結果也可以通過提前配置回調接收上傳相關事件來監聽。
STS方式上傳流程詳解
使用STS方式上傳的完整的流程如下圖所示:
使用者在上傳應用伺服器部署授權服務(如整合阿里雲STS SDK)用於擷取STS臨時Token。
用戶端向上傳應用伺服器發起請求擷取STS臨時Token。
上傳應用伺服器向阿里雲STS服務發起請求擷取STS臨時Token。
阿里雲STS服務返回上傳地址和憑證。
上傳應用伺服器向用戶端下發STS臨時Token。
用戶端使用STS臨時Token初始化上傳執行個體。
用戶端構造請求發起上傳請求。
OSS服務返回上傳結果。
說明 上傳結果也可以通過提前配置回調接收上傳相關事件來監聽。
上傳檔案
在iOS端上傳檔案的基本操作步驟如下:
擷取上傳地址和憑證或STS臨時Token,用於上傳授權。
iOS上傳SDK支援以下兩種上傳授權方式,推薦使用憑證方式:
執行結果
使用擷取到的上傳地址和憑證或STS臨時Token作為入參初始化上傳執行個體。
使用上傳憑證或STS臨時Token初始化上傳執行個體。
初始化上傳執行個體分為聲明初始化回調和初始化上傳執行個體兩步。
聲明VODUploadClient
屬性,不能是局部變數。
初始化上傳執行個體。請根據業務需求選擇用上傳地址和憑證方式或STS方式初始化上傳執行個體。
(推薦)上傳地址和憑證方式
展開查看代碼
//建立VODUploadClient對象
self.uploader = [VODUploadClient new];
//weakself
__weak typeof(self) weakSelf = self;
//setup callback
OnUploadFinishedListener FinishCallbackFunc = ^(UploadFileInfo* fileInfo, VodUploadResult* result){
NSLog(@"upload finished callback videoid:%@, imageurl:%@", result.videoId, result.imageUrl);
};
OnUploadFailedListener FailedCallbackFunc = ^(UploadFileInfo* fileInfo, NSString *code, NSString* message){
NSLog(@"upload failed callback code = %@, error message = %@", code, message);
};
OnUploadProgressListener ProgressCallbackFunc = ^(UploadFileInfo* fileInfo, long uploadedSize, long totalSize) {
NSLog(@"upload progress callback uploadedSize : %li, totalSize : %li", uploadedSize, totalSize);
};
OnUploadTokenExpiredListener TokenExpiredCallbackFunc = ^{
NSLog(@"upload token expired callback.");
//token到期,設定新的上傳憑證,繼續上傳
[weakSelf.uploader resumeWithAuth:`new upload auth`];
};
OnUploadRertyListener RetryCallbackFunc = ^{
NSLog(@"upload retry begin callback.");
};
OnUploadRertyResumeListener RetryResumeCallbackFunc = ^{
NSLog(@"upload retry end callback.");
};
OnUploadStartedListener UploadStartedCallbackFunc = ^(UploadFileInfo* fileInfo) {
NSLog(@"upload upload started callback.");
//設定上傳地址和上傳憑證
[weakSelf.uploader setUploadAuthAndAddress:fileInfo uploadAuth:`upload auth` uploadAddress:`upload address`];
};
VODUploadListener *listener = [[VODUploadListener alloc] init];
listener.finish = FinishCallbackFunc;
listener.failure = FailedCallbackFunc;
listener.progress = ProgressCallbackFunc;
listener.expire = TokenExpiredCallbackFunc;
listener.retry = RetryCallbackFunc;
listener.retryResume = RetryResumeCallbackFunc;
listener.started = UploadStartedCallbackFunc;
//init with upload address and upload auth
[self.uploader init:listener];
STS方式初始化上傳執行個體
說明 STS方式調用init
方法初始化,通過介面setKeyId:accessKeySecret:secretToken:expireTime:listener:
傳入臨時STS憑證。
當token到期時,觸發OnUploadTokenExpiredListener
回調,需要調用resumeWithToken: accessKeySecret: secretToken: expireTime
方法,設定新的STS繼續上傳。
展開查看代碼
//建立VODUploadClient對象
self.uploader = [VODUploadClient new];
//weakself
__weak typeof(self) weakSelf = self;
//setup callback
OnUploadFinishedListener FinishCallbackFunc = ^(UploadFileInfo* fileInfo, VodUploadResult* result){
NSLog(@"upload finished callback videoid:%@, imageurl:%@", result.videoId, result.imageUrl);
};
OnUploadFailedListener FailedCallbackFunc = ^(UploadFileInfo* fileInfo, NSString *code, NSString* message){
NSLog(@"upload failed callback code = %@, error message = %@", code, message);
};
OnUploadProgressListener ProgressCallbackFunc = ^(UploadFileInfo* fileInfo, long uploadedSize, long totalSize) {
NSLog(@"upload progress callback uploadedSize : %li, totalSize : %li", uploadedSize, totalSize);
};
OnUploadTokenExpiredListener TokenExpiredCallbackFunc = ^{
NSLog(@"upload token expired callback.");
//token到期,設定新的STS,繼續上傳
[weakSelf.uploader resumeWithToken:`STS Key Id` accessKeySecret:`STS Key Secret` secretToken:`STS Secret Token` expireTime:`STS Expire Time`];
};
OnUploadRertyListener RetryCallbackFunc = ^{
NSLog(@"upload retry begin callback.");
};
OnUploadRertyResumeListener RetryResumeCallbackFunc = ^{
NSLog(@"upload retry end callback.");
};
OnUploadStartedListener UploadStartedCallbackFunc = ^(UploadFileInfo* fileInfo) {
NSLog(@"upload upload started callback.");
};
//init
VODUploadListener *listener = [[VODUploadListener alloc] init];
listener.finish = FinishCallbackFunc;
listener.failure = FailedCallbackFunc;
listener.progress = ProgressCallbackFunc;
listener.expire = TokenExpiredCallbackFunc;
listener.retry = RetryCallbackFunc;
listener.retryResume = RetryResumeCallbackFunc;
listener.started = UploadStartedCallbackFunc;
//set STS and listener
[self.uploader setKeyId:`STS Key Id` accessKeySecret:`STS Key Secret` secretToken:STS Secret Token` expireTime:`STS Expire Time` listener:listener];
設定回調,用於接收上傳過程中關鍵節點的訊息。
設定VODUploadListener
對象,該對象是上傳狀態的回調類,需要設定下列回調方法:
展開查看代碼
/**
上傳完成回調
@param fileInfo 上傳檔案資訊
@param result 上傳結果資訊
*/
typedef void (^OnUploadFinishedListener) (UploadFileInfo* fileInfo, VodUploadResult* result);
/**
上傳失敗回調
@param fileInfo 上傳檔案資訊
@param code 錯誤碼
@param message 錯誤描述
*/
typedef void (^OnUploadFailedListener) (UploadFileInfo* fileInfo, NSString *code, NSString * message);
/**
上傳進度回調
@param fileInfo 上傳檔案資訊
@param uploadedSize 已上傳大小
@param totalSize 總大小
*/
typedef void (^OnUploadProgressListener) (UploadFileInfo* fileInfo, long uploadedSize, long totalSize);
/**
token到期回調
上傳地址和憑證方式上傳需要調用resumeWithAuth:方法繼續上傳
STS方式上傳需要調用resumeWithToken:accessKeySecret:secretToken:expireTime:方法繼續上傳
*/
typedef void (^OnUploadTokenExpiredListener) ();
/**
上傳開始重試回調
*/
typedef void (^OnUploadRertyListener) ();
/**
上傳結束重試,繼續上傳回調
*/
typedef void (^OnUploadRertyResumeListener) ();
/**
開始上傳回調
上傳地址和憑證方式上傳需要調用setUploadAuthAndAddress:uploadAuth:uploadAddress:方法設定上傳地址和憑證
@param fileInfo 上傳檔案資訊
*/
typedef void (^OnUploadStartedListener) (UploadFileInfo* fileInfo);
根據上傳的檔案類型(音視頻或圖片)構造上傳參數。
說明 音視頻和圖片的上傳參數略有差異。目前用戶端不支援上傳輔助媒資。
音視頻檔案參數
構造添加音視頻檔案到上傳列表的上傳請求函數。
展開查看代碼
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"視頻源檔案的名稱" ofType:@"視頻源檔案的格式,例如mp4"];
VodInfo *vodInfo = [[VodInfo alloc] init];
vodInfo.title = @"視頻上傳後的名稱";
vodInfo.desc =@"視頻上傳後的描述";
vodInfo.cateId = @(視頻的分類ID);
vodInfo.tags = @"視頻標籤,例如sports";
[self.uploader addFile:filePath vodInfo:vodInfo];
VodInfo說明
展開查看代碼
//標題
@property (nonatomic, copy) NSString* title;
//標籤
@property (nonatomic, copy) NSString* tags;
//描述
@property (nonatomic, copy) NSString* desc;
//分類ID
@property (nonatomic, strong) NSNumber* cateId;
//封面url(完整的URL https://)
@property (nonatomic, copy) NSString* coverUrl;
添加檔案後,SDK會將待上傳檔案封裝為UploadFileInfo
對象,具體結構如下:
展開查看代碼
//檔案本地路徑
@property (nonatomic, copy) NSString* filePath;
//endpoint
@property (nonatomic, copy) NSString* endpoint;
//bucket
@property (nonatomic, copy) NSString* bucket;
//object
@property (nonatomic, copy) NSString* object;
//VodInfo
@property (nonatomic, strong) VodInfo* vodInfo;
說明 如果需要對相簿內的視頻進行上傳,那麼通過選取器得到的選中視頻的絕對路徑,作為上傳的filepath進行上傳。
圖片檔案參數
展開查看代碼
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"圖片源檔案的名稱" ofType:@"圖片源檔案的格式,例如jpg"];
VodInfo *imageInfo = [[VodInfo alloc] init];
imageInfo.title = @"圖片上傳後的名稱";
imageInfo.desc =@"圖片上傳後的描述";
imageInfo.cateId = @(圖片的分類ID);
imageInfo.tags = @"圖片標籤,例如sports";
[self.uploader addFile:filePath vodInfo:imageInfo];
開始上傳。
調用start
開始上傳。
[self.uploader start];
該方法調用後,會觸發OnUploadStartedListener
回調。如果通過上傳地址和憑證方式上傳,需要在該回調方法中設定上傳地址和憑證。代碼如下:
[weakSelf.uploader setUploadAuthAndAddress:fileInfo uploadAuth:weakSelf.uploadAuth uploadAddress:weakSelf.uploadAddress];
檔案開始上傳後,OnUploadProgressListener
回調開始同步上傳進度。
回調參數包括已上傳檔案大小uploadedSize
和總檔案大小totalSize
。
檔案上傳成功後,OnUploadFinishedListener
回調會返回上傳檔案資訊UploadFileInfo
和上傳結果VodUploadResult
。
VodUploadResult
包含以下屬性:
@property (nonatomic, copy) NSString* videoId;
@property (nonatomic, copy) NSString* imageUrl;
說明 videoId
只在STS方式上傳視頻成功後才有傳回值,imageUrl
只在STS方式上傳圖片成功後才有傳回值。如果使用上傳地址和憑證方式上傳,videoId
和imageUrl
不會返回,相應的值在請求上傳地址和憑證時就可以擷取到。
執行結果
隊列管理
VODUploadClient
支援添加多個檔案順序上傳,並且提供了以下方法管理上傳隊列:
說明 儘管VODUploadClient
支援多檔案上傳,如果使用上傳憑證和地址方式上傳,每個檔案還是需要單獨設定。基於多檔案上傳代碼複雜度的考慮,建議只添加單檔案上傳。
從隊列中刪除上傳檔案,如果待刪除的檔案正在上傳中,則取消上傳並自動上傳下一個檔案。
- (BOOL)deleteFile:(int) index;
清空上傳隊列,如果有檔案在上傳,則取消上傳。
- (BOOL)clearFiles;
擷取上傳檔案隊列。
- (NSMutableArray<UploadFileInfo *> *)listFiles;
將檔案標記為取消,檔案仍保留在上傳列表中。如果待取消的檔案正在上傳中,則取消上傳並自動上傳下一個檔案。
- (BOOL)cancelFile:(int)index;
恢複已取消的上傳檔案,並自動開始上傳。
- (BOOL)resumeFile:(int)index;
上傳控制
停止上傳,如果有檔案正在上傳中,則取消上傳。
- (BOOL)stop;
說明 停止上傳後如需恢複上傳,請調用resumeFile:
恢複待上傳檔案,或者清空隊列後重新添加檔案上傳。
暫停上傳。
- (BOOL)pause;
恢複上傳。
- (BOOL)resume;
回調處理
上傳失敗
上傳失敗時,會觸發OnUploadFailedListener
回調。在該回調方法中,可以通過code
和message
查看具體原因,並在頁面上提示。更多錯誤碼資訊,請參見錯誤碼錶和OSS錯誤碼。
憑證到期處理
上傳憑證或STS到期,會觸發OnUploadTokenExpiredListener
回調。在該回調方法中,可以向AppServer重新請求新的上傳憑證或STS,並調用以下方法繼續上傳。
重新設定上傳憑證
- (BOOL)resumeWithAuth:(NSString *)uploadAuth;
重新設定STS
- (BOOL)resumeWithToken:(NSString *)accessKeyId
accessKeySecret:(NSString *)accessKeySecret
secretToken:(NSString *)secretToken
expireTime:(NSString *)expireTime;
逾時處理
上傳逾時,會觸發OnUploadRertyListener
回調並自動重試。在該回調方法中,可以在頁面上給予提示或者調用stop
方法停止上傳。此外,可以設定maxRetryCount
屬性,指定最大重試次數。逾時重試可以繼續上傳時,會觸發OnUploadRertyResumeListener
回調並恢複上傳。
進階設定
VODUploadClient
支援上傳轉碼、逾時重試、設定快取檔案夾位置、斷點續傳、分區上傳、設定點播服務地區等進階設定。具體樣本如下:
上傳轉碼
/**
上傳檔案到服務端是否轉碼,預設值YES。指定視頻轉碼產生的格式請參見:音視頻轉碼。
*/
@property (nonatomic, assign) BOOL transcode;
逾時重試
/**
最大逾時重試次數,預設值INT_MAX
*/
@property (nonatomic, assign) uint32_t maxRetryCount;
/**
逾時時間
*/
@property (nonatomic, assign) NSTimeInterval timeoutIntervalForRequest;
設定快取檔案夾位置
/**
快取檔案夾位置
*/
@property (nonatomic, copy) NSString * recordDirectoryPath;
斷點續傳
/**
是否記錄上傳進度(斷點續傳),預設值YES
*/
@property (nonatomic, assign) BOOL recordUploadProgress;
分區上傳
/**
分區大小,預設值1024 * 1024
*/
@property (nonatomic, assign) NSInteger uploadPartSize;
設定點播服務地區
/**
vod region,預設值"cn-shanghai"
*/
@property (nonatomic, copy) NSString *region;