【问题标题】:AVAssetWriter real-time processing audio from file and audio from AVCaptureSessionAVAssetWriter 实时处理来自文件的音频和来自 AVCaptureSession 的音频
【发布时间】:2018-04-19 20:56:57
【问题描述】:

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

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

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

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

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

添加所有三个写入器输入并将文件类型设置为 AVFileTypeQuickTimeMovie 后,来自文件的音频的 requestMediaDataOnQueue 进程似乎仍读取相同的数据。生成的 mov 文件显示三个轨道,两个音频,一个视频,并且捕获的音频和视频的持续时间长度不同,但它们显然有效,并且视频都完好无损地播放。但是,第三个轨道(第二个音轨)显示的持续时间为零。

有谁知道整个解决方案是否可行,以及为什么源文件音轨在 MOV 文件中的持续时间为零?如果有一种明确的方法可以让我混合两个音轨,但对于一个,AVAssetReaderAudioMixOutput 需要两个 AVAssetTracks,我本质上想将 AVAssetTrack 与捕获的音频混合,并且它们的管理或读取方式不同.

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

谢谢。

【问题讨论】:

    标签: audio real-time duration quicktime avassetwriter


    【解决方案1】:

    我发现原因是:

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

    CMTime bufferDuration = CMSampleBufferGetOutputDuration(nextBuffer);
    CMSampleBufferRef timeAdjustedBuffer;
    CMSampleTimingInfo timingInfo;
    timingInfo.duration = bufferDuration;
    timingInfo.presentationTimeStamp = _presentationTimeUsedToStartSession;
    timingInfo.decodeTimeStamp = kCMTimeInvalid;
    
    CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, nextBuffer, 1, &timingInfo, &timeAdjustedBuffer);
    

    【讨论】:

    • 但这不是让您的音频 PTS sBuffers 具有所有相同的 pts (_presentationTimeUsedToStartSession) 吗?每个新的音频缓冲区都将具有相同的 PTS 编号?不应该增加吗?
    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 2014-02-26
    • 1970-01-01
    • 2019-07-16
    相关资源
    最近更新 更多