初始化相机
//AVCaptureSessionPreset1280x720 相机分辨率
//AVCaptureDevicePositionBack 后置摄像头
//AVCaptureDevicePositionFront 前置摄像头
//GPUImageVideoCamera用于录制视频,采集数据
videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1280x720 cameraPosition:AVCaptureDevicePositionBack];
//Alan 为了在AVCaptureDevice上设置硬件属性,比如focusMode和exposureMode,客户端必须首先获取设备上的锁。
if ([videoCamera.inputCamera lockForConfiguration:nil]) {
//自动对焦
if ([videoCamera.inputCamera isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
[videoCamera.inputCamera setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
}
//自动曝光
if ([videoCamera.inputCamera isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
[videoCamera.inputCamera setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}
//自动白平衡
if ([videoCamera.inputCamera isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
[videoCamera.inputCamera setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
}
//Alan 解锁设备,提交配置
[videoCamera.inputCamera unlockForConfiguration];
}
_position = CameraManagerDevicePositionBack;
//竖屏方向采集数据
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
//录制的时候添加声音,添加输入源和输出源会暂时会使录制暂时卡住,所以在要使用声音的情况下要先调用该方法来防止录制被卡住。
[videoCamera addAudioInputsAndOutputs];
//前置不是镜像,后置是镜像
videoCamera.horizontallyMirrorFrontFacingCamera = YES;
videoCamera.horizontallyMirrorRearFacingCamera = NO;
//先添加一个空的滤镜
filter = [[LFGPUImageEmptyFilter alloc] init];
//用于显示视频的GPUImageView
filteredVideoView = [[GPUImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[videoCamera addTarget:filter];
[filter addTarget:filteredVideoView];
给相机设置UI
timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 27.0, 80, 26.0)];
timeLabel.font = [UIFont systemFontOfSize:13.0f];
timeLabel.text = @"录制 00:00";
timeLabel.textAlignment = NSTextAlignmentCenter;
timeLabel.backgroundColor = [UIColor colorWithRed:253/256.0 green:91/256.0 blue:73/256.0 alpha:1];
timeLabel.textColor = [UIColor whiteColor];
[filteredVideoView addSubview:timeLabel];
// [[AppDelegate appDelegate].cmImageSize setLabelsRounded:timeLabel cornerRadiusValue:2 borderWidthValue:0 borderColorWidthValue:[UIColor clearColor]];
timeLabel.hidden = YES;
_btView = [[UIView alloc]initWithFrame:CGRectMake(SCREEN_WIDTH/2 - 36.5, SCREEN_HEIGHT - 125, 73, 73)];
[_btView makeCornerRadius:36.5 borderColor:nil borderWidth:0];
_btView.backgroundColor = [UIColor colorWithRed:(float)0xfe/256.0 green:(float)0x65/256.0 blue:(float)0x53/256.0 alpha:1];
[filteredVideoView addSubview:_btView];
_photoCaptureButton = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2 - 31.5, SCREEN_HEIGHT- 120, 63, 63)];
_photoCaptureButton.backgroundColor = [UIColor colorWithRed:(float)0xfe/256.0 green:(float)0x65/256.0 blue:(float)0x53/256.0 alpha:1];
[_photoCaptureButton addTarget:self action:@selector(startRecording:) forControlEvents:UIControlEventTouchUpInside];
[_photoCaptureButton makeCornerRadius:31.5 borderColor:[UIColor blackColor] borderWidth:1.5];
[filteredVideoView addSubview:_photoCaptureButton];
_camerafilterChangeButton = [[UIButton alloc] init];
_camerafilterChangeButton.frame = CGRectMake(SCREEN_WIDTH - 160, 25, 30.0, 30.0);
UIImage* img = [UIImage imageNamed:@"beautyOFF"];
[_camerafilterChangeButton setImage:img forState:UIControlStateNormal];
[_camerafilterChangeButton setImage:[UIImage imageNamed:@"beautyON"] forState:UIControlStateSelected];
[_camerafilterChangeButton addTarget:self action:@selector(changebeautifyFilterBtn:) forControlEvents:UIControlEventTouchUpInside];
[filteredVideoView addSubview:_camerafilterChangeButton];
UIButton* backBtn = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH - 60, 25, 30, 30)];
[backBtn setImage:[UIImage imageNamed:@"BackToHome"] forState:UIControlStateNormal];
[backBtn addTarget:self action:@selector(clickBackToHome) forControlEvents:UIControlEventTouchUpInside];
[filteredVideoView addSubview:backBtn];
_cameraPositionChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH - 110, 25, 30, 30)];
UIImage* img2 = [UIImage imageNamed:@"cammera"];
[_cameraPositionChangeButton setImage:img2 forState:UIControlStateNormal];
[_cameraPositionChangeButton addTarget:self action:@selector(changeCameraPositionBtn:) forControlEvents:UIControlEventTouchUpInside];
[filteredVideoView addSubview:_cameraPositionChangeButton];
_cameraChangeButton = [[UIButton alloc] init];
_cameraChangeButton.hidden = YES;
_cameraChangeButton.frame = CGRectMake(SCREEN_WIDTH - 100 , SCREEN_HEIGHT - 105.0, 52.6, 50.0);
UIImage* img3 = [UIImage imageNamed:@"complete"];
[_cameraChangeButton setImage:img3 forState:UIControlStateNormal];
[_cameraChangeButton addTarget:self action:@selector(stopRecording:) forControlEvents:UIControlEventTouchUpInside];
[filteredVideoView addSubview:_cameraChangeButton];
_dleButton = [[UIButton alloc] init];
_dleButton.hidden = YES;
_dleButton.frame = CGRectMake( 50 , SCREEN_HEIGHT - 105.0, 50, 50.0);
UIImage* img4 = [UIImage imageNamed:@"del"];
[_dleButton setImage:img4 forState:UIControlStateNormal];
[_dleButton addTarget:self action:@selector(clickDleBtn:) forControlEvents:UIControlEventTouchUpInside];
[filteredVideoView addSubview:_dleButton];
_inputLocalVieoBtn = [[UIButton alloc] init];
// _inputLocalVieoBtn.hidden = YES;
_inputLocalVieoBtn.frame = CGRectMake( 50 , SCREEN_HEIGHT - 105.0, 50, 50.0);
UIImage* img5 = [UIImage imageNamed:@"record_ico_input_1"];
[_inputLocalVieoBtn setImage:img5 forState:UIControlStateNormal];
[_inputLocalVieoBtn addTarget:self action:@selector(clickInputBtn:) forControlEvents:UIControlEventTouchUpInside];
[filteredVideoView addSubview:_inputLocalVieoBtn];
progressPreView = [[UIView alloc]initWithFrame:CGRectMake(0, SCREEN_HEIGHT -4 , 0, 4)];
progressPreView.backgroundColor = UIColorFromRGB(0xffc738);
[progressPreView makeCornerRadius:2 borderColor:nil borderWidth:0];
[filteredVideoView addSubview:progressPreView];
给相机设置点击聚焦
-(void)cameraViewTapAction:(UITapGestureRecognizer *)tgr
{
//识别为手势触摸
if (tgr.state == UIGestureRecognizerStateRecognized && (_focusLayer == nil || _focusLayer.hidden)) {
CGPoint location = [tgr locationInView:filteredVideoView];
[self setfocusImage];
[self layerAnimationWithPoint:location];
AVCaptureDevice *device = videoCamera.inputCamera;
CGPoint pointOfInterest = [self convertToPointOfInterestFromViewCoordinates:location];
NSError *error;
//需要先锁定,防止其他线程访问
if ([device lockForConfiguration:&error]) {
//判断是否支持控制对焦
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
[device setFocusPointOfInterest:pointOfInterest];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
}
if([device isExposurePointOfInterestSupported] && [device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure])
{
[device setExposurePointOfInterest:pointOfInterest];
[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}
//操作完成后,记得进行unlock。
[device unlockForConfiguration];
NSLog(@"FOCUS OK");
} else {
NSLog(@"ERROR = %@", error);
}
}
}
- (void)layerAnimationWithPoint:(CGPoint)point {
if (_focusLayer) {
CALayer *focusLayer = _focusLayer;
focusLayer.hidden = NO;
[CATransaction begin];
[CATransaction setDisableActions:YES];
[focusLayer setPosition:point];
focusLayer.transform = CATransform3DMakeScale(2.0f,2.0f,1.0f);
[CATransaction commit];
CABasicAnimation *animation = [ CABasicAnimation animationWithKeyPath: @"transform" ];
//CATransform3DMakeScale (CGFloat sx, CGFloat sy,CGFloat sz),用来表示针对X(sx)轴,Y(sy)轴,Z(sz)轴的3D比例缩放,
animation.toValue = [ NSValue valueWithCATransform3D: CATransform3DMakeScale(1.0f,1.0f,1.0f)];
// animation.delegate = self;
animation.duration = 0.3f;
animation.repeatCount = 1;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[focusLayer addAnimation: animation forKey:@"animation"];
// 0.5秒钟延时
[self performSelector:@selector(focusLayerNormal) withObject:self afterDelay:0.5f];
}
}
相机切换和解除美颜
if (!sender.selected) {
//开启美颜
sender.selected = YES;
[videoCamera removeAllTargets];
filter = [[GPUImageBeautifyFilter alloc] init];
[videoCamera addTarget:filter];
[filter addTarget:filteredVideoView];
}else
{
//关闭美颜
sender.selected = NO;
[videoCamera removeAllTargets];
filter = [[LFGPUImageEmptyFilter alloc] init];
[videoCamera addTarget:filter];
[filter addTarget:filteredVideoView];
}
开启摄像头
//开启摄像头
[videoCamera startCameraCapture];
开始录制
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(720.0, 1280.0)];//GPUImageMovieWriter 保存滤镜处理过的视频
movieWriter.isNeedBreakAudioWhiter = YES;//GPUImageMovieWriter添加的新属性
movieWriter.encodingLiveVideo = YES;
movieWriter.shouldPassthroughAudio = YES;//是否使用声音
[filter addTarget:movieWriter];
videoCamera.audioEncodingTarget = movieWriter;//加入声音
[movieWriter startRecording];
暂停录制,也就是实现断点续拍,就是把视频先保存起来,并将视频地址保存在数组中,最后结束录制的时候取出数组中的所有视频
[movieWriter finishRecording];
[filter removeTarget:movieWriter];
[urlArray addObject:[NSURL URLWithString:[NSString stringWithFormat:@"file://%@",pathToMovie]]];
_isRecoding = NO;
在下一篇视频导出中会有将断开的视频整合到一起,实现断点续拍的讲解。
地址:https://blog.csdn.net/weixin_42433480/article/details/90109873