将appendSampleBuffer用于音频和视频时暂停AVAssetWriter会导致失步。有没有办法暂停录音?

时间:2012-08-04 00:25:25

标签: objective-c avassetwriter

我有两种方法(一种用于音频,一种用于视频),它们通过各自的AVAssetWriterInput将各自的样本附加到AVAssetWriter。一切都适用于简单的启动和停止案例。这里的一些背景是音频流来自coreAudio,我在那里应用了回声抑制,而视频输入来自AVCaptureVideoDataOutputSampleBufferDelegate,来自AVCaptureVideoDataOutput通过setSampleBufferDelegate。

问题是,当我想暂停录制,然后重新开始重新录制时,会对源的音频和视频部分发生不同的事情。到目前为止,我一直无法在暂停恢复后保持音频和视频同步。

看来,当通过appendSampleBuffera附加音频样本数据时,即使CMSampleBufferRef具有准确的时间戳,它似乎也没有“跳过”没有样本的时间段。我的意思是,当附加音频样本时,它并不关心CMSampleBuffer上的时间戳是什么......它只是不断地将样本背靠背堆积,即使有(例如)120秒音频数据中的差距,它不会为它创造一个“空白空间”。

我坦率地不在乎,只要视频样本的行为是相同的(但事实并非如此)。对于视频样本,结果视频编码会跳过样本,尽管它会在没有数据的时间段内产生延长的空视频帧。

因此,从一个简单的实现,在暂停期间,您会在暂停期间获得一个空白视频部分,但对于音频部分,您将获得下一个未暂停部分的样本背靠背。这意味着暂停和取消暂停(通过抑制向avasset写入器添加缓冲区数据)会导致音频和视频之间完全失步。

我尝试过的补救措施:

  1. 使用CMSetAttachment()设置kCMSampleBufferAttachmentKey_FillDiscontinuitiesWithSilence - 对于音频通道,希望它能像视频流那样做。这根本没有效果。我可能做错了,但是没有关于此的真实文档,所以在这个黑暗中拍摄。

  2. 在“暂停”的受影响持续时间内添加我自己的空样本(通过appendLapsedAudiotime)。问题是我不认为我的缓冲区是正确的,而且我不清楚是否可以添加一个只有0或1个样本的音频缓冲区,并在很长一段时间内将其拉长。如果我也可以将音频缓冲区格式更改为在整个暂停期间执行1个样本,但是下游低级API将不太喜欢不稳定的采样率设置。

  3. 使用CMSampleBufferCreateCopyWithNewTiming()更改视频的呈现时间,以配合音频的行为。这证明既不稳定,也没有用。我对此进行了多次迭代,包括调整音频和视频的时间戳。这可能是我在那里犯了错误,但是由于没有文件,我对这种做法也是盲目的。

  4. 使用多个startSessionAtSourceTime / endSessionAtSourceTime以及在暂停状态期间抑制写入示例,但这不起作用,实际上Apples头文件中的注释警告您不支持此操作(与之相反)他们的在线文档):注意:目前不支持多个样本编写会话。调用startSessionAtSourceTime是一个错误:在调用endSessionAtSourceTime之后第二次:

  5. 所以我的下一个方法是创建多个AVAssets。当有一个“暂停开始”时,我将完成录音,当有“暂停”时,我将开始一个全新的录音,当完成所有操作后,我将使用AVAssetComposition来将它们全部重新组合在一起。我对这种方法感到有些紧张,因为我发现在设置新的av捕获时,快速av捕获停止并开始在各个地方出现无法解释的故障。在尝试开始新的av捕获之前,我可能不得不强迫“取消暂停”等待一段时间。

    所以问题是......有更好的方式吗?

0 个答案:

没有答案