阿里云视频点播文件上传-iOS

阿里云视频点播文件上传-iOS

写在前面:

阿里云-上传SDK文档
阿里云-Api常见错误码表

使用前需先开通视频点播权限,见文档,否则Api访问无效,上传不上去的。

如果只是单纯的上传文件,而不是点播文件,使用简单上传就可以了,视频点播上传是针对点播服务的。刚开始不太清楚,搞了半天视频点播上传,发现Api访问无权限,后来才看到需要开通服务。

一、上传方式

1、上传地址加凭证

2、STS方式上传

方式一 上传地址加凭证上传

这是阿里官方推荐使用的上传方式

与STS方式流程基本一致,只有4点不同的地方

1、请求AppServer

请求AppServer的时候需要让server返回uploadAddress(上传地址)和uploadAuth(上传凭证)

2、在start的回调中设置上传地址和上传凭证
	OnUploadStartedListener UploadStartedCallbackFunc = ^(UploadFileInfo* fileInfo) {
		NSLog(@"upload upload started callback.");
		// 设置上传地址 和 上传凭证
		[weakSelf.uploader setUploadAuthAndAddress:fileInfo uploadAuth:`upload auth` uploadAddress:`upload address`];
	};	
3、uploadAuth过期重新设置
	OnUploadTokenExpiredListener TokenExpiredCallbackFunc = ^{
		NSLog(@"upload token expired callback.");
		// token过期,设置新的上传凭证,继续上传
		[weakSelf.uploader resumeWithAuth:`new upload auth`];
	};
4、上传图片和上传视频

STS上传视频和地址,请求AppServer返回都是key,secreatKey,token和过期时间,就可以上传视频和图片资源。

上传地址+凭证的上传方式注意:

  • 客户端上传视频:需要请求向AppServer发送请求,AppServer通过OpenApi向阿里云点播服务发送CreateUploadVideo请求。请求成功将返回上传地址,上传凭证以及VideoId,AppServer需要将结果返回给客户端。

  • 客户端上传图片:需要请求向AppServer发送请求,AppServer通过OpenApi向阿里云点播服务发送CreateUploadImage请求。请求成功将返回上传地址,上传凭证以及ImageURL,AppServer需要将结果返回给客户端。

方式二 STS方式上传

不推荐使用,可能会被废弃

1、请求STS

向自己的AppServer请求相关的AccessKeyId、AccessKeySecret、SecurityToken等信息。

2、初始化上传对象

初始化VODUploadClient对象,并调用以下方法设置STS授权信息

- (BOOL)        init:(NSString *)accessKeyId
     accessKeySecret:(NSString *)accessKeySecret
         secretToken:(NSString *)secretToken
          expireTime:(NSString *)expireTime
            listener:(VODUploadListener *) listener

STS方式调用init: accessKeySecret: secretToken: expireTime: listener:方法初始化,初始化参数即是第一步请求获取的临时STS凭证。

想不明白起名为什么要起init…,最新版的SDK里Api有所改动,这个方法改成了setAccessKeyId…。

3、回调设置

在初始化uploader对象的时候,顺便设置事件回调。

4、添加上传文件进入上传列表,支持视频文件和图片文件的上传
- (BOOL)addFile:(NSString *)filePath
        vodInfo:(VodInfo *)vodInfo;
5、启动上传
- (BOOL)start;
6、回调处理

略…

二、注意事项

  • 1.5.3版本的readme里面,推荐使用上传凭证的方式上传

  • STS上传方式可能会被废弃

  • 使用VODUpload.framework的话需要后台开通视频点播服务权限,否则接口访问受限

三、错误和异常处理

1、Undefined symbols for architecture x86_64

未添加依赖库,看Demo里有添加libresolv.tbd,libresolv.9.tbd、SystermConfigration.framework。

2、[VODUploadClient initMultiUpload]_block_invoke

初始化问题,未调用init方法设置STS授权信息。

