Запуск сеанса AVcapture медленный после перезапуска сеанса
У меня есть главный контроллер представления и он переходит к второму контроллеру представления, который имеет avcapturesession. В первый раз, когда я перехожу от главного контроллера представления к контроллеру сеанса захвата, он занимает около 50 мс (проверяется с помощью "инструментов" ). Затем я перехожу обратно к контроллеру главного представления из сеанса захвата, а затем обратно к контроллеру avcapturesession от главного контроллера. Каждый раз, когда требуется больше времени, чтобы перейти от главного контроллера к avcapturesession, и к 5-й или 6-й итерации, segue занимает около 10 секунд. (По сравнению с 50ms в первый раз.) Я вставил соответствующий код для сессии avcapture ниже. Может ли кто-нибудь помочь в решении этого? Благодаря
Этот класс (типа NSObject) управляет сеансом захвата для второго контроллера представления
что фактически реализует avcapturesession
#import "CaptureSessionManager.h"
@implementation CaptureSessionManager
@synthesize captureSession;
@synthesize previewLayer;
#pragma mark Capture Session Configuration
- (id)init {
if ((self = [super init])) {
[self setCaptureSession:[[AVCaptureSession alloc] init]];
}
return self;
}
- (void)addVideoPreviewLayer {
[self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
[[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];
}
- (void)addVideoInput {
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (videoDevice) {
NSError *error;
AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (!error) {
if ([[self captureSession] canAddInput:videoIn])
[[self captureSession] addInput:videoIn];
//else
// NSLog(@"Couldn't add video input");
}
// else
// NSLog(@"Couldn't create video input");
}
//else
// NSLog(@"Couldn't create video capture device");
}
- (void)dealloc {
[[self captureSession] stopRunning];
[previewLayer release], previewLayer = nil;
[captureSession release], captureSession = nil;
[super dealloc];
}
@end
В методе viewdidLoad контроллера представления avcapture используется следующее:
[self setCaptureManager:[[CaptureSessionManager alloc] init]];
[[self captureManager] addVideoInput];
[[self captureManager] addVideoPreviewLayer];
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),
CGRectGetMidY(layerRect))];
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];
[[captureManager captureSession] startRunning];
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:YES];
[[[self captureManager] previewLayer]removeFromSuperlayer];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[captureManager captureSession] stopRunning];
});
}
![Memory allocation]()
Ответы
Ответ 1
Я столкнулся с той же проблемой, я обнаружил, что эта строка является основной проблемой
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];
Просто удалите предварительный слой из суперслоя при освобождении памяти и проблемы с памятью. Моя функция deallocating следующая:
-(void)deallocSession
{
[captureVideoPreviewLayer removeFromSuperlayer];
for(AVCaptureInput *input1 in session.inputs) {
[session removeInput:input1];
}
for(AVCaptureOutput *output1 in session.outputs) {
[session removeOutput:output1];
}
[session stopRunning];
session=nil;
outputSettings=nil;
device=nil;
input=nil;
captureVideoPreviewLayer=nil;
stillImageOutput=nil;
self.vImagePreview=nil;
}
Я вызывал эту функцию перед тем, как выскочить и нажать любое другое представление. Он решил мою проблему.
Ответ 2
Удаление сеансовых входов и выходов, похоже, решает эту проблему для меня
[captureSession stopRunning];
for(AVCaptureInput *input in captureSession.inputs) {
[captureSession removeInput:input];
}
for(AVCaptureOutput *output in captureSession.outputs) {
[captureSession removeOutput:output];
}
Ответ 3
SWIFT 2.2 версия TUNER88 ответ
func stopRecording(){
captureSession.stopRunning()
for input in captureSession.inputs{
captureSession.removeInput(input as! AVCaptureInput)
}
for output in captureSession.outputs{
captureSession.removeOutput(output as! AVCaptureOutput)
}
}
Ответ 4
Кажется, вы не удаляете файл предварительного просмотра в avcaptureViewController, который будет содержать ссылку на сеанс захвата внутри. Убедитесь, что вы удалите файл предварительного просмотра из этой иерархии представлений.
Ответ 5
вот быстрая версия ответа TUNER88
session.stopRunning()
for(var i = 0 ; i < session.inputs.count ; i++){
session.removeInput(session.inputs[i] as! AVCaptureInput)
}
for(var i = 0 ; i < session.outputs.count ; i++){
session.removeOutput(session.outputs[i] as! AVCaptureOutput)
}
Ответ 6
Swift 3
let session = AVCaptureSession()
if let outputMovie = outputMovie, outputMovie.isRecording {
outputMovie.stopRecording()
}
self.session.stopRunning()
if let inputs = self.session.inputs as? [AVCaptureDeviceInput] {
for input in inputs {
self.session.removeInput(input)
}
}
if let outputs = self.session.outputs as? [AVCaptureOutput] {
for output in outputs {
self.session.removeOutput(output)
}
}