17

我有一个主视图控制器,它连接到具有 avcapturesession 的第二个视图控制器。我第一次从主视图控制器到捕获会话控制器时,大约需要 50 毫秒(使用“仪器”检查)。然后我从捕获会话回到主视图控制器,然后从主控制器回到 avcapturesession 控制器。每次从主视图控制器到 avcapturesession 需要更长的时间,到第 5 次或第 6 次迭代时,segue 大约需要 10 秒。(与第一次为 50 毫秒相比。)我在下面粘贴了 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

以下是在avcapture视图控制器的viewdidLoad方法中:

[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];
    });

}

内存分配

4

7 回答 7

11

我遇到了同样的问题我发现这条线是主要问题

[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];

只需在释放时从超级层中删除预览层,就不会出现内存问题。我的释放功能如下

 -(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;

}

我在弹出和推送任何其他视图之前调用了这个函数。它解决了我的问题。

于 2013-12-11T06:44:50.620 回答
5

删除会话输入和输出似乎为我解决了这个问题

[captureSession stopRunning];
for(AVCaptureInput *input in captureSession.inputs) {
    [captureSession removeInput:input];
}

for(AVCaptureOutput *output in captureSession.outputs) {
    [captureSession removeOutput:output];
}
于 2013-11-28T16:04:37.360 回答
3

对我有用的是将previewLayerof 类型设置AVCaptureVideoPreviewLayer()为弱变量,然后在stopCaptureSession()我拥有的函数中:

func stopCaptureSession() {
    self.previewLayer?.removeFromSuperlayer()
    self.previewLayer = nil
    self.captureSession.stopRunning()
    for input in captureSession.inputs {
        self.captureSession.removeInput(input)
    }
    for output in captureSession.outputs {
        self.captureSession.removeOutput(output)
    }
}

原来我所有的问题都与previewLayer有关

于 2018-09-11T15:28:44.497 回答
2

Swift 版本 TUNER88 的答案

func stopRecording() {
    captureSession.stopRunning()
    for input in captureSession.inputs {
        captureSession.removeInput(input)
    }
    for output in captureSession.outputs {
        captureSession.removeOutput(output)
    }
}
于 2016-04-11T16:46:17.270 回答
0

您似乎没有删除 avcaptureViewController 中的 previewLayer,这将在内部保留对捕获会话的引用。确保从该视图层次结构中删除 previewLayer。

于 2013-10-16T18:17:08.300 回答
0

斯威夫特 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)
        }
    }
于 2017-05-24T10:01:41.743 回答
-1

这是 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)

    }
于 2016-02-16T12:24:26.337 回答