Commit 75b1049a59cddd186c0f67ef87122daa9e58635e

Authored by 王军波
2 parents 569068be afd7749b

Merge branch 'master' of bj.gitlab.cnlive.com:ios-team/CNLiveUploadSDKDemo

# Conflicts:
#	CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo.xcodeproj/project.pbxproj
CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo.xcodeproj/project.pbxproj
... ... @@ -16,9 +16,9 @@
16 16 81B9CBA11F54204F009594FB /* CNLiveUploadController.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B9CBA01F54204F009594FB /* CNLiveUploadController.m */; };
17 17 81B9CBA81F54207B009594FB /* KS3YunSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B9CBA31F54205E009594FB /* KS3YunSDK.framework */; };
18 18 81B9CBA91F54207B009594FB /* KS3YunSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 81B9CBA31F54205E009594FB /* KS3YunSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
19   - 81B9CBAE1F5421C6009594FB /* 7.6M.mov in Resources */ = {isa = PBXBuildFile; fileRef = 81B9CBAD1F5421C6009594FB /* 7.6M.mov */; };
20   - D2FEF9D71FE763AC00B217BD /* CNLiveUploadYunSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2FEF9D51FE763A900B217BD /* CNLiveUploadYunSDK.framework */; };
21   - D2FEF9D81FE763AC00B217BD /* CNLiveUploadYunSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D2FEF9D51FE763A900B217BD /* CNLiveUploadYunSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
  19 + D21D75D51FE0C9C700658839 /* cnlive.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = D21D75D41FE0C9C600658839 /* cnlive.mp4 */; };
  20 + D2DD1B311FDFDA6C001DFDD1 /* CNLiveUploadYunSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2DD1B301FDFDA6C001DFDD1 /* CNLiveUploadYunSDK.framework */; };
  21 + D2DD1B331FDFDA6F001DFDD1 /* CNLiveUploadYunSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D2DD1B301FDFDA6C001DFDD1 /* CNLiveUploadYunSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
22 22 /* End PBXBuildFile section */
23 23  
24 24 /* Begin PBXCopyFilesBuildPhase section */
... ... @@ -28,7 +28,7 @@
28 28 dstPath = "";
29 29 dstSubfolderSpec = 10;
30 30 files = (
31   - D2FEF9D81FE763AC00B217BD /* CNLiveUploadYunSDK.framework in Embed Frameworks */,
  31 + D2DD1B331FDFDA6F001DFDD1 /* CNLiveUploadYunSDK.framework in Embed Frameworks */,
32 32 81B9CBA91F54207B009594FB /* KS3YunSDK.framework in Embed Frameworks */,
33 33 );
34 34 name = "Embed Frameworks";
... ... @@ -50,8 +50,8 @@
50 50 81B9CB9F1F54204F009594FB /* CNLiveUploadController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveUploadController.h; sourceTree = "<group>"; };
51 51 81B9CBA01F54204F009594FB /* CNLiveUploadController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveUploadController.m; sourceTree = "<group>"; };
52 52 81B9CBA31F54205E009594FB /* KS3YunSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = KS3YunSDK.framework; sourceTree = "<group>"; };
53   - 81B9CBAD1F5421C6009594FB /* 7.6M.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = 7.6M.mov; sourceTree = "<group>"; };
54   - D2FEF9D51FE763A900B217BD /* CNLiveUploadYunSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CNLiveUploadYunSDK.framework; sourceTree = "<group>"; };
  53 + D21D75D41FE0C9C600658839 /* cnlive.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = cnlive.mp4; sourceTree = "<group>"; };
  54 + D2DD1B301FDFDA6C001DFDD1 /* CNLiveUploadYunSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CNLiveUploadYunSDK.framework; sourceTree = "<group>"; };
55 55 /* End PBXFileReference section */
56 56  
57 57 /* Begin PBXFrameworksBuildPhase section */
... ... @@ -59,7 +59,7 @@
59 59 isa = PBXFrameworksBuildPhase;
60 60 buildActionMask = 2147483647;
61 61 files = (
62   - D2FEF9D71FE763AC00B217BD /* CNLiveUploadYunSDK.framework in Frameworks */,
  62 + D2DD1B311FDFDA6C001DFDD1 /* CNLiveUploadYunSDK.framework in Frameworks */,
63 63 81B9CBA81F54207B009594FB /* KS3YunSDK.framework in Frameworks */,
64 64 );
65 65 runOnlyForDeploymentPostprocessing = 0;
... ... @@ -70,7 +70,7 @@
70 70 81B9CB7C1F542006009594FB = {
71 71 isa = PBXGroup;
72 72 children = (
73   - D2FEF9D51FE763A900B217BD /* CNLiveUploadYunSDK.framework */,
  73 + D2DD1B301FDFDA6C001DFDD1 /* CNLiveUploadYunSDK.framework */,
74 74 81B9CBA31F54205E009594FB /* KS3YunSDK.framework */,
75 75 81B9CB871F542006009594FB /* CNLiveUploadYunSDKDemo */,
76 76 81B9CB861F542006009594FB /* Products */,
... ... @@ -94,7 +94,7 @@
94 94 81B9CB8F1F542006009594FB /* ViewController.m */,
95 95 81B9CB9F1F54204F009594FB /* CNLiveUploadController.h */,
96 96 81B9CBA01F54204F009594FB /* CNLiveUploadController.m */,
97   - 81B9CBAD1F5421C6009594FB /* 7.6M.mov */,
  97 + D21D75D41FE0C9C600658839 /* cnlive.mp4 */,
98 98 81B9CB911F542006009594FB /* Main.storyboard */,
99 99 81B9CB941F542006009594FB /* Assets.xcassets */,
100 100 81B9CB961F542006009594FB /* LaunchScreen.storyboard */,
... ... @@ -139,7 +139,7 @@
139 139 81B9CB7D1F542006009594FB /* Project object */ = {
140 140 isa = PBXProject;
141 141 attributes = {
142   - LastUpgradeCheck = 0830;
  142 + LastUpgradeCheck = 0920;
143 143 ORGANIZATIONNAME = zhulin;
144 144 TargetAttributes = {
145 145 81B9CB841F542006009594FB = {
... ... @@ -172,7 +172,7 @@
172 172 isa = PBXResourcesBuildPhase;
173 173 buildActionMask = 2147483647;
174 174 files = (
175   - 81B9CBAE1F5421C6009594FB /* 7.6M.mov in Resources */,
  175 + D21D75D51FE0C9C700658839 /* cnlive.mp4 in Resources */,
176 176 81B9CB981F542006009594FB /* LaunchScreen.storyboard in Resources */,
177 177 81B9CB951F542006009594FB /* Assets.xcassets in Resources */,
178 178 81B9CB931F542006009594FB /* Main.storyboard in Resources */,
... ... @@ -225,7 +225,9 @@
225 225 CLANG_CXX_LIBRARY = "libc++";
226 226 CLANG_ENABLE_MODULES = YES;
227 227 CLANG_ENABLE_OBJC_ARC = YES;
  228 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
228 229 CLANG_WARN_BOOL_CONVERSION = YES;
  230 + CLANG_WARN_COMMA = YES;
229 231 CLANG_WARN_CONSTANT_CONVERSION = YES;
230 232 CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
231 233 CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
... ... @@ -233,7 +235,11 @@
233 235 CLANG_WARN_ENUM_CONVERSION = YES;
234 236 CLANG_WARN_INFINITE_RECURSION = YES;
235 237 CLANG_WARN_INT_CONVERSION = YES;
  238 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  239 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
236 240 CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  241 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  242 + CLANG_WARN_STRICT_PROTOTYPES = YES;
237 243 CLANG_WARN_SUSPICIOUS_MOVE = YES;
238 244 CLANG_WARN_UNREACHABLE_CODE = YES;
239 245 CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
... ... @@ -274,7 +280,9 @@
274 280 CLANG_CXX_LIBRARY = "libc++";
275 281 CLANG_ENABLE_MODULES = YES;
276 282 CLANG_ENABLE_OBJC_ARC = YES;
  283 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
277 284 CLANG_WARN_BOOL_CONVERSION = YES;
  285 + CLANG_WARN_COMMA = YES;
278 286 CLANG_WARN_CONSTANT_CONVERSION = YES;
279 287 CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
280 288 CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
... ... @@ -282,7 +290,11 @@
282 290 CLANG_WARN_ENUM_CONVERSION = YES;
283 291 CLANG_WARN_INFINITE_RECURSION = YES;
284 292 CLANG_WARN_INT_CONVERSION = YES;
  293 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  294 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
285 295 CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  296 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  297 + CLANG_WARN_STRICT_PROTOTYPES = YES;
286 298 CLANG_WARN_SUSPICIOUS_MOVE = YES;
287 299 CLANG_WARN_UNREACHABLE_CODE = YES;
288 300 CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
... ... @@ -319,7 +331,7 @@
319 331 INFOPLIST_FILE = CNLiveUploadYunSDKDemo/Info.plist;
320 332 IPHONEOS_DEPLOYMENT_TARGET = 8.0;
321 333 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
322   - PRODUCT_BUNDLE_IDENTIFIER = com.rd.XpkUISDKDemo;
  334 + PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.CNLiveUploadSDKDemo;
323 335 PRODUCT_NAME = "$(TARGET_NAME)";
324 336 };
325 337 name = Debug;
... ... @@ -336,7 +348,7 @@
336 348 INFOPLIST_FILE = CNLiveUploadYunSDKDemo/Info.plist;
337 349 IPHONEOS_DEPLOYMENT_TARGET = 8.0;
338 350 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
339   - PRODUCT_BUNDLE_IDENTIFIER = com.rd.XpkUISDKDemo;
  351 + PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.CNLiveUploadSDKDemo;
340 352 PRODUCT_NAME = "$(TARGET_NAME)";
341 353 };
342 354 name = Release;
... ...
CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo/7.6M.mov deleted 100755 → 0
No preview for this file type
CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo/AppDelegate.h
... ... @@ -8,6 +8,7 @@
8 8  
9 9 #import <UIKit/UIKit.h>
10 10  
  11 +//在视讯云开放平台 open.cnlive.com 注册应用,配置bundleID以及权限得到AppId和AppKey
11 12 #define AppId @"60_jaxisljz90"
12 13 #define AppKey @"1ee33b54e18a66b94eca7f8149408565b02f749d314926"
13 14  
... ...
CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo/AppDelegate.m
... ... @@ -25,8 +25,10 @@
25 25 self.window.rootViewController = nav;
26 26 [self.window makeKeyAndVisible];
27 27  
  28 + //设置地区
28 29 [[CNLiveClient initialize] setBucketDomainWithRegion:CNLiveBucketBeijing];
29   - [CNLiveUpload setAppId:AppId appKey:AppKey isTestEnvironment:YES];
  30 + //初始化云上传SDK
  31 + [CNLiveUpload setAppId:AppId appKey:AppKey isTestEnvironment:NO];
30 32  
31 33 return YES;
32 34 }
... ...
CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo/CNLiveUploadController.m
... ... @@ -9,6 +9,7 @@
9 9 #import "CNLiveUploadController.h"
10 10 #import <AssetsLibrary/AssetsLibrary.h>
11 11 #import <CNLiveUploadYunSDK/CNLiveUploadYunSDK.h>
  12 +#import <MobileCoreServices/MobileCoreServices.h>
12 13  
13 14 #define mScreenWidth ([UIScreen mainScreen].bounds.size.width)
14 15 #define mScreenHeight ([UIScreen mainScreen].bounds.size.height)
... ... @@ -19,21 +20,23 @@
19 20 #define keyUploadPartNum @"partNum" //需要app本地存储已经传成功的块号,demo为了演示,用NSUserDefaults存储,app可用数据库等
20 21 #define keyUploadId @"uploadId" //需要app本地存储已经初始化成功的uploadId,用于断点续传,demo为了演示,用NSUserDefaults存储,app可用数据库等
21 22  
22   -@interface CNLiveUploadController ()<UITableViewDelegate,UITableViewDataSource,KingSoftServiceRequestDelegate>
  23 +@interface CNLiveUploadController ()<UITableViewDelegate,UITableViewDataSource,KingSoftServiceRequestDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>
23 24 {
24   - NSString *_bucketName;//SP对应的bucketName
  25 + NSURL *_imageAssetUrl;//相册文件URL
  26 + CNLiveUploadType _uploadType;//选择文件方式type
25 27 NSString *_bucketKey;//SP上传时用到的bucket里文件的路径(包含扩展名)
26 28 }
27   -@property (nonatomic ,strong) UITableView * tableView;
  29 +@property (nonatomic ,strong) UITableView * tableView;//列表
  30 +@property (nonatomic ,strong) UIButton * styleBtn;//上传方式按钮
28 31  
29   -@property (assign, nonatomic) long long fileSize;
30   -@property (assign, nonatomic) NSInteger partSize;
31   -@property (assign, nonatomic) long long partLength;
32   -@property (nonatomic) NSInteger uploadNum;
33   -@property (nonatomic) NSInteger totalNum;
34   -@property (strong, nonatomic) NSFileHandle *fileHandle;
35   -@property (nonatomic, strong) NSArray *arrItems;
36   -@property (strong, nonatomic) CNLiveMultipartUpload *muilt;
  32 +@property (assign, nonatomic) long long fileSize;//文件大小
  33 +@property (assign, nonatomic) NSInteger partSize;//单块大小
  34 +@property (assign, nonatomic) long long partLength;//单块长度
  35 +@property (nonatomic) NSInteger uploadNum;//当前上传块
  36 +@property (nonatomic) NSInteger totalNum;//上传总块数
  37 +@property (strong, nonatomic) NSFileHandle *fileHandle;//文件管理
  38 +@property (nonatomic, strong) NSArray *arrItems;//数据源
  39 +@property (strong, nonatomic) CNLiveMultipartUpload *muilt;//分块上传对象
37 40 @end
38 41  
39 42 @implementation CNLiveUploadController
... ... @@ -43,76 +46,49 @@
43 46 // Do any additional setup after loading the view.
44 47 self.view.backgroundColor = [UIColor whiteColor];
45 48 self.navigationItem.title = @"上传";
46   - _arrItems = [NSArray arrayWithObjects:@"Multipart Upload", @"Abort Upload", @"Put Object", nil];
  49 + _arrItems = [NSArray arrayWithObjects:@"Multipart Upload", @"Abort Multipart Upload", @"Put Single Object", nil];
47 50  
48   - self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
  51 + self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, CGRectGetMinY(self.view.frame), mScreenWidth, mScreenHeight-100)];
49 52 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CNLiveUpload"];
50 53 [self.view addSubview:self.tableView];
51 54 self.tableView.delegate = self;
52 55 self.tableView.dataSource = self;
53 56  
54   - _bucketName = [CNLiveUpload getSPBucketName];
55   - NSLog(@"bucketName:%@",_bucketName);
  57 + [self.view addSubview:self.styleBtn];
56 58 [self getBucketKeyFromServer];
57 59 }
58 60  
59   -- (void)getBucketKeyFromServer
  61 +/**
  62 + 从服务器获取BucketKey,BucketKey为文件路径
  63 + */
  64 +- (NSString *)getBucketKeyFromServer
60 65 {
61   -#warning 此处建议从server获取 上传文件对应的bucketKey(文件路径包含扩展名)
  66 +#warning 此处建议从server获取,为每一个上传的文件分配唯一的bucketKey,上传文件对应的bucketKey(文件路径包含扩展名). 例:完整bucketKey为@"cnlive-test/cnlive.mp4",可由服务器返回@"cnlive-test/cnlive",扩展名@".mp4"由开发者拼接,组成完整的bucketKey
62 67 #warning Demo为了演示 bucketKey用固定值
63   - _bucketKey = @"cnlive12/test123-7.6M.mov";
  68 + _bucketKey = @"cnlive-uploadtest/cnlive.mp4";//本地工程文件
  69 + return _bucketKey;
64 70 }
65 71  
66   -#pragma mark 相册方法
67   -/*
68   - 这里,枚举模拟器相册所有的视频,模拟器只有一个只能获得开头传入的7.6M视频,
69   - 具体工程使用时根据具体逻辑,获取到Alasset即可
70   - KS3Client 方法:
71   - - (NSData *)getUploadPartDataWithPartNum:(NSInteger)partNum
72   - partLength:(NSInteger)partlength
73   - alassetURL:(NSURL *)alassetURL;
74   -
75   - - (NSData *)getUploadPartDataWithPartNum:(NSInteger)partNum
76   - partLength:(NSInteger)partlength
77   - Alasset:(ALAsset *)assets;
78   -
79   - - (ALAsset *)getAlassetFromAlassetURL:(NSURL *)alassetURL;
80   -
81   - */
82   -- (ALAsset *)getAlasset
  72 +- (NSString *)bucketKey
83 73 {
84   - ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];
85   - __block ALAsset *assets ;
86   - dispatch_semaphore_t sem= dispatch_semaphore_create(0);
87   - dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_SERIAL);
88   - dispatch_async(concurrentQueue, ^{
89   - [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
90   - if (group) {
91   - [group setAssetsFilter:[ALAssetsFilter allVideos]];
92   - [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
93   - if (result) {
94   - assets = result;
95   - NSLog(@"url = %@",assets.defaultRepresentation.url);
96   - dispatch_semaphore_signal(sem);
97   - return ;
98   - }
99   - }];
100   - dispatch_semaphore_signal(sem);
101   - }else
102   - {
103   - // NSLog(@"group为空,枚举失败");
104   - }
105   - dispatch_semaphore_signal(sem);
106   - } failureBlock:^(NSError *error) {
107   -
108   - NSLog(@"请到设置->隐私->照片中开启,访问照片库的权限");
109   - dispatch_semaphore_signal(sem);
110   - }];
111   - });
112   -
113   - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
114   -
115   - return assets;
  74 + switch (_uploadType) {
  75 + case kCNLiveUploadNormal:
  76 + {//本地文件
  77 + _bucketKey = [self getBucketKeyFromServer];
  78 + }
  79 + break;
  80 + case kCNLiveUploadAlasset:
  81 + {//相册选取的文件,重新拼接扩展名
  82 + NSString *bucketKeyUnExt = [[self getBucketKeyFromServer] substringToIndex:_bucketKey.length - 4];
  83 + NSArray *arr = [_imageAssetUrl.absoluteString componentsSeparatedByString:@"ext="];
  84 + NSString *ext = arr[1];
  85 + _bucketKey = [NSString stringWithFormat:@"%@.%@",bucketKeyUnExt,ext];
  86 + }
  87 + break;
  88 + default:
  89 + break;
  90 + }
  91 + return _bucketKey;
