现在一个可以实现拍照时曝光、对焦,视频录制的小功能已经实现。真机上已经可以运行。已经将代码上传。
前面两篇实现了照片功能此片将要实现最后一个视频流的获取和保存,同样是保存到系统相册中。此篇说最后的一个视频流的获取和保存功能。
先讲个笑话:要不是上周我和妹妹拿错了包,我现在还是个不良少年,昨天和别人约架,兄弟们都从包里拿出了刀,棍子,而当我从包里拿出巴啦啦小魔仙的魔法棒的时候,我知道我这个大哥当不下去了。
思路
当摄像头一直捕捉图像显示到屏幕上时,开始录制操作就是开始将此事屏幕上展示的的图片转换成对应类型的媒体流文件(我们设置的类型)保存到对应的位置。自然,首选的位置就是沙盒中。当录制完成后,将文件在保存到系统相册中。苹果提供给我们一个代理,当我们停止录制时,会走一个代理方法,我们可以在此代理方法中将视频保存到系统相册中。
//获取视频流- (void)getVodioFromDevio:(NSURL *)url { AVCaptureConnection *connection = [self.videoOutpur connectionWithMediaType:AVMediaTypeVideo];//得到对应数据类型的连接器 //方向 if ([connection isVideoOrientationSupported]) { connection.videoOrientation = [self currentVideoOrientation]; } //用于优化视频质量,先判断在执行 if ([connection isVideoStabilizationSupported]) { connection.enablesVideoStabilizationWhenAvailable = YES; } //优化视频质量 if ([self.device isSmoothAutoFocusSupported]) { NSError *eroor; if ([_device lockForConfiguration:&eroor]) { self.device.smoothAutoFocusEnabled = YES; [self.device unlockForConfiguration]; }else { NSLog(@"%@",[eroor localizedDescription]); } //开始获取捕捉设备数据到对应的文件下 [self.videoOutpur startRecordingToOutputFileURL:url recordingDelegate:self]; }}
//创建保存地址//在实现此功能是会出现编号为11800的URL错误,但打印出来URL是正确的,但就是报错。解决方案是干掉重新生成一个新的,以下注释掉的代码是我第一次实现时使用的。在真机上成功过一次,但是吃了个饭回来就报错了,所以重新写了一个。- (NSURL *)saveVedioURL { NSString *documentsDirPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSURL *documentsDirUrl = [NSURL fileURLWithPath:documentsDirPath isDirectory:YES]; return [NSURL URLWithString:@"video.mov" relativeToURL:documentsDirUrl]; // // NSFileManager *manager = [NSFileManager defaultManager];// NSArray *vidoedoc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);// NSString *patch = [vidoedoc objectAtIndex:0];//// patch = [patch stringByAppendingPathComponent:@"viggjjhg.mov"];//// // if (![manager fileExistsAtPath:patch]) {// // [manager createDirectoryAtPath:patch withIntermediateDirectories:YES attributes:nil error:nil];// }// if (patch) {// // NSLog(@"url生成");// return [NSURL fileURLWithPath:patch];// } return nil;}//将视频流存储到系统相册中。此步骤在视屏拍摄完成后掉用。调用位置为在AVCaptureFileOutputRecordingDelegate系统提供的代理方法中,实现保存功能- (void)saveVideoToAssetsLibrary:(NSURL *)url { ALAssetsLibrary *libraty = [[ALAssetsLibrary alloc]init]; if ([libraty videoAtPathIsCompatibleWithSavedPhotosAlbum:url]) { ALAssetsLibraryWriteImageCompletionBlock completionBlock; completionBlock = ^(NSURL *assetURL, NSError *error) { if (error) { NSLog(@"%@",[error localizedDescription]); }else { //根据视频流第一帧图片生成一张展示图// [self generateIamgeForViodeWithURL:url]; } }; [libraty writeVideoAtPathToSavedPhotosAlbum:url completionBlock:completionBlock]; NSLog(@"保存方法"); }}
还写了一个根据视频文件生成占位图片的方法,本以为放入相册中的文件是不会自动生成首张图片作为占位图片,所以就写了一个,结果发现是自作多情了。但在此也一起罗列上,说不定以后可以用到
//根据录制视频生成一张视频的展示图- (void)generateIamgeForViodeWithURL:(NSURL *)url { dispatch_async(dispatch_get_global_queue(0, 0), ^{ //容器,根据地址获取到视频流 AVAsset *sesst = [AVAsset assetWithURL:url]; AVAssetImageGenerator * generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:sesst]; //图片大小 generator.maximumSize = CGSizeMake(100, 0.0f); generator.appliesPreferredTrackTransform = YES; //转换 CGImageRef imageRef = [generator copyCGImageAtTime:kCMTimeZero actualTime:NULL error:nil]; UIImage *image = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); dispatch_async(dispatch_get_main_queue(), ^{ //保存图片到对应位置(私有方法) [self saveImageToAssetsLibraty:image]; NSLog(@"缩略图生成"); }); });}