Можете ли вы предоставить источник / цитату?
окус не работает на первом AVCaptureSession, когда я создаю второй AVCaptureSession. Второй сеанс, который должен быть создан, - это тот, в котором работает автофокус, а первый созданный не имеет автофокусировки.
Я ожидаю, что один из сеансов сможет автоматически фокусироваться при запуске после того, как другой будет остановлен таким же образом, как автоматический баланс белого и автоэкспозиция работают для обоих сеансов. Если вы наблюдаете окно журнала с примером кода ниже, вы можете видеть поступающие сообщения наблюдения значения ключа; но никогда не изменяющееся сообщение фокуса, когда запущен верхний сеанс.
Sidenote: К сожалению, у меня есть ошибка в сторонней библиотеке, которую я использую, которая не позволяет мне просто воссоздавать сеансы полностью, когда я переключаюсь между ними (из-за утечки AVCaptureSessions, которая в конечном итоге приводит к уничтожению приложения). Вся история в том, что эта библиотека создает один из сеансов захвата для меня, у нее есть открытый API для запуска и остановки сеанса, и я хочу создать другой сеанс. Приведенный ниже код демонстрирует проблему, хотя и без использования сторонней библиотеки.
Я создал тестовое приложение с кодом, перечисленным ниже, и файлом XIB, который имеет два представления, одно над другим, и кнопку, подключенную к методу switchSessions, который демонстрирует проблему.
Это может быть связано с проблемой, описанной здесь,Фокус (автофокус) не работает в камере (AVFoundation AVCaptureSession)хотя не упоминается о двух сессиях захвата.
Заголовочный файл:
#import <UIKit/UIKit.h>
@class AVCaptureSession;
@class AVCaptureStillImageOutput;
@class AVCaptureVideoPreviewLayer;
@class AVCaptureDevice;
@class AVCaptureDeviceInput;
@interface AVCaptureSessionFocusBugViewController : UIViewController {
IBOutlet UIView *_topView;
IBOutlet UIView *_bottomView;
AVCaptureDevice *_device;
AVCaptureSession *_topSession;
AVCaptureStillImageOutput *_outputTopSession;
AVCaptureVideoPreviewLayer *_previewLayerTopSession;
AVCaptureDeviceInput *_inputTopSession;
AVCaptureSession *_bottomSession;
AVCaptureStillImageOutput *_outputBottomSession;
AVCaptureVideoPreviewLayer *_previewLayerBottomSession;
AVCaptureDeviceInput *_inputBottomSession;
}
- (IBAction)switchSessions:(id)sender;
@end
Файл реализации:
#import "AVCaptureSessionFocusBugViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface AVCaptureSessionFocusBugViewController ()
- (void)setupCaptureSession:(AVCaptureSession **)session
output:(AVCaptureStillImageOutput **)output
previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer
input:(AVCaptureDeviceInput **)input
view:(UIView *)view;
- (void)tearDownSession:(AVCaptureSession **)session
output:(AVCaptureStillImageOutput **)output
previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer
input:(AVCaptureDeviceInput **)input
view:(UIView *)view;
@end
@implementation AVCaptureSessionFocusBugViewController
- (IBAction)switchSessions:(id)sender
{
if ([_topSession isRunning]) {
[_topSession stopRunning];
[_bottomSession startRunning];
NSLog(@"Bottom session now running.");
}
else {
[_bottomSession stopRunning];
[_topSession startRunning];
NSLog(@"Top session now running.");
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(@"Observed value for key at key path %@.", keyPath);
// Enable to confirm that the focusMode is set correctly.
//NSLog(@"Autofocus for the device is set to %d.", [_device focusMode]);
}
- (void)viewDidLoad {
[super viewDidLoad];
_device = [[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] retain];
[self setupCaptureSession:&_topSession
output:&_outputTopSession
previewLayer:&_previewLayerTopSession
input:&_inputTopSession
view:_topView];
[self setupCaptureSession:&_bottomSession
output:&_outputBottomSession
previewLayer:&_previewLayerBottomSession
input:&_inputBottomSession
view:_bottomView];
// NB: We only need to observe one device, since the top and bottom sessions use the same device.
[_device addObserver:self forKeyPath:@"adjustingFocus" options:NSKeyValueObservingOptionNew context:nil];
[_device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:nil];
[_device addObserver:self forKeyPath:@"adjustingWhiteBalance" options:NSKeyValueObservingOptionNew context:nil];
[_topSession startRunning];
NSLog(@"Starting top session.");
}
- (void)setupCaptureSession:(AVCaptureSession **)session
output:(AVCaptureStillImageOutput **)output
previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer
input:(AVCaptureDeviceInput **)input
view:(UIView *)view
{
*session = [[AVCaptureSession alloc] init];
// Create the preview layer.
*previewLayer = [[AVCaptureVideoPreviewLayer layerWithSession:*session] retain];
[*previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[*previewLayer setFrame:[view bounds]];
[[view layer] addSublayer:*previewLayer];
// Configure the inputs and outputs.
[*session setSessionPreset:AVCaptureSessionPresetMedium];
NSError *error = nil;
*input = [[AVCaptureDeviceInput deviceInputWithDevice:_device error:&error] retain];
if (!*input) {
NSLog(@"Error creating input device:%@", [error localizedDescription]);
return;
}
[*session addInput:*input];
*output = [[AVCaptureStillImageOutput alloc] init];
[*session addOutput:*output];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[*output setOutputSettings:outputSettings];
[outputSettings release];
}
- (void)viewDidUnload {
[_topView release];
_topView = nil;
[_bottomView release];
_bottomView = nil;
[_device release];
_device = nil;
[self tearDownSession:&_topSession
output:&_outputTopSession
previewLayer:&_previewLayerTopSession
input:&_inputTopSession
view:_topView];
[self tearDownSession:&_bottomSession
output:&_outputBottomSession
previewLayer:&_previewLayerBottomSession
input:&_inputBottomSession
view:_bottomView];
}
- (void)tearDownSession:(AVCaptureSession **)session
output:(AVCaptureStillImageOutput **)output
previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer
input:(AVCaptureDeviceInput **)input
view:(UIView *)view
{
if ([*session isRunning]) {
[*session stopRunning];
}
[*session removeOutput:*output];
[*output release];
*output = nil;
[*session removeInput:*input];
[*input release];
*input = nil;
[*previewLayer removeFromSuperlayer];
[*previewLayer release];
*previewLayer = nil;
[*session release];
*session = nil;
}
@end