AVCaptureSession 获得与 iPhone 内置摄像头相同的设置
Posted
技术标签:
【中文标题】AVCaptureSession 获得与 iPhone 内置摄像头相同的设置【英文标题】:AVCaptureSession get same settings as built in iPhone camera 【发布时间】:2018-07-25 00:23:06 【问题描述】:我已经坚持了很长一段时间了。当我使用 iPhone 上的内置相机应用程序录制时,似乎有一个缩放因子。但是,当我在我的应用程序中使用 AVCaptureSession 时,我似乎无法获得相同的结果。这是我正在谈论的一个例子。顶部是从 iPhone 相机应用程序录制的,底部是使用 AVCaptureSession 在我的应用程序内录制的。这就像发生了鱼眼效应。我的相机设置代码如下。
- (void)configureCameraSession
_captureSession = [AVCaptureSession new];
[_captureSession beginConfiguration];
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if(!_device)
[self noValidCamera];
return;
AVCaptureDeviceFormat *currentFormat;
int frameRate = 60;
for (AVCaptureDeviceFormat *format in _device.formats)
NSArray *ranges = format.videoSupportedFrameRateRanges;
AVFrameRateRange *frameRates = ranges[0];
//CMVideoFormatDescriptionGet
int resolutionWidth = CMVideoFormatDescriptionGetDimensions(format.formatDescription).width;
if(frameRates.maxFrameRate > 59 && resolutionWidth >= 1920)
CameraFormat *cformat = [[CameraFormat alloc] init];
cformat.format = format;
cformat.fps = 60;
if(frameRates.maxFrameRate > 119)
cformat.fps = 120;
if(frameRates.maxFrameRate > 239)
cformat.fps = 240;
NSString *resolution;
if(resolutionWidth > 1920)
resolution = @"4K ";
else
resolution = [[NSNumber numberWithInt:CMVideoFormatDescriptionGetDimensions(format.formatDescription).height] stringValue];
resolution = [resolution stringByAppendingString:@"p "];
//stringValue];
NSString *fps = [[NSNumber numberWithInt:cformat.fps] stringValue];
fps = [fps stringByAppendingString:@" FPS"];
cformat.label = [resolution stringByAppendingString:fps];
BOOL isUniqueFormat = YES;
for(int i = 0; i < [_formatList count]; i++)
if([_formatList[i].label isEqualToString:cformat.label])
isUniqueFormat = NO;
break;
if(isUniqueFormat)
[_formatList addObject:cformat];
frameRate = cformat.fps;
currentFormat = cformat.format;
if(!currentFormat)
[self noValidCamera];
return;
_currentCameraFormat = _analysisViewController.currentCameraFormat;
if(_currentCameraFormat.fps == 0)
_currentCameraFormatIndex = 0;
_currentCameraFormat = _formatList[_currentCameraFormatIndex];
_analysisViewController.currentCameraFormat = _currentCameraFormat;
currentFormat = _currentCameraFormat.format;
frameRate = _currentCameraFormat.fps;
else
currentFormat = _currentCameraFormat.format;
frameRate = _currentCameraFormat.fps;
NSString *resolution;
if(CMVideoFormatDescriptionGetDimensions(currentFormat.formatDescription).width > 1920)
resolution = @"4K ";
else
resolution = [[NSNumber numberWithInt:CMVideoFormatDescriptionGetDimensions(currentFormat.formatDescription).height] stringValue];
resolution = [resolution stringByAppendingString:@"p "];
NSString *fps = [[NSNumber numberWithInt:frameRate] stringValue];
fps = [fps stringByAppendingString:@" FPS ▼"];
[self.videoLabelButton setTitle:[resolution stringByAppendingString:fps] forState:UIControlStateNormal];
[_device lockForConfiguration:nil];
_device.activeFormat = currentFormat;
_device.activeVideoMinFrameDuration = CMTimeMake(1, frameRate);
_device.activeVideoMaxFrameDuration = CMTimeMake(1, frameRate);
[_device unlockForConfiguration];
//Input
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];
[_captureSession addInput:input];
//Output
_movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
if([_captureSession canAddOutput:_movieFileOutput])
[_captureSession addOutput:_movieFileOutput];
[self setMovieOutputOrientation];
//Preview Layer
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
_previewView = [[UIView alloc] initWithFrame:self.imageView.bounds];
[self addFocusToView:_previewView];
[_previewView addSubview:self.imageView];
_previewLayer.frame = _previewView.bounds;
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[_previewView.layer addSublayer:_previewLayer];
_previewLayer.connection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];
AVCaptureVideoStabilizationMode stabilizationMode = AVCaptureVideoStabilizationModeCinematic;
if ([_device.activeFormat isVideoStabilizationModeSupported:stabilizationMode])
[_previewLayer.connection setPreferredVideoStabilizationMode:stabilizationMode];
[self.view addSubview:_previewView];
[self.view addSubview:self.topInfoBar];
[self.view addSubview:self.recordButton];
[self.view addSubview:self.doneButton];
[_captureSession commitConfiguration];
[_captureSession startRunning];
【问题讨论】:
【参考方案1】:好吧,我终于想通了。问题是在某些格式上支持视频稳定,所以如果可以的话,Apple 会使用它。问题是我没有在可以的时候打开它。基本上检查该选项是否可用于设备的活动格式并将其打开自动。
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [_movieFileOutput connections])
for ( AVCaptureInputPort *port in [connection inputPorts])
if ([[port mediaType] isEqual:AVMediaTypeVideo])
videoConnection = connection;
if([videoConnection isVideoOrientationSupported])
[videoConnection setVideoOrientation:[self videoOrientationFromCurrentDeviceOrientation]];
//Check if we can use video stabilization and if so then set it to auto
if (videoConnection.supportsVideoStabilization)
videoConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
【讨论】:
以上是关于AVCaptureSession 获得与 iPhone 内置摄像头相同的设置的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 iOS 中的 AVCaptureSession v AVAudioSession 冲突?
如何记录使用 AVCaptureSession 捕获的第一个和最后一个电影帧的确切时间?
iOS 相机 AVCaptureSession 在纵向与横向大小或分辨率