3、failed code = (null), error message = (null)

报错如下

2019-10-21 11:09:02.791887+0800 UploadDemo[5606:1449184] upload started . 2019-10-21 11:09:02.802116+0800 UploadDemo[5606:1449184] failed code = (null), error message = (null) 2019-10-21 11:09:02.802214+0800 UploadDemo[5606:1449184] state 5

不知道怎么处理,更新最新的SDK吧,旧的SDK是有这个问题。

4、Undefined symbols:_CMTimeGetSeconds

报错如下

Undefined symbols for architecture arm64: "_CMTimeRangeGetEnd", referenced from: +[AVCVAssetInfo AVCVVideoDuration:] in VODUpload(AVCVAssetInfo.o) +[AVCVAssetInfo AVCVAudioDuration:] in VODUpload(AVCVAssetInfo.o) "_CMTimeGetSeconds", referenced from: +[AVCVAssetInfo AVCVDuration:] in VODUpload(AVCVAssetInfo.o) +[AVCVAssetInfo AVCVVideoDuration:] in VODUpload(AVCVAssetInfo.o) +[AVCVAssetInfo AVCVAudioDuration:] in VODUpload(AVCVAssetInfo.o) "_AVMediaTypeAudio", referenced from: +[AVCVAssetInfo AVCVAudioDuration:] in VODUpload(AVCVAssetInfo.o) "_AVMediaTypeVideo", referenced from: +[AVCVAssetInfo AVCVNaturalSize:] in VODUpload(AVCVAssetInfo.o) +[AVCVAssetInfo AVCVFrameRate:] in VODUpload(AVCVAssetInfo.o) +[AVCVAssetInfo AVCVBitrate:] in VODUpload(AVCVAssetInfo.o) +[AVCVAssetInfo AVCVVideoDuration:] in VODUpload(AVCVAssetInfo.o) "_OBJC_CLASS_$_AVURLAsset", referenced from: objc-class-ref in VODUpload(VODUploadClient.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
官网上说要添加-Objc,force load,统统删掉,编译,OK了。

但是一初始化上传对象,编译,又报错了,什么情况呢?后来联系了阿里的技术服务和技术的童鞋。

原来是缺少了依赖库,也不用设置force load,-Objc什么的,需要添加的依赖库有:

libresolve.tbd
libresolve.9.tbd
SystermCongiguration.framework
MobileCoreService.framework
CoreMedia.ramework
AVFoundation.framework

这些官方文档上可是没有说的,就是对着Demo添加也添加不全的。

5、Forbidden.RAM

上传报错

failed code = Forbidden.RAM, error message = You are not authorized to operate this resource, or this API does not support RAM.

报这个错误,是没有权限使用上传Api,我是因为后台没有开通点播服务导致的。

四、实现代码

这个代码不是很合理,看看就行了。

STS上传方式源码

STS已经不被推荐使用了,这里直接跳过吧。

#import "VHVideoUploder.h"
#import <VODUpload/VODUploadClient.h>
#import "VHVideoUploadModel.h"
#import "VHWebService.h"

@interface VHVideoUploder ()

@property (nonatomic, strong) VODUploadClient *uploader;
@property (nonatomic, strong) VODUploadListener *listener;

@property (nonatomic, copy) NSString *userAccessToken;

@end

@implementation VHVideoUploder

/**
 获取SDK版本号
 */
+ (NSString *)getSDKVersion {
    return SDK_Version;
}

#pragma mark - init

- (VODUploadClient *)uploader {
    if (!_uploader) {
        _uploader = [[VODUploadClient alloc] init];
        
        __weak typeof(self)weakSelf = self;
        
        OnUploadFinishedListener finishedCallbackFunc = ^(UploadFileInfo* fileInfo, VodUploadResult* result) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"%@", [NSString stringWithFormat:@"upload success! %@", fileInfo.filePath]);
                
            });
        };
        
        OnUploadFailedListener testFailedCallbackFunc = ^(UploadFileInfo* fileInfo, NSString *code, NSString* message){
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"failed code = %@, error message = %@", code, message);
                NSLog(@"state %ld",(long)fileInfo.state);
            });
        };
        
        OnUploadProgressListener testProgressCallbackFunc = ^(UploadFileInfo* fileInfo, long uploadedSize, long totalSize) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"progress uploadedSize : %li, totalSize : %li", uploadedSize, totalSize);
                
            });
        };
        
        OnUploadTokenExpiredListener testTokenExpiredCallbackFunc = ^{
            NSLog(@"token expired.");
            // update sts token and call resumeWithToken
            
            // OSS token过期,设置新的STS,继续上传
            //[weakSelf.uploader resumeWithToken:`STS Key Id` accessKeySecret:`STS Key Secret` secretToken:`STS Secret Token` expireTime:`STS Expire Time`];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                [VHVideoUploder requestUploadAuthKeyWithToekn:self.userAccessToken success:^(id  _Nullable responseObject) {
                    
                    [weakSelf.uploader resumeWithToken:responseObject[@"stsArr"][@"AccessKeyId"] accessKeySecret:responseObject[@"stsArr"][@"AccessKeySecret"]  secretToken:responseObject[@"stsArr"][@"SecurityToken"] expireTime:responseObject[@"stsArr"][@"Expiration"] ];
                    
                } failure:^(NSError *error) {
                    
                }];
            });
        };
        
        OnUploadRertyListener testRetryCallbackFunc = ^{
            NSLog(@"manager: retry begin.");
        };
        
        OnUploadRertyResumeListener testRetryResumeCallbackFunc = ^{
            NSLog(@"manager: retry begin.");
        };
        
        OnUploadStartedListener testUploadStartedCallbackFunc = ^(UploadFileInfo* fileInfo) {
            NSLog(@"upload started .");
            
        };
        
        _listener = [[VODUploadListener alloc] init];
        _listener.finish = finishedCallbackFunc;
        _listener.failure = testFailedCallbackFunc;
        _listener.progress = testProgressCallbackFunc;
        _listener.expire = testTokenExpiredCallbackFunc;
        _listener.retry = testRetryCallbackFunc;
        _listener.retryResume = testRetryResumeCallbackFunc;
        _listener.started = testUploadStartedCallbackFunc;
    }
    return _uploader;
}


