Swiftで動画を撮りたい
Swiftで動画をとってUIImageViewに表示するプログラムを作成しました。しかしCameraUtil
のimageFromSampleBuffer
の1行目でunexpectedly found nil
エラーが出てしまいます。
どのようにすればoutputからUIImageを取得することができるのでしょうか。
ViewController.swift
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")
}
})
}
}
CameraUtil.swift
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
}
}
ちなみに以下のサイトを参考にしています。
http://giveitashot.hatenadiary.jp/entry/2014/10/19/190505
http://qiita.com/koki_h/items/91d9bf918df7c5788ffc