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
,请参阅注释。