开发者社区> 问答> 正文

我用阿里的视频录制来录制视频,如果上传的时候失败了,则下次重新上传

#pragma mark -- 录制视频,录制成功时,点击提交按钮保存视频地址等信息,如果上传成功则删除保存的信息,负责下次用这些信息重新上传。
-( void)recordVideo
{
     NSInteger timeCount;
    timeCount = 1800; //30分钟
    
    AliyunVideoUIConfig *config = [[AliyunVideoUIConfig alloc ] init ];
    
    config.timelineDeleteColor = [ UIColor redColor ];
    config. backgroundColor = [ UIColor blackColor];
    config.timelineBackgroundCollor = [ UIColor whiteColor ];
    config.durationLabelTextColor = [ UIColor redColor ];
    config.hiddenDurationLabel = NO ;
    config.hiddenFlashButton = NO ;
    config.hiddenBeautyButton = NO ;
    config.hiddenCameraButton = NO ;
    config.hiddenImportButton = YES ;
    config.hiddenDeleteButton = NO ;
    config.hiddenFinishButton = NO ;
    config. recordOnePart = NO;
    
    config.imageBundleName = @"QPSDK" ;
    
    config.showCameraButton = YES ;
    config. timelineTintColor = [ UIColor greenColor];
    config. recordType = AliyunVideoRecordTypeCombination ;
    [[ AliyunVideoBase shared ] registerWithAliyunIConfig :config];
    
     NSString *path = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory , NSUserDomainMask , YES ). lastObject stringByAppendingPathComponent : @"Video.mp4" ];
    
    //录制视频或者选择系统相册中的视频后需要写入文件到沙盒,在/Library/Caches 目录下面新建一个文件夹Video用来缓存视频文件
