Audio AVAssetWriter实时处理来自文件 ;和来自AVCaptureSession的音频

Audio AVAssetWriter实时处理来自文件 ;和来自AVCaptureSession的音频,audio,real-time,duration,quicktime,avassetwriter,Audio,Real Time,Duration,Quicktime,Avassetwriter,我正在尝试创建一个包含两个音频曲目和一个视频曲目的MOV文件,我正在尝试在没有AVAssetExportSession或AVComposition的情况下创建MOV文件,因为我希望在AVCaptureSession结束后立即准备好生成的文件。捕获会话后的导出可能只需要几秒钟,但在5分钟捕获会话的情况下则不需要。这看起来应该是可能的,但我觉得我离这里只有一步之遥: 有一个源#1-通过AVCaptureSession录制的视频和音频(通过AVCaptureVideoDataOutput和AVCapt

我正在尝试创建一个包含两个音频曲目和一个视频曲目的MOV文件,我正在尝试在没有AVAssetExportSession或AVComposition的情况下创建MOV文件,因为我希望在AVCaptureSession结束后立即准备好生成的文件。捕获会话后的导出可能只需要几秒钟,但在5分钟捕获会话的情况下则不需要。这看起来应该是可能的,但我觉得我离这里只有一步之遥:

有一个源#1-通过AVCaptureSession录制的视频和音频(通过AVCaptureVideoDataOutput和AVCaptureAudioDataOutput处理)

有一个源代码#2-一个用Avassetrader读入的音频文件。在这里,我使用AVAssetWriterInput和requestMediaDataWhenReadyOnQueue。我在其AvasseTrader上调用setTimeRange,从CMTimeZero到资产的持续时间,这正确地显示为注销时的27秒

我让三个输入中的每一个在自己的队列上工作,并且所有三个都是并发的。日志记录显示它们都在处理样本缓冲区——没有一个似乎落后于或卡在未处理的队列中

重要的一点是,音频文件可以独立工作,使用所有相同的AVAssetWriter代码。如果我将AVAssetWriter设置为输出WAVE文件,并避免添加来自#1(捕获会话)的writer输入,则当来自文件样本的音频耗尽时,我将完成writer会话。音频文件报告为具有一定大小,并且可以正确播放

添加了所有三个writer输入,并且文件类型设置为AVFileTypeQuickTimeMovie,来自文件的音频的requestMediaDataOnQueue进程仍会读取相同的数据。生成的mov文件显示了三个曲目、两个音频、一个视频,捕获的音频和视频的持续时间长度不同,但它们显然起了作用,视频播放时两者都完好无损。但是,第三个音轨(第二个音频音轨)的持续时间为零

有人知道这个完整的解决方案是否可行吗?为什么在MOV文件中,from文件音频曲目的持续时间为零?如果有一个明确的方法让我混合这两个音轨,我会这样做,但首先,AvassetraderaAudiomiXOutput需要两个AVAssetTrack,我基本上想混合AVAssetTrack和捕获的音频,它们不是以相同的方式管理或读取的

我还认为QuickTime电影不会接受某些音频格式,但我要强调的是将相同的输出设置字典传递给两个音频AVAssetWriterInputs,并且捕获的音频会播放并报告其持续时间(当处于具有相同输出设置的WAV文件中时,从文件音频播放),所以我不认为这是个问题


谢谢。

我发现原因是:

我正确地使用传入捕获会话数据的表示时间戳(我现在使用视频数据的PTS)开始编写器会话(startSessionAtSourceTime),这意味着从文件中读取的音频数据的时间戳有错误的时间戳-超出了指定给AVAssetWriter会话的时间范围。因此,我必须进一步处理音频文件中的数据,使用cmSampleBufferCreateCopyWithNewTimeing更改其计时信息

CMTime bufferDuration = CMSampleBufferGetOutputDuration(nextBuffer);
CMSampleBufferRef timeAdjustedBuffer;
CMSampleTimingInfo timingInfo;
timingInfo.duration = bufferDuration;
timingInfo.presentationTimeStamp = _presentationTimeUsedToStartSession;
timingInfo.decodeTimeStamp = kCMTimeInvalid;

CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, nextBuffer, 1, &timingInfo, &timeAdjustedBuffer);

但这不是让你的音频PTS缓冲区拥有所有相同的PTS吗?每个新的音频缓冲区将具有相同的PTS编号?它不应该增加吗?