登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

视频录制+压缩+合并+清除沙盒缓存

[复制链接]
来自: cleven 分类: iOS精品源码 上传时间: 2016-7-20 09:59:44
Tag:录制视频 视频 合并 缓存 video

项目介绍:

视频录制+压缩+合并+清除沙盒缓存
[Objective-C] 查看源文件 复制代码
-(void)AVCaptureVideo{
   
    //创建视频设备(摄像头前,后)
    NSArray *devices = [AVCaptureDevicedevicesWithMediaType:AVMediaTypeVideo];
    //初始化一个摄像头输入设备(first是后置摄像头,last是前置摄像头)
    AVCaptureDeviceInput *inputVideo = [AVCaptureDeviceInputdeviceInputWithDevice:[devices firstObject] error:NULL];
    //创建麦克风设备
    AVCaptureDevice *deviceAudio = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeAudio];
    //初始化麦克风输入设备
    AVCaptureDeviceInput *inputAudio = [AVCaptureDeviceInputdeviceInputWithDevice:deviceAudioerror:NULL];
   
    //初始化一个movie的文件输出
    AVCaptureMovieFileOutput *output = [[AVCaptureMovieFileOutputalloc] init];
    self.output = output;//保存output,方便下面操作
   
    //初始化一个会话
    AVCaptureSession *session = [[AVCaptureSessionalloc] init];
   
    //将输入输出设备添加到会话中
    if ([sessioncanAddInput:inputVideo]) {
        [session addInput:inputVideo];
    }
    if ([sessioncanAddInput:inputAudio]) {
        [session addInput:inputAudio];
    }
    if ([sessioncanAddOutput:output]) {
        [session addOutput:output];
    }
   
   
    //添加一个视频预览图层,设置大小,添加到控制器view的图层上
    //创建一个预览涂层
    AVCaptureVideoPreviewLayer *preLayer = [AVCaptureVideoPreviewLayerlayerWithSession:session];
    //设置图层的大小
    preLayer.frame =self.view.bounds;
    //添加到view上
    [self.view.layeraddSublayer:preLayer];
   
    //开始会话
    [session startRunning];
   
}

#pragma mark ==============
#pragma mark ===录制按钮======
- (void)clickVideoBtn:(UIButton *)sender {
    //判断是否在录制,如果在录制,就停止,并设置按钮title
    if ([self.outputisRecording]) {
      [self.outputstopRecording];
        

   [sender setTitle:@"录制"forState:UIControlStateNormal];
    return;
    }
   
    //设置按钮的title
    [sender setTitle:@"停止"forState:UIControlStateNormal];
   
    //设置录制视频保存的路径
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                NSUserDomainMask, YES).lastObjectstringByAppendingPathComponent:[NSStringstringWithFormat:@"%@.mov",[NSDatedate]]];
   

     //转为视频保存的url
     NSURL *url  = [NSURLfileURLWithPath:path];
   
//    UISaveVideoAtPathToSavedPhotosAlbum(path, nil, nil, nil);
   
    //开始录制,并设置控制器为录制的代理
    [self.outputstartRecordingToOutputFileURL:urlrecordingDelegate:self];
}


//清楚缓存
- (void)clickClearMemory{
   
   NSString *path = [LBClearCacheToolgetCacheSizeWithFilePath: [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject]];
   
    UIAlertController *alert=[UIAlertControlleralertControllerWithTitle:[NSStringstringWithFormat:@"确定清除%@缓存吗?",path]message:nilpreferredStyle:UIAlertControllerStyleActionSheet];
    //创建一个取消和一个确定按钮
    UIAlertAction *actionCancle=[UIAlertActionactionWithTitle:@"取消"style:UIAlertActionStyleCancelhandler:nil];
    //因为需要点击确定按钮后改变文字的值,所以需要在确定按钮这个block里面进行相应的操作
    UIAlertAction *actionOk=[UIAlertActionactionWithTitle:@"确定"style:UIAlertActionStyleDestructivehandler:^(UIAlertAction *_Nonnull action) {
        
        //清楚缓存
        BOOL isSuccess = [LBClearCacheToolclearCacheWithFilePath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject]];
        if (isSuccess) {
            [MBProgressHUDshowSuccess:@"清楚成功"];
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
               
                [MBProgressHUDhideAllHUDsForView:self.viewanimated:YES];
            });
        }
        
        
        
    }   ];
    //将取消和确定按钮添加进弹框控制器
    [alert addAction:actionCancle];
    [alert addAction:actionOk];
    //添加一个文本框到弹框控制器
   
    //显示弹框控制器
    [selfpresentViewController:alert animated:YEScompletion:nil];
   
}

