MTAudioProcessingTap的头文件表示,其初始化和准备回调将通过未准备和完成回调来平衡。但是,在Apple's example中,这些回调从未被调用(我在其中添加了日志记录,以便可以检查)。头文件说,当对象被释放时,它们将被调用。

在Apple的示例中,Tap被传递到audioMixInputParameters中的一个retain参数,该参数被传递到混音中,在该混音中不再公开可用:

MTAudioProcessingTapRef audioProcessingTap;
if (noErr == MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &audioProcessingTap))
{
    audioMixInputParameters.audioTapProcessor = audioProcessingTap;

    CFRelease(audioProcessingTap);

    audioMix.inputParameters = @[audioMixInputParameters];

    _audioMix = audioMix;
}

因此,我希望AudioMix负责以其自己的dealloc方法释放它,并负责在释放关联的PlayerItem时释放AudioMix。

苹果公司的示例使用了只播放一项的AVPlayer,因此也许不需要直接取消分配任何内容。但就我而言,我使用的是AVQueuePlayer,因此我不断为其传递新的AVPlayerItems。我认为这泄漏了我为每个播放器项目(以及相关的音频单元)创建的Taps,即使播放器项目被释放了。

当我完成其关联的播放器项目后,解除分配MTAudioProcessingTap并使其准备不足并最终触发回调的正确方法是什么?

更新:我发现实际上仍然可以通过混音访问它,但是像这样释放它不会触发准备不足和完成回调:
((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor = nil;

这也不是:
MTAudioProcessingTapRef audioProcessingTap = ((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor;
CFRelease(audioProcessingTap);

最佳答案

我有同样的问题。为了使其正常工作,我必须重置播放器项目的audioMix,敲击处理器(Apple的示例项目中的MYAudioTapProcessor)并手动释放MTAudioProcessingTapRef:

MTAudioProcessingTapRef tap = ((AVMutableAudioMixInputParameters *)_audioTapProcessor.audioMix.inputParameters[0]).audioTapProcessor;
_player.currentItem.audioMix = nil;
_audioTapProcessor = nil;
CFRelease(tap);

这将导致finalize回调被调用。

编辑:似乎不需要CFRelease,请参阅注释。

10-08 08:27