#pragma mark - public

/**
 添加文件
 
 @param videoPath 视频文件路径
 @param svideoInfo 短视频上传信息
 */
- (BOOL)addFileWithVideoPath:(NSString *)videoPath
                  svideoInfo:(VHVideoUploadModel *)svideoInfo
{
    VodInfo *info = [[VodInfo alloc] init];
    info.title = svideoInfo.name;
    info.desc = svideoInfo.desc;
    return [self.uploader addFile:videoPath vodInfo:info];
}

/**
 开始上传
 
 @param accessToken VH AccessToken
 */
- (void)startWithAccessToken:(NSString *)accessToken
{
    self.userAccessToken = accessToken;
    
    [VHVideoUploder requestUploadAuthKeyWithToekn:accessToken success:^(id  _Nullable responseObject) {

        [self.uploader setKeyId:responseObject[@"stsArr"][@"AccessKeyId"] accessKeySecret:responseObject[@"stsArr"][@"AccessKeySecret"] secretToken:responseObject[@"stsArr"][@"SecurityToken"] expireTime:responseObject[@"stsArr"][@"Expiration"] listener:self.listener];

        [self.uploader start];

    } failure:^(NSError *error) {

    }];
}


/**
 暂停上传
 */
- (void)pause
{
    [self.uploader pause];
}

/**
 恢复上传
 */
- (void)resume
{
    [self.uploader resume];
}

#pragma mark - private

