// // CameraManager.m // PanoramicCameraSDK // // Created by 王昭威 on 2023/1/14. // #import "CameraManager.h" @interface CameraManager () @property (nonatomic, assign) CGFloat backAspect; @property (nonatomic, assign) CGFloat frontAspect; @end @implementation CameraManager @synthesize front = _front; @synthesize back = _back; - (void)setResolutionFor:(AVCaptureDevicePosition)position with: (NSInteger)desiredWidth{ AVCaptureDevice* device = [self cameraWithPosition:position]; if(device == nil){ return; } NSArray *supportedFormats = device.formats; AVCaptureDeviceFormat *bestFormat; CGFloat aspect = 1; // CMTime maxFrameDuration; // float maxSeconds = 15; // AVFrameRateRange *bestFrameRateRange = nil;// for (AVCaptureDeviceFormat *format in supportedFormats) { CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions((CMVideoFormatDescriptionRef)[format formatDescription]); //分辨率 if (dimensions.width <= desiredWidth) { if(dimensions.height > 0) aspect = (CGFloat)dimensions.width / dimensions.height; bestFormat = format; } } [device lockForConfiguration:nil]; [device setActiveFormat:bestFormat]; [device setActiveVideoMaxFrameDuration:CMTimeMake(1, 10)]; [device setActiveVideoMinFrameDuration:CMTimeMake(1, 10)]; [device unlockForConfiguration]; if(device.position == AVCaptureDevicePositionFront){ self.frontAspect = aspect; } else if(device.position == AVCaptureDevicePositionBack){ self.backAspect = aspect; } } - (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position { NSArray *devices = nil; if(@available(iOS 10, *)){ AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:position]; devices = [captureDeviceDiscoverySession devices]; } else if(@available(iOS 4, *)){ devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; } if(devices == nil){ return nil; } for (AVCaptureDevice *device in devices) { if ([device position] == position) return device; } return nil; } + (instancetype)shared{ static dispatch_once_t token; static CameraManager* instance = nil; dispatch_once(&token, ^{ instance = [[self alloc] init]; }); return instance; } - (instancetype)init{ self = [super init]; if(self){ _back = [self cameraWithPosition:AVCaptureDevicePositionBack]; _front = [self cameraWithPosition:AVCaptureDevicePositionFront]; _frontAspect = 1; _backAspect = 1; } return self; } - (void)focusOn:(CGPoint)point{ if (self.back == nil) { return; } [self focusOn:point device:self.back]; } - (void)focusOn:(CGPoint)point device:(AVCaptureDevice *)device{ NSError* error; [device lockForConfiguration:&error]; if(error != nil){ return; } if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]){ [device setFocusPointOfInterest: point]; device.focusMode = AVCaptureFocusModeContinuousAutoFocus; } if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) { [device setExposurePointOfInterest:point]; device.exposureMode = AVCaptureExposureModeContinuousAutoExposure; } [device unlockForConfiguration]; } // // //- (void)configureCamera:(AVCaptureDevice *)device forFrameRate:(int)frameRate { // AVCaptureDeviceFormat *bestFormat = nil; // AVFrameRateRange *bestFrameRateRange = nil; // for ( AVCaptureDeviceFormat *format in [device formats] ) { // for ( AVFrameRateRange *range in format.videoSupportedFrameRateRanges ) { // //NSLog(@"Format %@",format); // if ( range.maxFrameRate == frameRate ) { // bestFormat = format; // bestFrameRateRange = range; // } // } // } // // //NSLog(@"Format %@",bestFormat); // // if ( bestFormat ) { // if ( [device lockForConfiguration:NULL] == YES ) { // device.activeFormat = bestFormat; // device.activeVideoMinFrameDuration = bestFrameRateRange.minFrameDuration; // device.activeVideoMaxFrameDuration = bestFrameRateRange.minFrameDuration; // [device unlockForConfiguration]; // } // } //} // // //- (void)configureCamera{ // /// 参数设置 // // 默认后置摄像头 // AVCaptureDevicePosition position = AVCaptureDevicePositionBack; // // 帧率 // int frameRate = 25; // // 显色方案 // OSType videoFormat = kCVPixelFormatType_32BGRA; // // 分辨率高 // int resolutionHeight = 720; // // /// 创建AVCaptureSession对象 // AVCaptureSession *session = [[AVCaptureSession alloc] init]; // /// 设置分辨率 // session.sessionPreset = AVCaptureSessionPreset1280x720; // /// 获取摄像头 // AVCaptureDevice *captureDevice; // // 默认AVCaptureDevicePositionBack,后置摄像头 // AVCaptureDeviceDiscoverySession *deviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:position]; // NSArray *devices = deviceDiscoverySession.devices; // for (AVCaptureDevice *device in devices) { // if (AVCaptureDevicePositionBack == device.position) { // captureDevice = device; // }else if (AVCaptureDevicePositionFront == device.position){ // captureDevice = device; // } // } // /// 设置帧率和分辨率高度 // BOOL isSuccess = NO; // for(AVCaptureDeviceFormat *vFormat in [captureDevice formats]) { // CMFormatDescriptionRef description = vFormat.formatDescription; // float maxRate = ((AVFrameRateRange*) [vFormat.videoSupportedFrameRateRanges objectAtIndex:0]).maxFrameRate; // if (maxRate >= frameRate && CMFormatDescriptionGetMediaSubType(description) == videoFormat) { // if ([captureDevice lockForConfiguration:NULL] == YES) { // // 对比镜头支持的分辨率和当前设置的分辨率 // CMVideoDimensions dims = CMVideoFormatDescriptionGetDimensions(description); // if (dims.height == resolutionHeight && dims.width == [self.class getResolutionWidthByHeight:resolutionHeight]) { // [session beginConfiguration]; // if ([captureDevice lockForConfiguration:NULL]){ // captureDevice.activeFormat = vFormat; // [captureDevice setActiveVideoMinFrameDuration:CMTimeMake(1, frameRate)]; // [captureDevice setActiveVideoMaxFrameDuration:CMTimeMake(1, frameRate)]; // [captureDevice unlockForConfiguration]; // } // [session commitConfiguration]; // isSuccess = YES; // } // }else { // NSLog(@"%s: 失败",__func__); // } // } // } // // // // //} // /////需要考虑横竖屏情况,这里暂未考虑 //+ (int)getResolutionWidthByHeight:(int)height { // switch (height) { // case 2160: // return 3840; // case 1080: // return 1920; // case 720: // return 1280; // case 480: // return 640; // default: // return -1; // } //} @end