116 92 }
117 93  
118 94 #pragma mark 上传方法
... ... @@ -135,100 +111,107 @@
135 111 */
136 112 - (void)beginMultipartUpload
137 113 {
138   - NSString *strKey = _bucketKey;
139   - _partSize = 5; // 文件大于5M为最小5M一块
140   -
141   - CNLiveAccessControlList *acl = [[CNLiveAccessControlList alloc] init];
142   - [acl setContronAccess:CNLiveYun_Permission_Public_Read];
143   -
144   - CNLiveInitiateMultipartUploadRequest *initMultipartUploadReq = [[CNLiveInitiateMultipartUploadRequest alloc] initWithKey:strKey inBucket:_bucketName acl:acl grantAcl:nil];
145   - [initMultipartUploadReq setCompleteRequest];
146   -
147   - NSArray *array = [initMultipartUploadReq.CNYHeader componentsSeparatedByString:@"\n"];
148   - NSString *headers = [array firstObject];
149   -
150   - [CNLiveUpload getTokenWithMd5:initMultipartUploadReq.contentMd5 verb:initMultipartUploadReq.httpMethod type:initMultipartUploadReq.contentType res:initMultipartUploadReq.CNYResource headers:headers date:initMultipartUploadReq.strDate success:^(NSString *token ,NSString *cnliveDate) {
151   - [initMultipartUploadReq setStrCNLiveToken:token];
152   - [initMultipartUploadReq setStrDate:cnliveDate];
153   - _muilt = [[CNLiveClient initialize] initiateMultipartUploadWithRequest:initMultipartUploadReq];
  114 + [CNLiveUpload initCNLiveUploadWithSuccess:^{
154 115  
155   - if (_muilt == nil) {
156   - NSLog(@"####Init upload failed, please check access key, secret key and bucket name!####");
157   - return ;
158   - }
  116 + NSString *strKey = [self bucketKey];
  117 + _partSize = 5; // 文件大于5M为最小5M一块
159 118  
160   - //选择相册还是普通方式
161   - _muilt.uploadType = kCNLiveUploadNormal;
  119 + CNLiveAccessControlList *acl = [[CNLiveAccessControlList alloc] init];
  120 + [acl setContronAccess:CNLiveYun_Permission_Public_Read];
162 121  
163   - //根据文件路径不一样,有如下两种上传
164   - if (_muilt.uploadType == kCNLiveUploadNormal) { //如果是沙盒或者工程里的文件
165   - //工程里,沙盒里,是沙盒路径
166   - NSString *strFilePath = [[NSBundle mainBundle] pathForResource:@"7.6M" ofType:@"mov"];
167   - _fileHandle = [NSFileHandle fileHandleForReadingAtPath:strFilePath];
168   - _fileSize = [_fileHandle availableData].length;
169   - if (_fileSize <= 0) {
170   - NSLog(@"####This file is not exist!####");
171   - return ;
172   - }
173   - if (!(_partSize > 0 || _partSize != 0)) {
174   - _partLength = _fileSize;
175   - }else{
176   - _partLength = _partSize * 1024.0 * 1024.0;
177   - }
178   - _totalNum = (ceilf((float)_fileSize / (float)_partLength));
179   - [_fileHandle seekToFileOffset:0];
180   - }else
181   - {
182   - //如果是相册里的,从这传
183   - ALAssetRepresentation *assetD = [self getAlasset].defaultRepresentation;
184   - _fileSize = assetD.size;
185   - if (_fileSize <= 0) {
186   - NSLog(@"####This file is not exist!####");
  122 + CNLiveInitiateMultipartUploadRequest *initMultipartUploadReq = [[CNLiveInitiateMultipartUploadRequest alloc] initWithKey:strKey acl:acl grantAcl:nil];
  123 + [initMultipartUploadReq setCompleteRequest];
  124 +
  125 + NSArray *array = [initMultipartUploadReq.CNYHeader componentsSeparatedByString:@"\n"];
  126 + NSString *headers = [array firstObject];
  127 +
  128 + [CNLiveUpload getTokenWithMd5:initMultipartUploadReq.contentMd5 verb:initMultipartUploadReq.httpMethod type:initMultipartUploadReq.contentType res:initMultipartUploadReq.CNYResource headers:headers date:initMultipartUploadReq.strDate success:^(NSString *token ,NSString *cnliveDate) {
  129 + [initMultipartUploadReq setStrCNLiveToken:token];
  130 + [initMultipartUploadReq setStrDate:cnliveDate];
  131 + _muilt = [[CNLiveClient initialize] initiateMultipartUploadWithRequest:initMultipartUploadReq];
  132 +
  133 + if (_muilt == nil) {
  134 + NSLog(@"####Init upload failed, please check access key, secret key and bucket name!####");
187 135 return ;
188 136 }
189   - if (!(_partSize > 0 || _partSize != 0)) {
190   - _partLength = _fileSize;
191   - }else{
192   - _partLength = _partSize * 1024.0 * 1024.0;
  137 +
  138 + //选择相册还是普通方式
  139 + _muilt.uploadType = _uploadType;
  140 +
  141 + //根据文件路径不一样,有如下两种上传
  142 + if (_muilt.uploadType == kCNLiveUploadNormal) { //如果是沙盒或者工程里的文件
  143 + //工程里,沙盒里,是沙盒路径
  144 + NSString *strFilePath = [[NSBundle mainBundle] pathForResource:@"cnlive" ofType:@"mp4"];
  145 + _fileHandle = [NSFileHandle fileHandleForReadingAtPath:strFilePath];
  146 + _fileSize = [_fileHandle availableData].length;
  147 + if (_fileSize <= 0) {
  148 + NSLog(@"####This file is not exist!####");
  149 + return ;
  150 + }
  151 + if (!(_partSize > 0 || _partSize != 0)) {
  152 + _partLength = _fileSize;
  153 + }else{
  154 + _partLength = _partSize * 1024.0 * 1024.0;
  155 + }
  156 + _totalNum = (ceilf((float)_fileSize / (float)_partLength));
  157 + [_fileHandle seekToFileOffset:0];
  158 + }else
  159 + {
  160 + //如果是相册里的,从这传
  161 + ALAsset *assets = [[CNLiveClient initialize] getAlassetFromAlassetURL:_imageAssetUrl];
  162 + ALAssetRepresentation *assetD = assets.defaultRepresentation;
  163 +
  164 + _fileSize = assetD.size;
  165 + if (_fileSize <= 0) {
  166 + NSLog(@"####This file is not exist!####");
  167 + return ;
  168 + }
  169 + if (!(_partSize > 0 || _partSize != 0)) {
  170 + _partLength = _fileSize;
  171 + }else{
  172 + _partLength = _partSize * 1024.0 * 1024.0;
  173 + }
  174 + _totalNum = (ceilf((float)_fileSize / (float)_partLength));
193 175 }
194   - _totalNum = (ceilf((float)_fileSize / (float)_partLength));
195   - }
196   -
  176 +
197 177 #warning 上传的断点续传判断:初始化上传后,开始上传前,此处需要list一下所有的数据块,如果uploadID是新生成的,可以跳过list过程从第一块开始传,如果上传是断点续传,需用初始化用到的uploadId,list一下所有已经传过的数据块,再从暂停块上传即可, 这里用NSUserDefault演示存储过程。
198   - //判断uploadId是否存在,进而进行上传的断点续传
199   - if ([mUserDefaults objectForKey:keyUploadId] == nil) {
200   - [mUserDefaults setObject:_muilt.uploadId forKey:keyUploadId];
201   - [mUserDefaults synchronize];
202   - _uploadNum = 1;
203   - [self uploadWithPartNumber:_uploadNum];
204   - }else
205   - {
206   - _muilt.uploadId = [mUserDefaults objectForKey:keyUploadId];
207   - //list一下所有上传过的块
208   - CNLiveListPartsRequest *req2 = [[CNLiveListPartsRequest alloc] initWithMultipartUpload:_muilt];
209   - [req2 setCompleteRequest];
210   - [CNLiveUpload getTokenWithMd5:req2.contentMd5 verb:req2.httpMethod type:req2.contentType res:req2.CNYResource headers:headers date:req2.strDate success:^(NSString *token ,NSString *cnliveDate) {
211   - [req2 setStrCNLiveToken:token];
212   - [req2 setStrDate:cnliveDate];
213   - CNLiveListPartsResponse *response2 = [[CNLiveClient initialize] listParts:req2];
214   -
215   - NSLog(@"response.listResult.parts.count =%lu",(unsigned long)[response2.listResult.parts count]);
216   -
217   - //从这块开始上传,list结果的最后一块
218   - _uploadNum = ((CNLivePart *)[response2.listResult.parts lastObject]).partNumber + 1 ;
219   -
220   - //进度补齐
221   - long long alreadyTotalWriten = (_uploadNum - 1) * _partLength ;
222   - double progress = alreadyTotalWriten / (float)_fileSize;
223   - UIProgressView *progressView = (UIProgressView *)[self.view viewWithTag:199];
224   - progressView.progress = progress;
  178 + //判断uploadId是否存在,进而进行上传的断点续传
  179 + if ([mUserDefaults objectForKey:keyUploadId] == nil) {
  180 + [mUserDefaults setObject:_muilt.uploadId forKey:keyUploadId];
  181 + [mUserDefaults synchronize];
  182 + _uploadNum = 1;
225 183 [self uploadWithPartNumber:_uploadNum];
226   - } failure:^(NSDictionary *error) {
227   -
228   - }];
229   - }
  184 + }else
  185 + {
  186 + _muilt.uploadId = [mUserDefaults objectForKey:keyUploadId];
  187 + //list一下所有上传过的块
  188 + CNLiveListPartsRequest *req2 = [[CNLiveListPartsRequest alloc] initWithMultipartUpload:_muilt];
  189 + [req2 setCompleteRequest];
  190 + [CNLiveUpload getTokenWithMd5:req2.contentMd5 verb:req2.httpMethod type:req2.contentType res:req2.CNYResource headers:headers date:req2.strDate success:^(NSString *token ,NSString *cnliveDate) {
  191 + [req2 setStrCNLiveToken:token];
  192 + [req2 setStrDate:cnliveDate];
  193 + CNLiveListPartsResponse *response2 = [[CNLiveClient initialize] listParts:req2];
  194 +
  195 + NSLog(@"response.listResult.parts.count =%lu",(unsigned long)[response2.listResult.parts count]);
  196 +
  197 + //从这块开始上传,list结果的最后一块
  198 + _uploadNum = ((CNLivePart *)[response2.listResult.parts lastObject]).partNumber + 1 ;
  199 +
  200 + //进度补齐
  201 + long long alreadyTotalWriten = (_uploadNum - 1) * _partLength ;
  202 + double progress = alreadyTotalWriten / (float)_fileSize;
  203 + UIProgressView *progressView = (UIProgressView *)[self.view viewWithTag:199];
  204 + progressView.progress = progress;
  205 + [self uploadWithPartNumber:_uploadNum];
  206 + } failure:^(NSDictionary *error) {
  207 + NSLog(@"error %@",error);
  208 + }];
  209 + }
  210 + } failure:^(NSDictionary *error) {
  211 + NSLog(@"error %@",error);
  212 + }];
230 213 } failure:^(NSDictionary *error) {
231   -
  214 + NSLog(@"error %@",error);
232 215 }];
233 216 }
234 217  
... ... @@ -243,7 +226,8 @@
243 226 NSData *data = nil;
244 227 if (_muilt.uploadType == kCNLiveUploadAlasset) {
245 228 //相册信息
246   - data = [[CNLiveClient initialize] getUploadPartDataWithPartNum:partNumber partLength:FileBlockSize Alasset:[self getAlasset]];
  229 + ALAsset *assets = [[CNLiveClient initialize] getAlassetFromAlassetURL:_imageAssetUrl];
  230 + data = [[CNLiveClient initialize] getUploadPartDataWithPartNum:partNumber partLength:FileBlockSize Alasset:assets];
247 231 }else
248 232 {
249 233 //沙盒路径
... ... @@ -313,45 +297,52 @@
313 297 //最小支持但块上传小于5M,最大支持单块上传为5G
314 298 - (void)beginSingleUpload:(NSInteger) row
315 299 {
316   - CNLiveAccessControlList *ControlList = [[CNLiveAccessControlList alloc] init];
317   - [ControlList setContronAccess:CNLiveYun_Permission_Public_Read_Write];
318   - CNLivePutObjectRequest *putObjRequest = [[CNLivePutObjectRequest alloc] initWithName:_bucketName withAcl:ControlList grantAcl:nil];
319   - NSString *fileName = [[NSBundle mainBundle] pathForResource:@"7.6M" ofType:@"mov"];
320   - putObjRequest.data = [NSData dataWithContentsOfFile:fileName options:NSDataReadingMappedIfSafe error:nil];
321   - _fileSize = putObjRequest.data.length;
322   -
323   - putObjRequest.delegate = self;
324   - putObjRequest.filename = _bucketKey;
325   - putObjRequest.contentMd5 = [CNLiveSDKUtil base64md5FromData:putObjRequest.data];
326   - [putObjRequest setCompleteRequest];
327   -
328   - NSArray *array = [putObjRequest.CNYHeader componentsSeparatedByString:@"\n"];
329   - NSString *headers = [array firstObject];
330   -
331   - [CNLiveUpload getTokenWithMd5:putObjRequest.contentMd5 verb:putObjRequest.httpMethod type:putObjRequest.contentType res:putObjRequest.CNYResource headers:headers date:putObjRequest.strDate success:^(NSString *token ,NSString *cnliveDate) {
332   - [putObjRequest setStrCNLiveToken:token];
333   - [putObjRequest setStrDate:cnliveDate];
334   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
335   - CNLivePutObjectResponse *response = [[CNLiveClient initialize] putObject:putObjRequest];
336   -
337   - //putObjRequest若没设置代理,则是同步的下方判断,
338   - //putObjRequest若设置了代理,则走上传代理回调,
339   - if (putObjRequest.delegate == nil) {
340   - NSLog(@"%@",[[NSString alloc] initWithData:response.body encoding:NSUTF8StringEncoding]);
341   - if (response.httpStatusCode == 200) {
342   - NSLog(@"Put object success");
343   - }
344   - else {
345   - NSLog(@"Put object failed");
  300 + [CNLiveUpload initCNLiveUploadWithSuccess:^{
  301 +
  302 + CNLiveAccessControlList *ControlList = [[CNLiveAccessControlList alloc] init];
  303 + [ControlList setContronAccess:CNLiveYun_Permission_Public_Read_Write];
  304 + CNLivePutObjectRequest *putObjRequest = [[CNLivePutObjectRequest alloc] initWithAcl:ControlList grantAcl:nil];
  305 + NSString *fileName = [[NSBundle mainBundle] pathForResource:@"cnlive" ofType:@"mp4"];
  306 + putObjRequest.data = [NSData dataWithContentsOfFile:fileName options:NSDataReadingMappedIfSafe error:nil];
  307 + _fileSize = putObjRequest.data.length;
  308 +
  309 + putObjRequest.delegate = self;
  310 + putObjRequest.filename = [self bucketKey];
  311 + putObjRequest.contentMd5 = [CNLiveSDKUtil base64md5FromData:putObjRequest.data];
  312 + [putObjRequest setCompleteRequest];
  313 +
  314 + NSArray *array = [putObjRequest.CNYHeader componentsSeparatedByString:@"\n"];
  315 + NSString *headers = [array firstObject];
  316 +
  317 + [CNLiveUpload getTokenWithMd5:putObjRequest.contentMd5 verb:putObjRequest.httpMethod type:putObjRequest.contentType res:putObjRequest.CNYResource headers:headers date:putObjRequest.strDate success:^(NSString *token ,NSString *cnliveDate) {
  318 + [putObjRequest setStrCNLiveToken:token];
  319 + [putObjRequest setStrDate:cnliveDate];
  320 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  321 + CNLivePutObjectResponse *response = [[CNLiveClient initialize] putObject:putObjRequest];
  322 +
  323 + //putObjRequest若没设置代理,则是同步的下方判断,
  324 + //putObjRequest若设置了代理,则走上传代理回调,
  325 + if (putObjRequest.delegate == nil) {
  326 + NSLog(@"%@",[[NSString alloc] initWithData:response.body encoding:NSUTF8StringEncoding]);
  327 + if (response.httpStatusCode == 200) {
  328 + NSLog(@"Put object success");
  329 + }
  330 + else {
  331 + NSLog(@"Put object failed");
  332 + }
346 333 }
347   - }
348   - });
  334 + });
  335 + } failure:^(NSDictionary *error) {
  336 + NSLog(@"error %@",error);
  337 + }];
349 338 } failure:^(NSDictionary *error) {
350 339 NSLog(@"error %@",error);
351 340 }];
  341 +
352 342 }
353 343  
354   -#pragma mark - Action
  344 +#pragma mark -
  345 +#pragma mark - ButtonAction
355 346 - (void)uploadBtnClicked:(UIButton *)btn
356 347 {
357 348 btn.selected =! btn.selected;
... ... @@ -364,6 +355,7 @@
364 355 UIProgressView *progressView = (UIProgressView *)[self.view viewWithTag:199];
365 356 progressView.progress = 0;
366 357 [btn setTitle:@"开始" forState:UIControlStateNormal];
  358 + _uploadType = kCNLiveUploadNormal;
367 359 return;
368 360 }
369 361 [_muilt pause];
... ... @@ -371,6 +363,72 @@
371 363 }
372 364 }
373 365  
  366 +- (void)styleBtnAction
  367 +{
  368 + [self uploadStyle];
  369 +}
  370 +
  371 +- (void)uploadStyle
  372 +{
  373 + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"上传方式" message:@"默认上传方式为本地文件" preferredStyle:UIAlertControllerStyleActionSheet];
  374 + UIAlertAction *localAlert = [UIAlertAction actionWithTitle:@"本地文件" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  375 + _uploadType = kCNLiveUploadNormal;
  376 + }];
  377 + [alert addAction:localAlert];
  378 + UIAlertAction *albumAlert = [UIAlertAction actionWithTitle:@"相册文件" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  379 +
  380 + UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
  381 + imagePicker.delegate = self;
  382 + imagePicker.allowsEditing = YES;
  383 + imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;//相机相册
  384 + // 设置所支持的媒体功能,即只能拍照,或则只能录像,或者两者都可以
  385 +#warning 此处需要区分视频还是图片文件,获取上传资源路径([CNLiveUpload getUploadResourceUrlWithBucketKey:uploadType:success:failure:])时需要用到此CNLiveYun_UploadType,Demo演示相册中 视频文件的上传
  386 + // NSString *requiredMediaType = ( NSString *)kUTTypeImage;
  387 + NSString *requiredMediaType1 = ( NSString *)kUTTypeMovie;
  388 + NSArray *arrMediaTypes=[NSArray arrayWithObjects: requiredMediaType1,nil];//requiredMediaType
  389 + imagePicker.mediaTypes = arrMediaTypes;
  390 + [self presentViewController:imagePicker animated:YES completion:NULL];
  391 +
  392 + _uploadType = kCNLiveUploadAlasset;
  393 + }];
  394 + [alert addAction:albumAlert];
  395 + UIAlertAction *cancelAlert = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  396 + [self dismissViewControllerAnimated:YES completion:NULL];
  397 + }];
  398 + [alert addAction:cancelAlert];
  399 + [self presentViewController:alert animated:YES completion:NULL];
  400 +}
  401 +
  402 +//#pragma mark 相册方法
  403 +///*
  404 +// 这里,枚举模拟器相册所有的视频,模拟器只有一个只能获得开头传入的cnlive.mp4视频,
  405 +// 具体工程使用时根据具体逻辑,获取到Alasset即可
  406 +//CNLiveClient 方法:
  407 +// - (NSData *)getUploadPartDataWithPartNum:(NSInteger)partNum
  408 +// partLength:(NSInteger)partlength
  409 +// alassetURL:(NSURL *)alassetURL;
  410 +//
  411 +// - (NSData *)getUploadPartDataWithPartNum:(NSInteger)partNum
  412 +// partLength:(NSInteger)partlength
  413 +// Alasset:(ALAsset *)assets;
  414 +//
  415 +// - (ALAsset *)getAlassetFromAlassetURL:(NSURL *)alassetURL;
  416 +//
  417 +// */
  418 +#pragma mark - UIImagePickerControllerDelegate
  419 +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
  420 +{
  421 + NSURL *imageAssetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
  422 + _imageAssetUrl = imageAssetUrl;
  423 + [self dismissViewControllerAnimated:YES completion:NULL];
  424 +}
  425 +
  426 +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
  427 +{
  428 + [self dismissViewControllerAnimated:YES completion:NULL];
  429 + NSLog(@"cancel");
  430 +}
  431 +
