2017-01-23 48 views
2

私たちは結果を出すことなくかなりの時間を費やして、ここでそれを聞くことにしました。Swift 3でAVCaptureVideoDataOutputを使用してビデオを録画する

AVCaptureVideoDataOutputを使用して、カメラのライブビデオのピクセルデータを取得し、captureOutput機能で使用しています。しかし、我々はまた、そのデータを使用してビデオを記録したい。さらに、このビデオ録画が、AVCaptureMovieFileOutputで作られた録画されたビデオほど圧縮されているのだろうかと思う。

AVCaptureMovieFileOutputを使用して問題なく録音したことをお知らせします。しかし、AVCaptureMovieFileOutputAVCaptureVideoDataOutputは同時に動作しません。

下記のcaptureOutput機能があります。

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 

    let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! 

    CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 

    let baseAddress    = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0) 
    let bytesPerRow    = CVPixelBufferGetBytesPerRow(imageBuffer) 
     videoWidth    = CVPixelBufferGetWidth(imageBuffer) 
     videoHeight    = CVPixelBufferGetHeight(imageBuffer) 
    let colorSpace    = CGColorSpaceCreateDeviceRGB() 

    var bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue) 

    let context = CGContext(data: baseAddress, width: videoWidth, height: videoHeight, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) 

    let imageRef = context!.makeImage() 

    CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 

    let data = imageRef!.dataProvider!.data as! NSData 
    let pixels = data.bytes.assumingMemoryBound(to: UInt8.self) 


    /* Because what we are doing with pixel data irrelevant to the question we omitted the rest of the code to make it simple */ 




} 

答えて

1

ライブビデオの基本的な分析を行うためにピクセル情報を取得したときに、私はビデオを記録する方法を見つけました。

最初に私はAVAssetWriterを設定し、実際の記録順序を与える前にその関数を呼び出します。

var sampleBufferGlobal : CMSampleBuffer? 
let writerFileName = "tempVideoAsset.mov" 
var presentationTime : CMTime! 
var outputSettings = [String: Any]() 
var videoWriterInput: AVAssetWriterInput! 
var assetWriter: AVAssetWriter! 


func setupAssetWriter() { 

    eraseFile(fileToErase: writerFileName) 

    presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBufferGlobal!) 

    outputSettings = [AVVideoCodecKey : AVVideoCodecH264, 
         AVVideoWidthKey : NSNumber(value: Float(videoWidth)), 
         AVVideoHeightKey : NSNumber(value: Float(videoHeight))] as [String : Any] 

    videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: outputSettings) 


    assetWriter = try? AVAssetWriter(outputURL: createFileURL(writerFileName), fileType: AVFileTypeQuickTimeMovie) 

    assetWriter.add(videoWriterInput) 

} 

は私が記録を作るために他の機能を書いて、私は同じ機能で、sampleBufferGlobal、sampleBufferGlobal = sampleBufferにsampleBufferをコピーした後の記録を作るためにcaptureOutput機能でその関数を呼び出しました。

func writeVideoFromData() { 

    if assetWriter?.status == AVAssetWriterStatus.unknown { 

     if ((assetWriter?.startWriting) != nil) { 

      assetWriter?.startWriting() 
      assetWriter?.startSession(atSourceTime: presentationTime) 

     } 
    } 



     if assetWriter?.status == AVAssetWriterStatus.writing { 

      if (videoWriterInput.isReadyForMoreMediaData == true) { 


       if videoWriterInput.append(sampleBufferGlobal!) == false { 

        print(" we have a problem writing video") 

       } 
      } 
     }   
    } 

次に、以下の機能を使用して録音を停止しました。

func stopAssetWriter() { 

    videoWriterInput.markAsFinished() 

    assetWriter?.finishWriting(completionHandler: { 


     if (self.assetWriter?.status == AVAssetWriterStatus.failed) { 

      print("creating movie file is failed ") 

     } else { 

      print(" creating movie file was a success ") 

      DispatchQueue.main.async(execute: {() -> Void in 




      }) 

     } 

    }) 

} 
関連する問題