2013-04-05 27 views
9

Tôi đang cố gắng nhúng chế độ xem đơn giản trong ứng dụng iPhone của mình để chụp nhanh nhanh. Mọi thứ hoạt động tốt nhưng tôi đang đối mặt với một số vấn đề với thời gian khởi động của máy ảnh. Trong một dự án mẫu của Apple, -startRunning của AVCaptureSession không được thực thi trên luồng chính, những gì có vẻ là cần thiết. Tôi đang thiết lập phiên chụp trong quá trình khởi tạo của khung nhìn cũng như bắt đầu nó trong một chuỗi riêng biệt. Bây giờ tôi thêm AVCaptureVideoPreviewLayer vào -didMoveToSuperview. Mọi thứ đều tốt mà không có đa luồng (giao diện người dùng bị chặn trong khoảng một giây) nhưng với giao diện người dùng GCD đôi khi hoạt động, đôi khi phải mất quá nhiều thời gian để giao diện người dùng 'hủy cố định' hoặc bản xem trước được hiển thị.Làm thế nào để tránh chặn giao diện người dùng khi sử dụng camera iPhone thông qua AVFoundation?

Làm cách nào để xử lý sự chậm trễ khởi động của máy ảnh một cách đáng tin cậy mà không chặn luồng chính (bản thân độ trễ không phải là vấn đề)?

Tôi hy vọng các bạn hiểu vấn đề của tôi: D

Cảm ơn bạn trước!

BTW: Đây là proof-of-concept-dự án (không GCD) Tôi bây giờ tái sử dụng cho các ứng dụng khác của tôi: http://github.com/dariolass/QuickShotView

Trả lời

10

Vì vậy, tôi figured it out bởi bản thân mình. Mã này làm việc cho tôi và tạo ra tình trạng đóng băng UI nhất:

- (void)willMoveToSuperview:(UIView *)newSuperview { 
    //capture session setup 
    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:self.rearCamera error:nil]; 
    AVCaptureStillImageOutput *newStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: 
          AVVideoCodecJPEG, AVVideoCodecKey, 
          nil]; 
    [newStillImageOutput setOutputSettings:outputSettings]; 

    AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init]; 

    if ([newCaptureSession canAddInput:newVideoInput]) { 
     [newCaptureSession addInput:newVideoInput]; 
    } 

    if ([newCaptureSession canAddOutput:newStillImageOutput]) { 
     [newCaptureSession addOutput:newStillImageOutput]; 
     self.stillImageOutput = newStillImageOutput; 
     self.captureSession = newCaptureSession; 
    } 
    // -startRunning will only return when the session started (-> the camera is then ready) 
    dispatch_queue_t layerQ = dispatch_queue_create("layerQ", NULL); 
    dispatch_async(layerQ, ^{ 
     [self.captureSession startRunning]; 
     AVCaptureVideoPreviewLayer *prevLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession]; 
      prevLayer.frame = self.previewLayerFrame; 
      prevLayer.masksToBounds = YES; 
      prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
      prevLayer.cornerRadius = PREVIEW_LAYER_EDGE_RADIUS; 
     //to make sure were not modifying the UI on a thread other than the main thread, use dispatch_async w/ dispatch_get_main_queue 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self.layer insertSublayer:prevLayer atIndex:0]; 
     }); 
    }); 
} 
+0

Cảm ơn! Chìa khóa cho tôi đã thực hiện 'startRunning' của' AVCaptureSession' và 'stopRunning' trên một chuỗi nền. – the4kman

-1

Tôi nghĩ một cách khác để tránh là bạn có thể đặt bạn "bắt đầu camera" mã trong viewDidAppear, thay vì đặt chúng trong viewWillAppear.

+0

Điều này không giải quyết được vấn đề của một hàm tốn kém đang được thực thi trên chuỗi chính. Bạn vẫn có thể thực hiện điều này sớm (ví dụ, trong 'viewWillAppear') và không chặn các luồng chính –

Các vấn đề liên quan