最近一顿疯狂加班啊,年前一顿加,写了好几个版本的更新。然而到现在都没有上线,真蛋疼。
回归正题啊,通过学习本章的内容,你将学会本章内容。
##一 、第一步当然还是绘制一个界面,很简单一个view 一个录制按钮
导入几个头文件和遵守几个协议 #import <AVFoundation/AVFoundation.h> #import "RAFileManager.h" //这是个操作文件的工具类 不多做介绍 #import <AssetsLibrary/AssetsLibrary.h> //这货iOS8过期了。。。 PHPhoto看起来比这个好用多了
遵守一个协议
//这玩意必须遵守不然拿不到视频哦复制代码
##二、初始化相机硬件等 这个步骤跟拍照的步骤大部分是一样的,两处区别 : ####1、输出不一样:拍照部分用的是AVCaptureStillImageOutput,视频录制需要的是AVCaptureMovieFileOutput ####2、输入硬件不一样:拍照只需要摄像头捕捉影像的输入,视频录制的话还需要一个音频的输入(毕竟咱们这AV是有声的哈)。
创建如下属性
@property (nonatomic) dispatch_queue_t sessionQueue; /**复制代码
* AVCaptureSession对象来执行输入设备和输出设备之间的数据传递 / @property (nonatomic, strong) AVCaptureSession session; /** * 视频输入设备 / @property (nonatomic, strong) AVCaptureDeviceInput videoInput; /** * 声音输入 / @property (nonatomic, strong) AVCaptureDeviceInput audioInput; /** * 视频输出流 / @property(nonatomic,strong)AVCaptureMovieFileOutput movieFileOutput; / * 预览图层 / @property (nonatomic, strong) AVCaptureVideoPreviewLayer previewLayer; /** * 记录录制时间 / @property (nonatomic, strong) NSTimer timer;
什么?这些属性都是干啥的?猛戳这里--->
之后初始化相机,连接硬件和软件。
- (void)initAVCaptureSession{复制代码
self.session = [[AVCaptureSession alloc] init]; //这里根据需要设置 可以设置4K self.session.sessionPreset = AVCaptureSessionPreset1280x720; NSError *error; AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //更改这个设置的时候必须先锁定设备,修改完后再解锁,否则崩溃 [device lockForConfiguration:nil]; //设置闪光灯为自动 [device setFlashMode:AVCaptureFlashModeAuto]; [device unlockForConfiguration]; self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error]; self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio] error:nil]; if (error) { NSLog(@"%@",error); }
self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; if ([self.session canAddInput:self.videoInput]) { [self.session addInput:self.videoInput]; } if ([self.session canAddInput:self.audioInput]) { [self.session addInput:self.audioInput]; } if ([self.session canAddOutput:self.movieFileOutput]) { [self.session addOutput:self.movieFileOutput]; } //初始化预览图层 self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; self.previewLayer.frame = CGRectMake(0, 0,KMainScreenW, KMainScreenH); self.backView.layer.masksToBounds = YES; [self.backView.layer insertSublayer:self.previewLayer atIndex:0]; }记得在viewDidLoad里面调用一下。viewWillAppear里面开启session ,viewWillDisappear里面关闭session
相机开启了一定要关闭,相机开启了一定要关闭,相机开启了一定要关闭,重要的事情说三遍
##三、开启录制方法和结束录制方法 - (void)startVideoRecorder{ AVCaptureConnection *movieConnection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo]; AVCaptureVideoOrientation avcaptureOrientation = AVCaptureVideoOrientationPortrait; [movieConnection setVideoOrientation:avcaptureOrientation]; [movieConnection setVideoScaleAndCropFactor:1.0]; NSURL *url = [[RAFileManager defaultManager] filePathUrlWithUrl:[self getVideoSaveFilePathString]];
if (![self.movieFileOutput isRecording]) { [self.movieFileOutput startRecordingToOutputFileURL:url recordingDelegate:self];
}
}- (void)stopVideoRecorder{复制代码
if ([self.movieFileOutput isRecording]) {复制代码
[self.movieFileOutput stopRecording]; }
}##四、最后写个按钮点击开始录制调用上面方法就好并且实现delegate。注意判断是否有使用相机,麦克风的权限。如果没有权限,你还刚好没判断。。。那么恭喜你。。崩溃了。
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{ //判断最小时间的哈复制代码
if (CMTimeGetSeconds(captureOutput.recordedDuration) < VIDEO_RECORDER_MIN_TIME) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"视频时间过短" message:nil delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; return; } NSLog(@"%s-- url = %@ ,recode = %f , int %lld kb", func, outputFileURL, CMTimeGetSeconds(captureOutput.recordedDuration), captureOutput.recordedFileSize / 1024); ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init]; [lib writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) { }]; }
向相册写入视频的时候也要注意权限。
######DLC:
获取视频截图的方法
- (UIImage *)videoSnap:(NSString *)videoPath{复制代码
NSURL *url = [NSURL fileURLWithPath:videoPath]; AVAsset *asset = [AVAsset assetWithURL:url]; AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset]; CMTime snaptime = CMTimeMake(10, 10); CMTime time2; CGImageRef cgImageRef = [generator copyCGImageAtTime:snaptime actualTime:&time2 error:nil]; UIImage *tempImage = [UIImage imageWithCGImage:cgImageRef]; //这里取完图片记得搞下图片的方向,在这里我就不写了。 return tempImage; }
这个方法第一个时间是指的图片创建的时间, 第二个actualTime 是指向图片正式生成时间的指针,实际生成时间这个参数可以传NULL,如果你不关心它是什么时候诞生的。 但是第一个时间不能传入空,必须告诉它你要在哪一个时间点生成一张截图 - (nullable CGImageRef)copyCGImageAtTime:(CMTime)requestedTime actualTime:(nullable CMTime *)actualTime error:(NSError * __nullable * __nullable)outError CF_RETURNS_RETAINED;
获取到截图之后记得处理下方向。
最后: ######1、硬件之间关系介绍戳这里 ######2、文章演示demo戳这里 ######文章演示demo戳这里 ######文章演示demo戳这里 重要的事情还是要说三遍,虽然写的不怎么样,如果你们要用还是希望能仔细看一看,别上来就私聊 留言要demo。
######3、要转载的看官们也不要问了,注明出处就行了。随便转。 ######4、文章有什么问题请留言指出,欢迎交流。