Vision Frameworkを使って動画解析をするための前準備として、動画ファイルから毎フレームを抽出し、UIImageViewへ描画するにはどうしたら良いのか。Appleのサンプルコードを勉強し、ミニマム実装をしてみました。
このコードのキモは、AVAssetReaderTrackOutputクラスのcopyNextSampleBuffer()メソッドを利用し、CVPixelBufferオブジェクトを得て、UIImageへ描画することです。
func nextFrame() -> CVPixelBuffer? {
guard let sampleBuffer = self.videoAssetReaderOutput.copyNextSampleBuffer() else {
return nil
}
return CMSampleBufferGetImageBuffer(sampleBuffer)
}
while loop内で nextFrame == true を満たす場合にフレームの抽出を続け、
while true {
guard let frame = videoReader.nextFrame() else {
break
}
// Draw results
delegate?.displayFrame(frame, withAffineTransform: videoReader.affineTransform)
usleep(useconds_t(videoReader.frameRateInSeconds))
}
得たframe: CVPixelBufferをdelegateメソッドに送り、ViewController内のUIImageViewに描画します。
func displayFrame(_ frame: CVPixelBuffer?, withAffineTransform transform: CGAffineTransform) {
DispatchQueue.main.async {
if let frame = frame {
let ciImage = CIImage(cvPixelBuffer: frame).transformed(by: transform)
let uiImage = UIImage(ciImage: ciImage)
self.imageView.image = uiImage
}
}
}