28744


Swiftで動画をとってUIImageViewに表示するプログラムを作成しました。しかし`CameraUtil`の`imageFromSampleBuffer`の1行目で`unexpectedly
found nil`エラーが出てしまいます。

どのようにすればoutputからUIImageを取得することができるのでしょうか。

**ViewController.swift**

[code]

    import UIKit
    import AVFoundation
    
    class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    
        @IBOutlet weak var imageView: UIImageView!
    
        var session : AVCaptureSession!
        var device: AVCaptureDevice!
        var output: AVCaptureVideoDataOutput!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            if self.initCamera(){
                self.session.startRunning()
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func initCamera() -> Bool{
            self.session = AVCaptureSession()
            self.session.sessionPreset = AVCaptureSessionPresetMedium
    
            let devices = AVCaptureDevice.devices()
    
            for device in devices{
                if(device.position == AVCaptureDevicePosition.Back){
                    self.device = device as! AVCaptureDevice
                }
            }
            if self.device == nil{
                return false
            }
    
            let input: AVCaptureDeviceInput
            do{
                input = try AVCaptureDeviceInput(device: self.device) as AVCaptureDeviceInput
            }catch{
                return false
            }
    
            if self.session.canAddInput(input){
                self.session.addInput(input)
            }else{
                return false
            }
    
            self.output = AVCaptureVideoDataOutput()
            self.output.videoSettings = [ kCVPixelBufferPixelFormatTypeKey: Int(kCVPixelFormatType_32BGRA)]
    
            do{
                try self.device.lockForConfiguration()
                self.device.activeVideoMinFrameDuration = CMTimeMake(1, 15)
                self.device.unlockForConfiguration()
            }catch{
                return false
            }
    
            let queue: dispatch_queue_t = dispatch_queue_create("myqueue", nil)
            self.output.setSampleBufferDelegate(self, queue: queue)
    
            self.output.alwaysDiscardsLateVideoFrames = true
    
            if self.session.canAddOutput(self.output){
                self.session.addOutput(self.output)
            }else{
                return false
            }
    
            for connection in self.output.connections{
                if let conn = connection as? AVCaptureConnection{
                    if conn.supportsVideoOrientation{
                        conn.videoOrientation = AVCaptureVideoOrientation.Portrait
                    }
                }
            }
            return true
        }
    
        func captureOutput(captureOutput: AVCaptureOutput!, didDropSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
            dispatch_async(dispatch_get_main_queue(), {
                if sampleBuffer != nil{
                   self.imageView.image = CameraUtil.imageFromSampleBuffer(sampleBuffer)
                }else{
                    print("sample buffer is nil")
                }
    
            })
        }
    
    
    }
    
[/code]

**CameraUtil.swift**

[code]

    import Foundation
    import UIKit
    import AVFoundation
    
    class CameraUtil {
        class func imageFromSampleBuffer(sampleBuffer: CMSampleBuffer)->UIImage{
            // サンプルバッファからピクセルバッファを取り出す
            let pixelBuffer:CVImageBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
    
            // ピクセルバッファをベースにCoreImageのCIImageオブジェクトを作成
            let ciImage = CIImage(CVPixelBuffer: pixelBuffer)
    
            //CIImageからCGImageを作成
            let pixelBufferWidth = CGFloat(CVPixelBufferGetWidth(pixelBuffer))
            let pixelBufferHeight = CGFloat(CVPixelBufferGetHeight(pixelBuffer))
            let imageRect:CGRect = CGRectMake(0,0,pixelBufferWidth, pixelBufferHeight)
            let ciContext = CIContext.init()
            let cgimage = ciContext.createCGImage(ciImage, fromRect: imageRect )
    
            // CGImageからUIImageを作成
            let image = UIImage(CGImage: cgimage)
            return image
        }
    }
    
[/code]

ちなみに以下のサイトを参考にしています。

<http://giveitashot.hatenadiary.jp/entry/2014/10/19/190505>  
<http://qiita.com/koki_h/items/91d9bf918df7c5788ffc>


CC BY-SA 3.0
2016-09-07T06:43:16.660
28738
2016-09-07T12:18:32.720
7232
question
swift ios
Swiftで動画を撮りたい


あなたがリンクに挙げられている記事中では、`captureOutput(_:didDropSampleBuffer:fromConnection:)`メソッドは使ってないようです。

[`-
captureOutput:didDropSampleBuffer:fromConnection:`](https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVCaptureVideoDataOutputSampleBufferDelegate_Protocol/#//apple_ref/occ/intfm/AVCaptureVideoDataOutputSampleBufferDelegate/captureOutput:didDropSampleBuffer:fromConnection:)

> _sampleBuffer_
>
> A `CMSampleBuffer` object containing information about the dropped frame,
> such as its format and presentation time..
>
> **This sample buffer contains none of the original video data.**

(太字部) **このサンプルバッファーは元のビデオデータを含んでいません。**

リンクに挙げられたサイト同様に`captureOutput(_:didOutputSampleBuffer:fromConnection:)`の方を使ってみるべきではないでしょうか?

[code]

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
        dispatch_async(dispatch_get_main_queue(), {
            if sampleBuffer != nil{
               self.imageView.image = CameraUtil.imageFromSampleBuffer(sampleBuffer)
            }else{
                print("sample buffer is nil")
            }
    
        })
    }
    
[/code]


CC BY-SA 3.0
2016-09-07T10:40:54.780
28744
2016-09-07T12:18:32.720
2020-06-17T08:14:45.997
-1
13972
28738
answer