2016-08-08 13 views
0

ich ein seltsames Problem haben,AVCaptureSession mit Automatische Anordnung

in meiner app ich einen Hintergrund laufen Videos (über AVCaptureSession) und die Anwendung ist für iPhone-Geräte so braucht es mehrere Bildschirme über automatischen Layout passen. Das Problem ist, wenn ich die Sitzung in ViewDidLoad die Frames immer noch nicht festgelegt und wenn ich die Sitzung in viewDidLayoutSubviews die Sitzung beendet zu starten und die Anwendung abstürzt.

Hier ist mein AVCaptureSession-Code

- (void)setupAVCapture { 
    //Capture session 
    _session = nil; 
    _session = [[AVCaptureSession alloc] init]; 
    [_session setSessionPreset:AVCaptureSessionPresetLow]; 

    //Get the camera and set the capture device 
    AVCaptureDevice *inputDevice = [self getCamera:_camera]; // self.camera 

    //Capture device input 
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:nil]; 
    if ([_session canAddInput:deviceInput]) 
     [_session addInput:deviceInput]; 

    //Capture Still Image Output 
    stillImageOutput = nil; 
    stillImageOutput = [AVCaptureStillImageOutput new]; 
    [stillImageOutput addObserver:self forKeyPath:@"capturingStillImage" options:NSKeyValueObservingOptionNew context:(__bridge void *)(AVCaptureStillImageIsCapturingStillImageContext)]; 
    if ([_session canAddOutput:stillImageOutput]) 
    { 
     [_session addOutput:stillImageOutput]; 
    } 

    //Capture Video Data Output 
    videoDataOutput = nil; 
    videoDataOutput = [AVCaptureVideoDataOutput new]; 

    NSDictionary *rgbOutputSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCMPixelFormat_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 
    [videoDataOutput setVideoSettings:rgbOutputSettings]; 
    [videoDataOutput setAlwaysDiscardsLateVideoFrames:YES]; 

    videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL); 
    [videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue]; 

    if ([_session canAddOutput:videoDataOutput]) 
    { 
     [_session addOutput:videoDataOutput]; 
    } 

    [[videoDataOutput connectionWithMediaType:AVMediaTypeVideo] setEnabled:NO]; 

    //preview view 
    self.previewLayer = nil; 
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_session]; 
    [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 

    CALayer *rootLayer = [_previewView layer]; 
    [rootLayer setMasksToBounds:YES]; 
    [[[self previewLayer]connection]setVideoOrientation:AVCaptureVideoOrientationPortrait]; 
    //[self.previewLayer setTransform:CATransform3DMakeAffineTransform(CGAffineTransformMakeRotation(-M_PI/2))]; 
    [self.previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height)]; 
    [rootLayer insertSublayer:self.previewLayer atIndex:0]; 

    //go 
    [_session startRunning]; 

    AVCaptureDevicePosition desiredPosition = [[self getCamera:_camera] position];//AVCaptureDevicePositionFront; 

    for (AVCaptureDevice *captureDevice in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) 
    { 
     if ([captureDevice position] == desiredPosition) 
     { 
      [[_previewLayer session] beginConfiguration]; 
      AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil]; 

      for (AVCaptureInput *oldInput in [[_previewLayer session] inputs]) 
      { 
       [[_previewLayer session] removeInput:oldInput]; 
      } 

      [[_previewLayer session] addInput:input]; 
      [[_previewLayer session] commitConfiguration]; 
      break; 
     } 
    } 
} 

Antwort

0

Ahah, das ist komisch, ich habe gestern durch diese Frage kam, mit dem gleichen Absturz. Also eigentlich, auch wenn es nicht so aussieht, führen Sie diesen Code im Hintergrund. Sie sollten klar sagen, dass Sie Schichten auf dem Haupt-Thread hinzufügen möchten, vor allem diese drei Codezeilen:

[self.previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height)]; 
    [rootLayer insertSublayer:self.previewLayer atIndex:0]; 
    [_session startRunning]; 

diese stattdessen tun:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height)]; 
    [rootLayer insertSublayer:self.previewLayer atIndex:0]; 
    [_session startRunning]; 
}); 

Hope this helfen;)

+0

I immer noch malloc: *** Fehler für Objekt 0x17004e820: Ungültiger Zeiger von der freien Liste aus Warteschlange *** einen Haltepunkt in malloc_error_break zu debuggen – OXXY

+0

ok so versuchen Sie, die Sitzung in ViewDidAppear zu sehen, ob es aus dem Layout kommt – RomOne

+0

Es scheint, dass das Problem von XCode 8.0 Beta 4 verursacht, baute ich ein Projekt auf XCode 7.3.1 und es funktioniert gut – OXXY

Verwandte Themen