+ (void)requestUploadAuthKeyWithToekn:(NSString *)toekn
                              success:(nullable void (^)(id _Nullable responseObject))success
                              failure:(nullable void (^)(NSError *error))failure
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[@"access_token"] = toekn;
    [VHWebService requestWithApi:UploadAuthKey param:dict onRequestFinished:^(id data) {
        NSLog(@"request authKey response : %@",data);
        if (success) {
            success(data);
        }
    } onRequestFailed:^(NSError *error) {
        NSLog(@"request authKey error : %@",error);
        if (failure) {
            failure(error);
        }
    }];
}

@end

这个代码测试了一下没跑通,OSS SDK报错信息如下:

failed code = Forbidden.RAM, error message = You are not authorized to operate this resource, or this API does not support RAM.

然后阿里技术的童鞋说推荐使用上传地址+凭证的方式上传。查了Api错误表,搜索‘API does not support RAM’关键字,会有解释,这个Api不能用了:

’未授权,或此 API 不支持访问控制。‘

安卓端也是报这个问题,‘临时用户访问无权限,该临时用户角色扮演指定授权策略,该授权策略无权限’。

上传地址+凭证方式源码

VHVideoUploader.m

//
//  VHVideoUploader.m
//  VHUploadFramework
//
//  Created by vhall on 2019/10/15.
//  Copyright © 2019 vhall. All rights reserved.
//

#import "VHVideoUploader.h"
#import <VODUpload/VODUploadClient.h>
#import "VHVideoUploadModel.h"
#import "VHWebService.h"

@interface VHVideoUploader ()

@property (nonatomic, strong) VODUploadClient *uploader;
@property (nonatomic, strong) VODUploadListener *listener;

@property (nonatomic, copy) NSString *userAccessToken;

@property (nonatomic, copy) NSString *uploadAuth;//上传凭证
@property (nonatomic, copy) NSString *uploadAddress;//上传地址

@end

@implementation VHVideoUploader

/**
 获取SDK版本号
 */
+ (NSString *)getSDKVersion {
    return SDK_Version;
}

#pragma mark - init

- (VODUploadClient *)uploader {
    if (!_uploader) {
        _uploader = [[VODUploadClient alloc] init];
        
        __weak typeof(self)weakSelf = self;
        
        OnUploadFinishedListener finishedCallbackFunc = ^(UploadFileInfo* fileInfo, VodUploadResult* result) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"%@", [NSString stringWithFormat:@"upload success! %@", fileInfo.filePath]);
                [weakSelf finished:fileInfo result:result];
            });
        };
        
        OnUploadFailedListener testFailedCallbackFunc = ^(UploadFileInfo* fileInfo, NSString *code, NSString* message){
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"failed code = %@, error message = %@", code, message);
                NSLog(@"state %ld",(long)fileInfo.state);
                [weakSelf failed:fileInfo code:code message:message];
            });
        };
        
        OnUploadProgressListener testProgressCallbackFunc = ^(UploadFileInfo* fileInfo, long uploadedSize, long totalSize) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"progress uploadedSize : %li, totalSize : %li", uploadedSize, totalSize);
                [weakSelf progress:fileInfo uploadSize:uploadedSize totalSize:totalSize];
            });
        };
        
        OnUploadTokenExpiredListener testTokenExpiredCallbackFunc = ^{
            NSLog(@"token expired.");
            
            // upload auth过期,设置新的upload auth,继续上传
            // [weakSelf.uploader resumeWithAuth:`new upload auth`];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                [VHVideoUploader requestUploadAuthKeyWithToekn:self.userAccessToken success:^(id  _Nullable responseObject) {
                    
//                    weakSelf.uploadAuth =
//                    weakSelf.uploadAddress =
                    
                    [weakSelf.uploader resumeWithAuth:weakSelf.uploadAuth];
                    
                } failure:^(NSError *error) {
                    
                }];
            });
        };
        
        OnUploadRertyListener testRetryCallbackFunc = ^{
            NSLog(@"manager: retry begin.");
        };
        
        OnUploadRertyResumeListener testRetryResumeCallbackFunc = ^{
            NSLog(@"manager: retry begin.");
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf onResume];
            });
        };
        
        OnUploadStartedListener testUploadStartedCallbackFunc = ^(UploadFileInfo* fileInfo) {
            NSLog(@"upload started .");
            
            // 设置上传地址 和 上传凭证
            //[weakSelf.uploader setUploadAuthAndAddress:fileInfo uploadAuth:`upload auth` uploadAddress:`upload address`];

            [weakSelf.uploader setUploadAuthAndAddress:fileInfo uploadAuth:weakSelf.uploadAuth uploadAddress:weakSelf.uploadAddress];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf start:fileInfo];
            });
        };
        
        
        _listener = [[VODUploadListener alloc] init];
        _listener.finish = finishedCallbackFunc;
        _listener.failure = testFailedCallbackFunc;
        _listener.progress = testProgressCallbackFunc;
        _listener.expire = testTokenExpiredCallbackFunc;
        _listener.retry = testRetryCallbackFunc;
        _listener.retryResume = testRetryResumeCallbackFunc;
        _listener.started = testUploadStartedCallbackFunc;
    }
    return _uploader;
}


