Reputation: 1
I do video recording with AVCaptureVideoDataOutputSampleBufferDelegate and function func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) I use AVAssetWriter to save the received CMSampleBuffers as videos to the generated url. I need to let users see the continuously updated recorded video capacity. I accumulated the CMSampleBuffer to display with the calculateSampleBufferSize function but the results are not accurate. Does anyone know how to calculate it correctly from the CMSampleBuffer? Thank you.
Here is the code I implemented
func writeBufferVideoToFile(assetWriter: AVAssetWriter,
sampleBuffer: CMSampleBuffer) {
guard isRecoding else {
return
}
// Setup start record
if assetWriter.status == .unknown {
totalBytesWritten = 0
assetWriter.startWriting()
assetWriter.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(sampleBuffer))
}
// Record data
if let assetWriterInput = assetWriter.currentInput,
assetWriterInput.isReadyForMoreMediaData {
// Calculate the total number of bytes written
totalBytesWritten += Double(calculateSampleBufferSize(sampleBuffer: sampleBuffer))
// Record
assetWriterInput.append(sampleBuffer)
}
}
func calculateSampleBufferSize(sampleBuffer: CMSampleBuffer) -> Int {
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return 0
}
CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
let size = CVPixelBufferGetDataSize(imageBuffer)
CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
return size
}
Upvotes: 0
Views: 65
Reputation: 299345
You're currently computing the size of the raw, uncompressed image buffer. This is almost certainly not what you're writing. Generally your AVAssetWriter is configured to write to a compressed container (such as a QuickTime or MPEG-4). You appear to want the size of that final data.
To get that final output data, implement a AVAssetWriterDelegate and assign it as the delegate
. That object will be called every time there is output data to write. You can check its size there.
I cannot remember immediately if the delegate is used when you use one of the URL-based init
. If it isn't, you'll need to use the non-URL init
, and have your delegate write the file itself, for example by using FileHandle.
Upvotes: 0