Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

AVFoundationを使ったキャプチャ機能

42,081 views

Published on

http://tomoyaonishi.hatenablog.jp/entry/2014/06/29/024010

Published in: Technology

AVFoundationを使ったキャプチャ機能

  1. 1. Capturing with AVFoundation 2014/03/12 iOS_LT #8 @Tomoya_Onishi
  2. 2. 自己紹介 • iOS開発歴約3年 • ツイート専用アプリ「FasPos」:累計5万DL • その他位置情報ログアプリなどいくつか
  3. 3. AVFoundation @import AVFoundation;
  4. 4. 音声、画像、動画 の再生や作成の細かい作業を行うための 超強力な低レベルObjective-C API
  5. 5. 今回はキャプチャ機能を かなりざっくりと
  6. 6. AVCaptureSession 入力と出力を管理する カメラ マイク 静止画 音声データ 動画 メタデータ AVCaptureDeviceInput AVCaptureDevice AVCaptureOutput …
  7. 7. AVCaptureSession • デバイスからの入力と出力を管理するクラス @property(nonatomic, copy) NSString *sessionPreset; キャプチャクオリティの調整 AVCaptureSessionPresetPhoto AVCaptureSessionPresetHigh AVCaptureSessionPresetMedium … self.session = [[AVCaptureSession alloc] init];
  8. 8. AVCaptureDevice • デバイスそのものを表現するクラス self.camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; @property(nonatomic) AVCaptureFocusMode focusMode; @property(nonatomic) CGPoint focusPointOfInterest; … @property(nonatomic, readonly) AVCaptureDevicePosition position; @property(nonatomic) AVCaptureExposureMode exposureMode; @property(nonatomic) AVCaptureWhiteBalanceMode whiteBalanceMode;
  9. 9. AVCaptureDeviceInput • 指定したデバイスをセッションに入力する時に使うクラス self.cameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:self.camera error:NULL]; [self.session addInput:self.cameraInput]; セッションにカメラが入力機器として接続された状態
  10. 10. AVCaptureOutput • AVCaptureStillImageOutput(静止画) • AVCaptureMovieFileOutput(動画) • AVCaptureVideoDataOutput(ビデオデータ) • AVCaptureAudioDataOutput(音声データ) • AVCaptureMetadataOutput(顔、QRコードなど) [self.session addOutput:self.output]; セッションへの入力を特定の方法で出力できる状態
  11. 11. AVCaptureStillImageOutput • カメラから入力されたデータを静止画として出力するクラス self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; @property(nonatomic) BOOL automaticallyEnablesStillImageStabilizationWhenAvailable                              NS_AVAILABLE_IOS(7_0) 手ぶれ補正ON [self.session addOutput:self.stillImageOutput]; 静止画のキャプチャ準備完了
  12. 12. - (void)captureStillImageAsynchronouslyFromConnection:(AVCaptureConnection *)connection                       completionHandler:        (void (^)(CMSampleBufferRef imageDataSampleBuffer, NSError *error))handler; + (NSData *)jpegStillImageNSDataRepresentation:(CMSampleBufferRef)jpegSampleBuffer; JPEG画像がNSDataで取得できる このメソッドを呼ぶと自動でシャッター音が鳴る Exifなどのメタデータも含まれる 非同期で静止画をキャプチャ CoreMediaのままではUIKitで使いづらいので変換
  13. 13. AVCaptureMovieFileOutput • 動画を簡単にキャプチャできるクラス self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; self.movieFileOutput.maxRecordedDuration = CMTimeMake(10 * 30, 30); 最大10秒キャプチャする [self.session addOutput:self.movieFileOutput]; 動画のキャプチャ準備完了
  14. 14. キャプチャ開始 [self.movieFileOutput startRecordingToOutputFileURL:self.movieURL                         recordingDelegate:self]; キャプチャ終了 self.movieFileOutput stopRecording]; - (void)captureOutput:(AVCaptureFileOutput *)captureOutput                         didStartRecordingToOutputFileAtURL:(NSURL *)fileURL                    fromConnections:(NSArray *)connections AVCaptureFileOutputRecordingDelegate - (void)captureOutput:(AVCaptureFileOutput *)captureOutput                  didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL                  fromConnections:(NSArray *)connections                         error:(NSError *)error AVCaptureFileOutputRecordingDelegate outputFileURLに動画が保存されている
  15. 15. AVCaptureVideoDataOutput • 映像の各フレームをそのまま取得できるクラス self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; self.videoDataOutput.videoSettings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) }; self.videoDataQueue =   dispatch_queue_create("jp.co.xxx.videoDataQueue", DISPATCH_QUEUE_SERIAL); [self.videoDataOutput setSampleBufferDelegate:self queue:self.videoDataQueue]; [self.session addOutput:self.videoDataOutput]; 映像フレームのキャプチャ準備完了
  16. 16. AVCaptureVideoDataOutputSampleBufferDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection sampleBufferがフレーム 1秒に何十回も呼ばれるので重い処理はしないように 各フレームの取得
  17. 17. プレビュー AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; previewLayer.frame = self.view.bounds; セッションからレイヤーを生成して画面に貼り付けるだけ 盗撮防止のため?renderInContextが効かないようになっている
  18. 18. セッションを動かす 入出力をセッションに接続した状態で呼ぶ 実際に入力データがセッションに入って、出力できるようになる [self.session startRunning]; [self.session stopRunning]; 止める
  19. 19. Tips • AVCaptureSession startRunning • AVCaptureVideoPreviewLayerの生成が遅い dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; [self.session startRunning]; ! dispatch_async(dispatch_get_main_queue(), ^{ previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; previewLayer.frame = frame; }); ! }); 非同期で
  20. 20. その他 • QRコードのキャプチャ及び生成
 AVCaptureMetadataOutput, CIFilter • 動画の再構成や画像との合成など
 AVMutableComposition, AVVideoCompositionCoreAnimationTool • 動画変換
 AVAssetExportSession • フレームから動画構築
 AVAssetWriter
  21. 21. 参考 • https://developer.apple.com/jp/devcenter/ios/library/ documentation/AVFoundationPG.pdf#search='AVFoundation' • https://developer.apple.com/library/ios/navigation/ • ヘッダーファイル

×