You can control the timing of each sample you append to your AVAssetWriterInput
directly with CMSampleBufferCreateCopyWithNewTiming
.
You need to adjust the timing in the CMSampleTimingInfo
you provide.
Retrieve current timing info with CMSampleBufferGetOutputSampleTimingInfoArray
and just go over the duration of each sample and calculate the correct duration to get 12 frames per second and adjust presentation and decode timestamps to match this new duration.
You then make your copy and feed it to your writer's input.
Let's say you have existingSampleBuffer
:
CMSampleBufferRef sampleBufferToWrite = NULL;
CMSampleTimingInfo sampleTimingInfo = {0};
CMSampleBufferGetSampleTimingInfo(existingSampleBuffer, 0, &sampleTimingInfo);
// modify duration & presentationTimeStamp
sampleTimingInfo.duration = CMTimeMake(1, 12) // or whatever frame rate you desire
sampleTimingInfo.presentationTimeStamp = CMTimeAdd(previousPresentationTimeStamp, sampleTimingInfo.duration);
previousPresentationTimeStamp = sampleTimingInfo.presentationTimeStamp; // should be initialised before passing here the first time
OSStatus status = CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, existingSampleBuffer, 1, &sampleTimingInfo, &sampleBufferToWrite);
if (status == noErr) {
// you can write sampleBufferToWrite
}
I'm making some assumptions in this code:
- SampleBuffer contains only one sample
- SampleBuffer contains uncompressed video (otherwise, you need to handle decodeTimeStamp as well)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…