你如何发布一个MTAudioProcessingTap?

MTAudioProcessingTap的头文件说,它的初始化和准备callback将通过unspare和finalizecallback进行平衡。 然而,在苹果的例子中 ,这些callback永远不会被调用(我添加了日志logging,所以我可以检查)。 头文件说,当对象被释放时它们将被调用。

在苹果公司的例子中,Tap被传递到audioMixInputParameters中的retain参数中,该参数被传递到audio混合中,不再公开访问:

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。 我认为它泄露了我为每个玩家项目(以及相关的audio单元)创build的Taps,即使玩家项目被释放。

什么是正确的方式来释放MTAudioProcessingTap并得到它的无与伦比的callback触发,当我完成相关的播放器项目?

更新 :我发现它实际上仍然可以通过audio混合访问,但是像这样释放它并不会触发非预期和最终callback:

 ((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor = nil; 

这也不是:

 MTAudioProcessingTapRef audioProcessingTap = ((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor; CFRelease(audioProcessingTap); 

我有同样的问题。 为了使它工作,我不得不重置播放器项目的audioMix ,轻敲处理器(苹果示例项目中的MTAudioProcessingTapRef ),并手动释放MTAudioProcessingTapRef

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

这会导致finalizecallback被调用。

编辑:似乎CFRelease 不是必需的,请参阅评论。