//    NSString *fileName = @"Video.mp4";
//    NSString *cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
//    NSString *path = [cachesDirectory stringByAppendingPathComponent:@"video"];
//    NSFileManager *fileManager = [[NSFileManager alloc] init];
//    [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
//    path = [cachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"/video/%.0f%@",[NSDate date].timeIntervalSince1970,fileName]];
    
     NSLog (@"录制文件地址:%@" ,path);
     self . recoreParam = [ AliyunVideoRecordParam recordConfigWithVideoRatio :AliyunVideoVideoRatio9To16 videoSize :AliyunVideoVideoSize360P position :AliyunCameraPositionFront trochMode :AliyunCameraTorchModeOff beautifyStatus : NO beautifyValue : 90 outputPath :path minDuration : 1 maxDuration :timeCount videoQuality :AliyunVideoQualityLow encodeMode :AliyunVideoEncodeModeHardH264 fps : 5 gop : 5 ];
     UIViewController *recordVC = [[ AliyunVideoBase shared ] createRecordViewControllerWithRecordParam : self . recoreParam ];
    recordVC.view .backgroundColor = [UIColor whiteColor ];
    [AliyunVideoBase shared ].delegate = self ;
    recordVC.hidesBottomBarWhenPushed = YES ;
    [ self . VC . navigationController pushViewController :recordVC animated : YES ];
}
#pragma mark 实现aliyunBaseVideo的协议
-( void)videoBase:( AliyunVideoBase *)base recordCompeleteWithRecordViewController:( UIViewController *)recordVC videoPath:( NSString *)videoPath{
     NSLog( @"录制完成 %@", videoPath);
    [ _videoPathArray removeAllObjects ];
    [_videoFileNameArray removeAllObjects ];
    [ _videoNeedArray removeAllObjects ];
    
    [ _videoPathArray addObject:videoPath];
    [ self getOSSCredatailWithCode : @"class-video" ];
    [ self . classVideoBtn setImage :[ UIImage imageNamed : @"start" ] forState :UIControlStateNormal ];
    
    [ self . VC . navigationController popViewControllerAnimated : YES ];
    [ self . VC . navigationController setNavigationBarHidden : NO ];
}
- ( void)videoBaseRecordVideoExit{
     NSLog (@"退出录制!" );
    [ self . VC . navigationController popViewControllerAnimated : YES ];
    [ self . VC . navigationController setNavigationBarHidden : NO ];
}
#pragma mark -- 获取上传OSS用户信息(阿里云)
-( void)getOSSCredatailWithCode:( NSString *)code
{
    [ SVProgressHUD showWithStatus : @"提交中" ];
    
     NSString *interfaceStr = [[ NSString stringWithFormat :@"/common/oss_upload_info.do?code=%@&ios_version=%@" ,code, version ] md5 ];
    
     NSDictionary *dic= @{@"code" :code,@"ios_version" : version ,@"APICHANNEL_ID" : channelNumber ,@"APICHANNEL_SIGN" :interfaceStr } ;
    
    [[ NetDataTool shareInstance] getNetData: ROOTPATH url: @"common/oss_upload_info.do" With:dic and:^( id responseObject) {
        [SVProgressHUD dismiss ];
        
         NSDictionary *dataDic = [ NSJSONSerialization JSONObjectWithData :responseObject options :NSJSONReadingAllowFragments error : nil ];
        
         NSString *str = dataDic[ @"msg"];
         if ([str isEqualToString: @"ok"]){
            
             NSLog( @"%@",str);
            
             //判断是图片还是视频
             if ([code isEqualToString: @"class"]) {
                //code是class说明上传的是图片
            } else{
                //code是class-video说明上传的是视频
                 self. videoModel = [ upToOSSModel getDataWithDic:dataDic];
                 self. videoCredentail = [ credentailsModel getDataWith:dataDic];
                [_videoFileNameArray addObject : self .videoModel .filename ];
            }
            
        } else
        {
            [ self alertShowWith: @"服务器错误!"];
        }
        
    } Faile:^( NSError *error) {
         NSLog( @"失败%@",error);
    }];
    
}
#pragma mark -- 0调用提交短视频的方法
- ( void)uploadVideoAction{
     if (_videoPathArray . count > 0 ) {
        //上传视频的方法
//        [self uploadVideoWith:_videoPathArray[0] withType:@"video"];
        //断点上传视频的方法
        [ self ddUploadVideoWith : _videoPathArray [ 0 ]];
        
        //将提交的视频信息保存在本地
         DDUModel *model = [[ DDUModel alloc] init];
         //面授的视频
        model. fileType = @"MSVIDEO";
        model.filePath = _videoPathArray [ 0 ];
        model.fileName = _videoFileNameArray [ 0 ];
//        model.fileName = _videoNeedArray[0];
        model.bucketName = self .videoModel .bucketname ;
        model. netStr = @"classesapi/upSchedulePath.do" ;
         if ( self. videoNeedArray. count> 0){
             NSString *VideoPath = self. videoNeedArray. firstObject;
             NSString *infoStr = [ NSString stringWithFormat: @"ios_version=%@&PATH=%@&SCHEDULE_ID=%@", version,[VideoPath encoding], self. dataModel. SCHEDULE_ID];
            
             NSString *interfaceStr = [[ NSString stringWithFormat: @"/classesapi/upSchedulePath.do?%@",infoStr] md5];
             NSDictionary *dic= @{@"PATH" :VideoPath,@"SCHEDULE_ID" : self . dataModel . SCHEDULE_ID ,@"ios_version" : version ,@"APICHANNEL_ID" : channelNumber ,@"APICHANNEL_SIGN" :interfaceStr } ;
            model. dic = dic;
        }
         NSData *data = [ NSKeyedArchiver archivedDataWithRootObject:model];
         NSArray *array = [[ NSUserDefaults standardUserDefaults ] objectForKey : @"uploadList" ];
         NSMutableArray *mutArray = [ NSMutableArray arrayWithArray:array];
        [mutArray insertObject:data atIndex: 0];
         NSArray *arr = [ NSArray arrayWithArray:mutArray];
        [[ NSUserDefaults standardUserDefaults ] removeObjectForKey : @"uploadList" ];
        [[ NSUserDefaults standardUserDefaults ] setObject :arr forKey : @"uploadList" ];
        [[ NSUserDefaults standardUserDefaults ] synchronize ];
        
    } else{
        [ self alertShowWith : @"请先选择上传视频!" ];
    }
}
#pragma mark -- 断点续传视频到阿里云服务器第1步(初始化分片上传获得uploadId)
#pragma mark -- 断点续传视频到阿里云服务器第2步
-( void)ddUploadVideoWith:( NSString *)path
{
    [ SVProgressHUD showWithStatus : @"上传中" ];
    [ SVProgressHUD setDefaultAnimationType :SVProgressHUDAnimationTypeNative ];
    //1. 初始化OSSClient
     id< OSSCredentialProvider> credential1 = [[ OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^ NSString *( NSString *contentToSign, NSError * __autoreleasing *error) {
         NSString *signature = [ OSSUtil calBase64Sha1WithData:contentToSign withSecret: SecretKey];
         if (signature != nil) {
            *error = nil;
        } else {
            
            *error = [ NSError errorWithDomain: ENDPOINTVIDEO code: OSSClientErrorCodeSignFailed userInfo: nil];
             return nil;
        }
         return [ NSString stringWithFormat: @"OSS %@:%@", AccessKey, signature];
    }];
    
    OSSClientConfiguration * conf = [OSSClientConfiguration new ];
    conf.maxRetryCount = 2 ;
    conf.timeoutIntervalForRequest = 30 ;
    conf.timeoutIntervalForResource = 24 * 60 * 60 ;
    
     client1 = [[ OSSClient alloc ] initWithEndpoint : ENDPOINTVIDEO credentialProvider :credential1 clientConfiguration :conf];
    
    
     NSString *bucketName = self. videoModel. bucketname;
    
     NSString *subStr = [path componentsSeparatedByString : @"." ][ 1 ];
     NSString *videoKey = [ NSString stringWithFormat: @"%@.%@", _videoFileNameArray[ 0],subStr];
     NSString * objectKey = videoKey;
    [ self. videoNeedArray addObject:videoKey];
    
    OSSInitMultipartUploadRequest *init = [OSSInitMultipartUploadRequest new ];
    init. bucketName = bucketName;
    init. objectKey = videoKey;
     OSSTask * initTask = [ client1 multipartUploadInit:init];
    [initTask waitUntilFinished ];
     if (!initTask. error) {
        
        OSSInitMultipartUploadResult * result = initTask.result ;
        
         //执行断点续传
        OSSResumableUploadRequest *resumableUpload = [OSSResumableUploadRequest new ];
        resumableUpload. bucketName = bucketName;
        resumableUpload. objectKey = objectKey;
        resumableUpload. partSize = 1024 * 101;
        resumableUpload. uploadId = result. uploadId;
        resumableUpload. uploadProgress = ^( int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
            //NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
             NSString *str1 = [ NSString stringWithFormat: @"%lld",totalByteSent];
             NSString *str2 = [ NSString stringWithFormat: @"%lld",totalBytesExpectedToSend];
             int percent = ( int)([str1 floatValue]/[str2 floatValue] * 100);
             NSString *str = @"%";
            [ SVProgressHUD showWithStatus:[ NSString stringWithFormat: @"%d%@",percent,str]];
        };
        
//        NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
//        resumableUpload.recordDirectoryPath = cachesDir;
//        resumableUpload.deleteUploadIdOnCancelling = NO;
        resumableUpload. uploadingFileURL = [ NSURL fileURLWithPath:path];
         NSLog( @"录制后上传的地址%@",path);
        
         OSSTask * resumeTask = [ client1 resumableUpload:resumableUpload];
        [resumeTask continueWithBlock:^ id( OSSTask *task) {
             if (task. error) {
                 NSLog( @"error: %@", task.error);
                 if ([task. error. domain isEqualToString: OSSClientErrorDomain] && task. error. code == OSSClientErrorCodeCannotResumeUpload) {
                    //该任务无法续传,需要获取新的uploadId重新上传
                }
            } else {
                 NSLog (@"Upload file success" );
                [ self uploadVideoToServiceAction ];
                
            }
             return nil;
        }];
        
    } else{
         return;
    }
    
  
    

}
#pragma mark -- 2提交短视频到自己的服务器的方法
- ( void)uploadVideoToServiceAction{
    //提交添加的文件
    [ SVProgressHUD showWithStatus : @"提交中" ];
    
    NSDictionary *dic;
    
     NSString *VideoPath;
     if ( self .videoNeedArray . count > 0 ){
        VideoPath = self. videoNeedArray. firstObject;
         NSString *infoStr = [ NSString stringWithFormat: @"ios_version=%@&PATH=%@&SCHEDULE_ID=%@", version,[VideoPath encoding], self. dataModel. SCHEDULE_ID];
        
         NSString *interfaceStr = [[ NSString stringWithFormat: @"/classesapi/upSchedulePath.do?%@",infoStr] md5];
        dic= @{@"PATH" :VideoPath,@"SCHEDULE_ID" : self . dataModel . SCHEDULE_ID ,@"ios_version" : version ,@"APICHANNEL_ID" : channelNumber ,@"APICHANNEL_SIGN" :interfaceStr } ;
    }
    
    
    //图片太大会导致文件上传不成功
    
    [[ NetDataTool shareInstance] getNetData: ROOTPATH url: @"classesapi/upSchedulePath.do" With:dic and:^( id responseObject){
        
        [SVProgressHUD dismiss ];
        
         NSDictionary *dataDic = [ NSJSONSerialization JSONObjectWithData :responseObject options :NSJSONReadingAllowFragments error : nil ];
        
         NSString *str = dataDic[ @"msg"];
         if ([str isEqualToString: @"ok"]){
            
            [ SVProgressHUD showSuccessWithStatus : @"提交成功!" ];
            [ self . VC . navigationController popViewControllerAnimated : YES ];
             NSMutableArray *mutArray = [[[ NSUserDefaults standardUserDefaults ] objectForKey : @"uploadList" ] mutableCopy ];
             if (mutArray. count) {
                [mutArray removeObjectAtIndex: 0];
            }
            [[ NSUserDefaults standardUserDefaults ] removeObjectForKey : @"uploadList" ];
            [[ NSUserDefaults standardUserDefaults ] setObject :mutArray forKey : @"uploadList" ];
            [[ NSUserDefaults standardUserDefaults ] synchronize ];
            
        } else
        {
            [ self alertShowWith: @"服务器错误,请稍后重试"];
        }
        
    } Faile:^( NSError *error) {
         NSLog( @"失败%@",error);
    }];
    

}






这个功能已经是实现的了,就是在这种情况下:上传的时候由于一些原因失败了,那我下次进来的时候用断点续传。但是提示打开文件失败,因为不存在该文件。我想知道是不是阿里的录制视频没有保存在本地?

展开
收起
飞羽而醉月 2018-04-13 15:37:20 2949 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
附件下载测试 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载