Запуск сеанса 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)
        }
    }