#pragma mark - public

/**
 添加文件
 
 @param videoPath 视频文件路径
 @param model 短视频上传信息
 */
- (BOOL)addFileWithVideoPath:(NSString *)videoPath
                  svideoInfo:(VHVideoUploadModel *)model
{
    return [self.uploader addFile:videoPath vodInfo:[self unPackVodInfo:model]];
}

/**
 开始上传
 
 @param accessToken VH AccessToken
 */
- (void)startWithAccessToken:(NSString *)accessToken
{
    self.userAccessToken = accessToken;
    
    [VHVideoUploader requestUploadAuthKeyWithToekn:accessToken success:^(id  _Nullable responseObject) {

//        self.uploadAuth =
//        self.uploadAddress =

        [self.uploader start];

    } failure:^(NSError *error) {

    }];
}


/**
 暂停上传
 */
- (void)pause
{
    [self.uploader pause];
}

/**
 恢复上传
 */
- (void)resume
{
    [self.uploader resume];
}

#pragma mark - private

+ (void)requestUploadAuthKeyWithToekn:(NSString *)toekn
                              success:(nullable void (^)(id _Nullable responseObject))success
                              failure:(nullable void (^)(NSError *error))failure
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[@"access_token"] = toekn;
    [VHWebService requestWithApi:UploadAuthKey param:dict onRequestFinished:^(id data) {
        NSLog(@"request authKey response : %@",data);
        if (success) {
            success(data);
        }
    } onRequestFailed:^(NSError *error) {
        NSLog(@"request authKey error : %@",error);
        if (failure) {
            failure(error);
        }
    }];
}

- (VHUploadFileInfo *)packUploadInfo:(UploadFileInfo *)fileInfo {
    VHUploadFileInfo *info = [[VHUploadFileInfo alloc] init];
    info.filePath = fileInfo.filePath;
    info.endpoint = fileInfo.endpoint;
    info.bucket = fileInfo.bucket;
    info.object = fileInfo.object;
    info.state = (VHVODUploadFileStatus)fileInfo.state;
    info.vodInfo = [self packUploadModel:fileInfo.vodInfo];
    return info;
}
- (VHVideoUploadModel *)packUploadModel:(VodInfo *)vodInfo {
    VHVideoUploadModel *info = [[VHVideoUploadModel alloc] init];
    info.title = vodInfo.title;
    info.tags = vodInfo.tags;
    info.desc = vodInfo.desc;
    info.cateId = vodInfo.cateId;
    info.coverUrl = vodInfo.coverUrl;
    info.userData = vodInfo.userData;
    return info;
}

