4

我正在使用AVFoundation来捕获和录制音频。有一些问题我不太明白。如何为AVWriter书写设置CMSampleBuffer的时间戳

基本上我想从AVCaptureSession捕获音频并使用AVWriter编写,但是我需要在从AVCaptureSession获取的CMSampleBuffer的时间戳中进行一些转换。我阅读了CMSampleBuffer的文档,我看到两个不同的时间戳:'演示时间戳'和'输出演示时间戳'。两者有什么不同?

假设我从AVCaptureSession获得一个CMSampleBuffer(用于音频)实例,并且我想用AVWriter将它写入一个文件,我应该使用什么函数将CMTime“注入”缓冲区以设置演示文稿它在生成的文件中的时间戳?

谢谢。

回答

6

使用CMSampleBufferGetPresentationTimeStamp,这是捕获缓冲区的时间,应在播放时同步播放时呈现。在WWDC 2012上引用会话520:“演示时间是缓冲区中的第一个样本被麦克风拾取的时间”。

如果启动AVWriter与

[videoWriter startWriting]; 
[videoWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; 

然后追加样品

if(videoWriterInput.readyForMoreMediaData) [videoWriterInput appendSampleBuffer:sampleBuffer]; 

在完成视频帧将与CMSampleBufferGetPresentationTimeStamp是一致的(我已签)。如果要修改时添加样品时,你必须使用AVAssetWriterInputPixelBufferAdaptor

+0

为什么当你对答案不感兴趣时​​,你会问一个问题? – Sten 2013-02-14 11:17:17

+0

我需要设置CMSampleBuffer的时间戳,因为我想暂时记录会话。我结束了使用CMSampleBufferCreateCopyWithNewTiming。我想知道是否有直接的方法来注入现有缓冲区的时间戳,所以我不需要复制它。 – 2013-02-17 10:52:07

+2

我无法使用AVAssetWriterInputPixelBufferAdaptor,因为它只适用于视频流。 – 2013-02-17 14:14:18

6

块的示例代码从这里:http://www.gdcl.co.uk/2013/02/20/iPhone-Pause.html CMSampleBufferRef样品 - 是您sampleBuffer,CMSampleBufferRef SOUT你的输出。 NewTimeStamp是你的时间戳。

CMItemCount count; 
CMTime newTimeStamp = CMTimeMake(YOURTIME_GOES_HERE); 
CMSampleBufferGetSampleTimingInfoArray(sample, 0, nil, &count); 
CMSampleTimingInfo* pInfo = malloc(sizeof(CMSampleTimingInfo) * count); 
CMSampleBufferGetSampleTimingInfoArray(sample, count, pInfo, &count); 
for (CMItemCount i = 0; i < count; i++) 
{ 
    pInfo[i].decodeTimeStamp = newTimeStamp; // kCMTimeInvalid if in sequence 
    pInfo[i].presentationTimeStamp = newTimeStamp; 

} 
CMSampleBufferRef sout; 
CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, sample, count, pInfo, &sout); 
free(pInfo);