#pragma mark - AVCaptureFileOutputRecordingDelegate
//录制完成代理
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
    [MBProgressHUDshowSuccess:@"录制完成"];
   
    [selfsetAlertView:outputFileURL];
   
}

#pragma mark ==============
#pragma mark ===输入框======
-(void)setAlertView:(NSURL *)inPutUrl{
   
    UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:@"输入视频名称"message:@""preferredStyle:(UIAlertControllerStyleAlert)];
   
    [alert addTextFieldWithConfigurationHandler:^(UITextField*textField) {
        
        textField.text = [NSStringstringWithFormat:@"%@",[NSDatedate]];
        
        [textField addTarget:selfaction:@selector(changValue:)forControlEvents:(UIControlEventEditingChanged)];
        
        self.videoName = textField.text;
        
    }];
   
    UIAlertAction *ok = [UIAlertActionactionWithTitle:@"确定"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *_Nonnull action) {
        
        [selfZIPVideo:inPutUrl VideoName:self.videoName];
    }];
   
    [alert addAction:ok];
   
    [selfpresentViewController:alert animated:YEScompletion:nil];

}


#pragma mark ==============
#pragma mark ===视频压缩======
- (void) lowQuailtyWithInputURL:(NSURL*)inputURL
                      outputURL:(NSURL*)outputURL
                   blockHandler:(void (^)(AVAssetExportSession*))handler
{
    AVURLAsset *asset = [AVURLAssetURLAssetWithURL:inputURL options:nil];
    AVAssetExportSession *session = [[AVAssetExportSessionalloc] initWithAsset:asset    presetName:AVAssetExportPresetMediumQuality];
    session.outputURL = outputURL;
    session.outputFileType =AVFileTypeQuickTimeMovie;
    [session exportAsynchronouslyWithCompletionHandler:^(void)
     {
         handler(session);
     }];
}
-(void)ZIPVideo:(NSURL *)inputURl VideoName:(NSString *)videoName{
   
    //设置录制视频保存的路径
    NSString *outpath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                            NSUserDomainMask, YES).lastObjectstringByAppendingPathComponent:[NSStringstringWithFormat:@"%@.mov",videoName]];
   
    //转为视频保存的url
    NSURL *outurl  = [NSURLfileURLWithPath:outpath];
   
    //把path添加到数组中(合并视频)
    [self.videoPathArrayaddObject:outpath];
   
    [selflowQuailtyWithInputURL:inputURl outputURL:outurl blockHandler:^(AVAssetExportSession *session)
     {
         if (session.status ==AVAssetExportSessionStatusCompleted)
         {
             NSLog(@"压缩成功");
            
         }
         else
         {
             NSLog(@"压缩失败");
            
         }
     }];
}

#pragma mark ==============
#pragma mark ===监听textfield======
-(void)changValue:(UITextField *)text{
   
    self.videoName = text.text;
   
}