- (VodInfo *)unPackVodInfo:(VHVideoUploadModel *)model {
    VodInfo *info = [[VodInfo alloc] init];
    info.title = model.title;
    info.tags = model.tags;
    info.desc = model.desc;
    info.cateId = model.cateId;
    info.coverUrl = model.coverUrl;
    info.userData = model.userData;
    return info;
}

- (VHVodUploadResult *)packUploadResult:(VodUploadResult *)result
{
    VHVodUploadResult *uploadResult = [[VHVodUploadResult alloc] init];
    uploadResult.videoId = result.videoId;
    uploadResult.imageUrl = result.imageUrl;
    uploadResult.bucket = result.bucket;
    uploadResult.endpoint = result.endpoint;
    return uploadResult;
}


#pragma mark - 回调
- (void)start:(UploadFileInfo *)fileInfo {
    if ([self.delegate respondsToSelector:@selector(uploader:didStarted:)]) {
        [self.delegate uploader:self didStarted:[self packUploadInfo:fileInfo]];
    }
}
- (void)failed:(UploadFileInfo *)fileInfo code:(NSString *)code message:(NSString *)message {
    if ([self.delegate respondsToSelector:@selector(failed:code:message:)]) {
        [self.delegate uploader:self didFailed:[self packUploadInfo:fileInfo] code:code message:message];
    }
}
- (void)finished:(UploadFileInfo *)fileInfo result:(VodUploadResult *)reult {
    if ([self.delegate respondsToSelector:@selector(uploader:didFinished:result:)]) {
        [self.delegate uploader:self didFinished:[self packUploadInfo:fileInfo] result:[self packUploadResult:reult]];
    }
}
- (void)onResume {
    if ([self.delegate respondsToSelector:@selector(uploaderDidResume:)]) {
        [self.delegate uploaderDidResume:self];
    }
}
- (void)progress:(UploadFileInfo *)fileInfo uploadSize:(long)uploadedSize totalSize:(long)totalSize  {
    
    
    if ([self.delegate respondsToSelector:@selector(uploader:progressFile:uploadSize:totalSize:)]) {
        [self.delegate uploader:self progressFile:[self packUploadInfo:fileInfo] uploadSize:uploadedSize totalSize:totalSize];
    }
}

@end

VHVideoUploadModel.h

//
//  VHVideoUploadModel.h
//  VHUploadFramework
//
//  Created by vhall on 2019/10/15.
//  Copyright © 2019 vhall. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, VHVODUploadFileStatus) {
    VHVODUploadFileStatusReady,
    VHVODUploadFileStatusUploading,
    VHVODUploadFileStatusCanceled,
    VHVODUploadFileStatusPaused,
    VHVODUploadFileStatusSuccess,
    VHVODUploadFileStatusFailure
};



@interface VHVideoUploadModel : NSObject

/**
 标题
 */
@property (nonatomic, copy) NSString* title;

/**
 标签
 */
@property (nonatomic, copy) NSString* tags;

/**
 描述
 */
@property (nonatomic, copy) NSString* desc;

/**
 分类id
 */
@property (nonatomic, strong) NSNumber* cateId;

/**
 封面url
 */
@property (nonatomic, copy) NSString* coverUrl;

/**
 设置自定义数据
 */
@property (nonatomic, copy) NSString* userData;

@end


@interface VHUploadFileInfo : NSObject

@property (nonatomic, copy) NSString* filePath;
@property (nonatomic, copy) NSString* endpoint;
@property (nonatomic, copy) NSString* bucket;
@property (nonatomic, copy) NSString* object;
@property (nonatomic, strong) VHVideoUploadModel* vodInfo;
@property VHVODUploadFileStatus state;

@end


@interface VHVodUploadResult: NSObject
@property (nonatomic, copy) NSString* videoId;
@property (nonatomic, copy) NSString* imageUrl;
@property (nonatomic, copy) NSString* bucket;
@property (nonatomic, copy) NSString* endpoint;
@end

NS_ASSUME_NONNULL_END

