10

我正在使用 AVFoundation 来捕获和录制音频。有些问题我不是很明白。

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

假设我从 AVCaptureSession 获得了一个 CMSampleBuffer(用于音频)实例,并且我想使用 AVWriter 将其写入文件,我应该使用什么函数将 CMTime“注入”到缓冲区以便设置它的呈现时间戳结果文件?

谢谢。

4

2 回答 2

6

来自此处的示例代码块:http : //www.gdcl.co.uk/2013/02/20/iPhone-Pause.html CMSampleBufferRef 示例 - 是您的 sampleBuffer,CMSampleBufferRef 是您的输出。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);
于 2013-03-02T06:06:17.803 回答
6

使用 CMSampleBufferGetPresentationTimeStamp,即缓冲区被捕获的时间,应在回放时“呈现”以保持同步。引用 WWDC 2012 的第 520 场会议:“演示时间是麦克风拾取缓冲区中第一个样本的时间”。

如果你启动 AVWriter

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

然后附加样本

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

完成视频中的帧将与 CMSampleBufferGetPresentationTimeStamp 一致(我已经检查过)。如果要修改添加样本的时间,则必须使用 AVAssetWriterInputPixelBufferAdaptor

于 2013-02-09T17:08:13.923 回答