2013-04-05 19 views
9

簡単なスナップショットを撮るために私のiPhoneアプリケーションにシンプルなビューを埋め込もうとしています。すべて正常に動作しますが、私はカメラの起動時にいくつかの問題に直面しています。 AppleのサンプルプロジェクトでAVCaptureSessionの-startRunningがメインスレッドで実行されていない場合は、何が必要なのでしょうか。ビューの初期化中にキャプチャセッションをセットアップすると同時に、別のスレッドでキャプチャセッションを開始します。今度はAVCaptureVideoPreviewLayer-didMoveToSuperviewに追加します。マルチスレッド(UIは約1秒間ブロックされます)がなくても問題ありませんが、GCDではUIが動作することがあります。UIが「アンフリーズ」するか、プレビューを表示するには時間がかかりすぎることがあります。AVFoundation経由でiPhoneカメラを使用しているときにUIをブロックしないようにするにはどうすればよいですか?

メインスレッド(遅延自体は問題ではありません)をブロックすることなく、信頼性の高い方法でカメラの起動遅延を処理するにはどうすればよいですか?

私は君たちが私の問題を理解してほしい:事前にD

ありがとう!ところで

は:ここで私は今、別のアプリを再利用しています私の概念実証プロジェクト(GCDなし)です:http://github.com/dariolass/QuickShotView

答えて

10

だから私は自分でそれを考え出しました。このコードは、私の作品と少なくともUI凍結生成:

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

ありがとうございます!私のための鍵はバックグラウンドスレッドで 'AVCaptureSession'の' startRunning'と 'stopRunning'を実行していました。 – the4kman

-1

は私が回避するための別の方法は、あなたの代わりにviewWillAppearでそれらを置くこと、viewDidAppearであなたの「カメラを起動し、」コードを置くことができるということだと思いますが。

+0

これは、メインスレッドで実行されている高価な機能の問題には対処していません。これを早期に実行することができます(つまり、 'viewWillAppear'で)、メインスレッドをブロックしません –

関連する問題