这种每次回调的时候都需要将数据包装,在progress回调方法中一直创建对象的方法不是很妥当,还需要优化。

以下Java示例代码演示了如何在服务端上传媒资文件至视频点播,媒资类型支持音频、视频和图片。 * <p> * 一、音视频上传目前支持4种方式上传: * * 1.上传本地文件,使用分片上传,并支持断点续传,参见testUploadVideo函数。 * 1.1 当断点续传关闭时,最大支持上传任务执行时间为3000秒,具体可上传文件大小与您的网络带宽及磁盘读写能力有关。 * 1.2 当断点续传开启时,最大支持48.8TB的单个文件,注意,断点续传开启后,上传任务执行过程中,同时会将当前上传位置写入本地磁盘文件,影响您上传文件的速度,请您根据文件大小选择是否开启 * * 2.上传网络流,可指定文件URL进行上传,支持断点续传,最大支持48.8TB的单个文件。 * 该上传方式需要先将网络文件下载到本地磁盘,再进行上传,所以要保证本地磁盘有充足的空间。参见testUploadURLStream函数。 * * 3.上传文件流,可指定本地文件进行上传,不支持断点续传,最大支持5GB的单个文件。参见testUploadFileStream函数。 * * 4.流式上传,可指定输入流进行上传,支持文件流和网络流等,不支持断点续传,最大支持5GB的单个文件。参见testUploadStream函数。 * <p> * * 二、图片上传目前支持2种方式上传: * 1.上传本地文件,不支持断点续传,最大支持5GB的单个文件,参见testUploadImageLocalFile函数 * 2.上传文件流和网络流,InputStream参数必选,不支持断点续传,最大支持5GB的单个文件。参见testUploadImageStream函数。 * 注:图片上传完成后,会返回图片ID和图片地址,也可通过GetImageInfo查询图片信息,参见接口文档 https://help.aliyun.com/document_detail/89742.html * <p> * * 三、m3u8文件上传目前支持2种方式: * 1.上传本地m3u8音视频文件(包括所有分片文件)到点播,需指定本地m3u8索引文件地址和所有分片地址。 * 2.上传网络m3u8音视频文件(包括所有分片文件)到点播,需指定m3u8索引文件和分片文件的URL地址。 * * 注: * 1) 上传网络m3u8音视频文件时需要保证地址可访问,如果有权限限制,请设置带签名信息的地址,且保证足够长的有效期,防止地址无法访问导致上传失败 * 2) m3u8文件上传暂不支持进度回调 * <p> * * 四、上传进度回调通知: * 1.默认上传进度回调函数:视频点播上传SDK内部默认开启上传进度回调函数,输出不同事件通知的日志,您可以设置关闭该上传进度通知及日志输出; * 2.自定义上传进度回调函数:您可根据自已的业务场景重新定义不同事件处理的方式,只需要修改上传回调示例函数即可。 * <p> * * 五、辅助媒资上传目前支持2种方式: * 1.上传本地文件,不支持断点续传,最大支持5GB的单个文件,参见testUploadAttachedMediaLocalFile函数 * 2.上传文件流和网络流,InputStream参数必选,不支持断点续传,最大支持5GB的单个文件。参见testUploadAttachedMediaStream函数。 * <p> * * 六、支持STS方式上传: * 1.您需要实现VoDRefreshSTSTokenListener接口的onRefreshSTSToken方法,用于生成STS信息, * 当文件上传时间超过STS过期时间时,SDK内部会定期调用此方法刷新您的STS信息进行后续文件的上传。 * <p> * * 七、可指定上传脚本部署的ECS区域(设置Request的EcsRegionId参数,取值参考存储区域标识:https://help.aliyun.com/document_detail/98194.html), * 如果与点播存储(OSS)区域相同,则自动使用内网上传文件至存储,上传更快且更省公网流量 * 由于点播API只提供外网域名访问,因此部署上传脚本的ECS服务器必须具有访问外网的权限。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morris_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值