374 432 #pragma mark - UITableView datasource
375 433 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
376 434 {
... ... @@ -437,10 +495,11 @@
437 495 if ([request isKindOfClass:[KS3PutObjectRequest class]]) {
438 496 if (response.httpStatusCode == 200) {
439 497 NSLog(@"单块上传成功");
440   - [CNLiveUpload getUploadResourceUrlWithBucketKey:_bucketKey uploadType:CNLiveYun_UploadType_VideoFile success:^(NSString *resUrl) {
441   - NSLog(@"succ:%@",resUrl);
  498 +#warning 根据选择的文件类型更改CNLiveYun_UploadType,Demo演示视频路径的获取
  499 + [CNLiveUpload getUploadResourceUrlWithBucketKey:[self bucketKey] uploadType:CNLiveYun_UploadType_VideoFile success:^(NSString *resUrl) {
  500 + NSLog(@"资源路径: %@",resUrl);
442 501 } failure:^(NSDictionary *error) {
443   - NSLog(@"error%@",error);
  502 + NSLog(@"error: %@",error);
444 503 }];
445 504 }else
446 505 {
... ... @@ -490,8 +549,9 @@
490 549 [mUserDefaults setInteger:0 forKey:keyUploadPartNum];
491 550 _uploadNum = 0 ;
492 551 [mUserDefaults synchronize];
493   - [CNLiveUpload getUploadResourceUrlWithBucketKey:_bucketKey uploadType:CNLiveYun_UploadType_VideoFile success:^(NSString *resUrl) {
494   - NSLog(@"succ: %@",resUrl);
  552 +#warning 根据选择的文件类型更改CNLiveYun_UploadType,Demo演示视频路径的获取
  553 + [CNLiveUpload getUploadResourceUrlWithBucketKey:[self bucketKey] uploadType:CNLiveYun_UploadType_VideoFile success:^(NSString *resUrl) {
  554 + NSLog(@"资源路径: %@",resUrl);
495 555 } failure:^(NSDictionary *error) {
496 556 NSLog(@"error: %@",error);
497 557 }];
... ... @@ -567,11 +627,23 @@
567 627 }
568 628 }
569 629  
  630 +#pragma mark - Lazy
  631 +- (UIButton *)styleBtn
  632 +{
  633 + if (!_styleBtn)
  634 + {
  635 + _styleBtn = [[UIButton alloc] initWithFrame:CGRectMake(mScreenWidth *0.5-70, CGRectGetMaxY(self.tableView.frame) + 20, 140, 30)];
  636 + [_styleBtn setTitle:@"选择上传方式" forState:UIControlStateNormal];
  637 + [_styleBtn addTarget:self action:@selector(styleBtnAction) forControlEvents:UIControlEventTouchUpInside];
  638 + _styleBtn.backgroundColor = [UIColor redColor];
  639 + }
  640 + return _styleBtn;
  641 +}
  642 +
570 643 - (void)didReceiveMemoryWarning {
571 644 [super didReceiveMemoryWarning];
572 645 // Dispose of any resources that can be recreated.
573 646 }
574   -
575 647 /*
576 648 #pragma mark - Navigation
577 649  
... ...
CNLiveUploadYunSDKDemo/CNLiveUploadYunSDKDemo/cnlive.mp4 0 → 100644
No preview for this file type
CNLiveUploadYunSDKDemo/iOS 视讯云上传SDK使用说明文档.pdf
No preview for this file type
README.md
... ... @@ -55,7 +55,6 @@
55 55 */
56 56 - (CNLivePutObjectResponse *)putObject:(CNLivePutObjectRequest *)putObjectRequest;
57 57 ```
58   -**putObjectRequest.contentType**不设置默认为下载类型,[设置请参考contentType示例](http://tool.oschina.net/commons)
59 58  
60 59 * 分块上传
61 60  
... ... @@ -72,7 +71,6 @@
72 71 ```
73 72 调用这个接口会初始化一个分块上传,response会返回一个CNLiveMultipartUpload 对象,其属性有upload id, upload id 用来标识属于当前上传的具体的块,并且用来标识完成分块上传或者取消分块上传。
74 73  
75   -**uploadPartRequest.contentType**不设置默认为下载类型,[设置请参考contentType示例](http://tool.oschina.net/commons)
76 74  
77 75 * 取消分块上传
78 76  
... ...