- 拍照
//
// CHRecordPhoto.m
// SCCAProofSdk
//
// Created by cyptt on 2022/3/16.
//
#import "CHRecordPhoto.h"
#import "CHCameraUitl.h"
#import
@interface CHRecordPhoto ()<CAAnimationDelegate>
/*
预览view
*/
@property(nonatomic,strong)AVCaptureVideoPreviewLayer * previewLayer;
/**
如果提供则使用外部提供的,否则使用sdk内部的 视频路径
*/
@property (atomic, strong) NSString *pubFilePath;
@property(nonatomic,strong)void(^successBlock) (NSURL* filePath);
@property(nonatomic,strong)void(^failBlock) (NSError * error);
@property(nonatomic,strong)AVCaptureSession * session; //回话
@property(nonatomic,strong)AVCaptureDevice * audioDevice; //添加音频、话筒
@property (strong, nonatomic) AVCaptureDeviceInput *backCameraInput;//后置摄像头输入
@property (strong, nonatomic) AVCaptureDeviceInput *frontCameraInput;//前置摄像头输入
@property(nonatomic,strong)AVCaptureStillImageOutput * imageOutput; //输出设备信息
@property(nonatomic,strong)AVCaptureConnection * captureConnection;
@property(nonatomic,strong)NSString * privateVideoPath;
@property(nonatomic,assign)BOOL isBackCamera; //当前是否是后置 yes 是后置
@end
@implementation CHRecordPhoto
-(void)startPreView:(AVCaptureVideoPreviewLayer *)preViewLayer{
_previewLayer= preViewLayer;
preViewLayer.session=self.session;
[self.session startRunning];
}
-(void)startRecordFilePath:(nullableNSString*)filePathisSaveAblum:(BOOL)isSaveAblumsuccessBlock:(void(^_Nonnull)(NSURL* filePath))successBlockfailBlock:(void(^_Nonnull)(NSError* error))failBlock;{
_successBlock= successBlock;
_failBlock= failBlock;
self.pubFilePath= filePath;
NSString* outputFielPath = [selfgetPrivateVideoPath];
NSURL*fileUrl=[NSURLfileURLWithPath:outputFielPath];
NSLog(@"进来 了----- 0001");
if ([self.session canAddConnection:self.captureConnection]) {
[self.session addConnection:self.captureConnection];
}
if (self.captureConnection.isVideoOrientationSupported) {
NSLog(@"支持");
}
if (self.captureConnection.enabled) {
[self.imageOutput captureStillImageAsynchronouslyFromConnection:self.captureConnection completionHandler:^(CMSampleBufferRef _Nullable imageDataSampleBuffer, NSError * _Nullable error) {
if(imageDataSampleBuffer ==NULL) {
return;
}
NSData*imageData = [AVCaptureStillImageOutputjpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage*image = [[UIImagealloc]initWithData:imageData];
BOOLisSaveSuccess = [imageDatawriteToURL:fileUrlatomically:YES];
if(isSaveSuccess) {
if(successBlock) {
successBlock(fileUrl);
}
}else{
NSError* error = [[NSErroralloc]initWithDomain:@"保存图片失败"code:302userInfo:nil];
if(failBlock) {
failBlock(error);
}
}
if(isSaveAblum) {
dispatch_queue_tqueue =dispatch_queue_create("com.ch.camera.queue",NULL);
dispatch_async(queue, ^{
UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);
});
}
}];
}else{
NSError* error = [NSErrorerrorWithDomain:@"获取捕捉失败"code:7003userInfo:nil];
if(failBlock) {
failBlock(error);
}
}
}
-(void)stop{
[self.session stopRunning];
}
/*
开启闪光灯
*/
-(void)openFlashSuccessBlock:(void(^_Nonnull)(BOOLisSuccess))successBlockfailBlock:(void(^_Nonnull)(NSString* errMsg))failBlock{
NSLog(@"开起frash");
if (!self.isBackCamera) {
NSLog(@"当前是前置摄像头");
if(failBlock) {
failBlock(@"当前是前置摄像头");
}
return;
}
AVCaptureDevice*backCamera = [selfbackCamera];
if (backCamera.torchMode == AVCaptureTorchModeOff) {
[backCameralockForConfiguration:nil];
backCamera.torchMode = AVCaptureTorchModeOn;
backCamera.flashMode = AVCaptureFlashModeOn;
[backCameraunlockForConfiguration];
if(successBlock) {
successBlock(YES);
}
}
}
/*
关闭闪光灯
*/
-(void)closeFlash{
AVCaptureDevice*backCamera = [selfbackCamera];
if (backCamera.torchMode == AVCaptureTorchModeOn) {
[backCameralockForConfiguration:nil];
backCamera.torchMode = AVCaptureTorchModeOff;
backCamera.flashMode = AVCaptureFlashModeOff;
[backCameraunlockForConfiguration];
}
NSLog(@"关闭frash");
}
-(AVCaptureSession *)getSession{
return self.session;
}
-(void)transferCapture{
[self changeCameraInputDeviceisFront:self.isBackCamera];
self.isBackCamera = !self.isBackCamera;
}
//切换前后摄像头 yes 后置
- (void)changeCameraInputDeviceisFront:(BOOL)isBack{
if(isBack) {
[self.session beginConfiguration];
[self.session removeInput:self.backCameraInput];
if ([self.session canAddInput:self.frontCameraInput]) {
[self changeCameraAnimation];
[self.session addInput:self.frontCameraInput];
[self.session commitConfiguration];
}
}else{
[self.session beginConfiguration];
[self.session removeInput:self.frontCameraInput];
if ([self.session canAddInput:self.backCameraInput]) {
[self changeCameraAnimation];
[self.session addInput:self.backCameraInput];
[self.session commitConfiguration];
}
}
//完成后需要重新设置视频输出连接
self.captureConnection = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
}
/**
获取文件路径
*/
-(NSString *)getPrivateVideoPath{
NSString*defultPath = [CHCameraUitlgetVideoPathCache];
NSString*outputFielPath=[defultPathstringByAppendingPathComponent:[CHCameraUitlgetVideoNameWithType:@"jpg"]];
if (self.pubFilePath) {
self.privateVideoPath = self.pubFilePath;
}else{
self.privateVideoPath= outputFielPath;
}
NSLog(@"视频保存地址%@",self.privateVideoPath);
return self.privateVideoPath;
}
//用来返回是前置摄像头还是后置摄像头
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position {
//返回和视频录制相关的所有默认设备
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
//遍历这些设备返回跟position相关的设备
for(AVCaptureDevice*deviceindevices) {
if([deviceposition] == position) {
returndevice;
}
}
return nil;
}
#pragma mark- 切换动画
- (void)changeCameraAnimation {
CATransition*changeAnimation = [CATransitionanimation];
changeAnimation.delegate=self;
changeAnimation.duration=0.45;
changeAnimation.type=@"oglFlip";
changeAnimation.subtype = kCATransitionFromRight;
changeAnimation.timingFunction = UIViewAnimationCurveEaseInOut;
[self.previewLayeraddAnimation:changeAnimationforKey:@"changeAnimation"];
}
- (void)animationDidStart:(CAAnimation *)anim {
// self.captureConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
// [self.session startRunning];
}
/*
初始化会话
*/
-(AVCaptureSession *)session{
if(!_session) {
_session= [[AVCaptureSessionalloc]init];
[_session setSessionPreset:AVCaptureSessionPreset1280x720];
//视频输入对象
if (self.backCameraInput) {
[_session addInput:self.backCameraInput];
}
//将设备输出添加到会话中
if ([_session canAddOutput:self.imageOutput]) {
[_session addOutput:self.imageOutput];
}
if ([self.captureConnection isVideoStabilizationSupported]) {
self.captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
}
}
return _session;
}
#pragma mark- 视频相关
//返回前置摄像头
- (AVCaptureDevice *)frontCamera {
return [self cameraWithPosition:AVCaptureDevicePositionFront];
}
//返回后置摄像头
- (AVCaptureDevice *)backCamera {
return [self cameraWithPosition:AVCaptureDevicePositionBack];
}
/*
添加音频、话筒
*/
-(AVCaptureDevice *)audioDevice{
if (!_audioDevice) {
_audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio ];
}
return _audioDevice;
}
//后置摄像头输入
- (AVCaptureDeviceInput *)backCameraInput {
if (_backCameraInput == nil) {
NSError*error;
self.isBackCamera=YES;//默认后置
_backCameraInput= [[AVCaptureDeviceInputalloc]initWithDevice:[selfbackCamera]error:&error];
if(error) {
NSLog(@"获取后置摄像头失败~");
}
}
return _backCameraInput;
}
//前置摄像头输入
- (AVCaptureDeviceInput *)frontCameraInput {
if (_frontCameraInput == nil) {
NSError*error;
_frontCameraInput= [[AVCaptureDeviceInputalloc]initWithDevice:[selffrontCamera]error:&error];
if(error) {
NSLog(@"获取前置摄像头失败~");
}
}
return _frontCameraInput;
}
/*
输出设备信息
*/
-(AVCaptureStillImageOutput *)imageOutput{
if (!_imageOutput) {
_imageOutput = [[AVCaptureStillImageOutput alloc]init];
_imageOutput.outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
}
return _imageOutput;
}
-(AVCaptureConnection *)captureConnection{
if (!_captureConnection) {
//设置录制模式
_captureConnection = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
//捕捉连接
}
return _captureConnection;
}
@end
地址 https://gitee.com/Cyptt/ch-record-camera.git