//视频合并按钮
-(void)clickMergeButton{
   
    [selfmergeAndExportVideos:self.videoPathArraywithOutPath:[selfvideoPath]];
}
#pragma mark =====下面是合成视频的方法===========
- (void)mergeAndExportVideos:(NSArray*)videosPathArray withOutPath:(NSString*)outpath{
    if (videosPathArray.count ==0) {
        [MBProgressHUDshowError:@"请录制视频"];
        return;
    }
   
    [MBProgressHUDshowMessage:@"合并中..."toView:self.view];
   
    AVMutableComposition *mixComposition = [[AVMutableCompositionalloc] init];
   
    AVMutableCompositionTrack *audioTrack = [mixCompositionaddMutableTrackWithMediaType:AVMediaTypeAudio
                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *videoTrack = [mixCompositionaddMutableTrackWithMediaType:AVMediaTypeVideo
                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
    //视频旋转270(视频合并后默认旋转了-90度)
    videoTrack.preferredTransform =CGAffineTransformMake(0,1.0, -1.0,0, 0,0);
   
    CMTime totalDuration =kCMTimeZero;
    for (int i =0; i < videosPathArray.count; i++) {
        AVURLAsset *asset = [AVURLAssetassetWithURL:[NSURLfileURLWithPath:videosPathArray]];

        NSError *erroraudio =nil;
        //获取AVAsset中的音频或者视频
        AVAssetTrack *assetAudioTrack = [[assettracksWithMediaType:AVMediaTypeAudio]firstObject];
        
        
        
        //向通道内加入音频或者视频
        [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                            ofTrack:assetAudioTrack
                             atTime:totalDuration
                              error:&erroraudio];
        
//        NSLog(@"erroraudio:%@",erroraudio);
        NSError *errorVideo =nil;
        AVAssetTrack *assetVideoTrack = [[assettracksWithMediaType:AVMediaTypeVideo]firstObject];
        [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                            ofTrack:assetVideoTrack
                             atTime:totalDuration
                              error:&errorVideo];
        
//        NSLog(@"errorVideo:%@",errorVideo);
        totalDuration = CMTimeAdd(totalDuration, asset.duration);
    }
   
    NSURL *mergeFileURL = [NSURLfileURLWithPathutpath];
    AVAssetExportSession *exporter = [[AVAssetExportSessionalloc] initWithAsset:mixComposition
                                                                     presetName:AVAssetExportPresetMediumQuality];
    exporter.outputURL = mergeFileURL;
    exporter.outputFileType =AVFileTypeQuickTimeMovie;
    exporter.shouldOptimizeForNetworkUse =YES;
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        
        if (exporter.error !=nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [MBProgressHUDhideHUDForView:self.view];
               
                [MBProgressHUDshowSuccess:@"合并失败"];
            });
            NSLog(@"合并失败");
            
        }else{
            
            dispatch_async(dispatch_get_main_queue(), ^{
                [MBProgressHUDhideHUDForView:self.view];
               
                [MBProgressHUDshowSuccess:@"合并成功"];
            });
            
            NSLog(@"合并成功");
        }
        //保存到相册
//        UISaveVideoAtPathToSavedPhotosAlbum([mergeFileURL path], nil, nil, nil);
        
    }];
}

//路径
- (NSString *)videoPath {
    NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)firstObject];
    NSString *moviePath = [basePathstringByAppendingPathComponent:[NSStringstringWithFormat:@"qqq%@.mov",[NSDatedate]]];
    return moviePath;
}

DEMO 直接下载:
录制视频.zip (970.56 KB, 下载次数: 221, 售价: 10 金钱)
我来说两句
*滑动验证:
所有评论(7)
半吱湮 2016-7-21 08:38:50
感谢分享,Code4App有你更精彩
回复
王颖博 2016-7-21 08:44:54
强烈支持楼主ing……
回复
别隆采圆盘 2016-7-21 10:45:15
感谢分享,Code4App有你更精彩
回复
zhangfei2015 2016-7-22 11:30:44
确实不错,代码简介明了,能把知识点写的很明白
回复
_interface 2016-7-22 13:28:29
感谢分享,Code4App有你更精彩
回复
hujifenggg 2016-7-30 17:15:30
不错感谢分享,Code4App有你更精彩
回复
yinxuejun 2017-8-14 17:28:42
感谢分享,Code4App有你更精彩
回复
2551 2 0
联系我们
首页/微信公众账号投稿

帖子代码编辑/版权问题

QQ:435399051,742864542


代码贡献英雄榜
用户名 下载数
通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

快速回复 返回顶部 返回列表