MTAudioProcessingTap 的头文件说它的初始化和准备回调将由未准备和完成回调平衡。然而,在 Apple's example ,这些回调永远不会被调用(我向它们添加了日志记录以便我可以检查)。头文件说它们将在对象被释放时被调用。
在 Apple 的示例中,Tap 被传递到 audioMixInputParameters 中的保留参数,该参数被传递到音频混合中,不再公开访问:
MTAudioProcessingTapRef audioProcessingTap;
if (noErr == MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &audioProcessingTap))
{
audioMixInputParameters.audioTapProcessor = audioProcessingTap;
CFRelease(audioProcessingTap);
audioMix.inputParameters = @[audioMixInputParameters];
_audioMix = audioMix;
}
因此,我希望 AudioMix 负责在其自己的 dealloc 方法中释放它,并在释放关联的 PlayerItem 时释放 AudioMix。
Apple 的例子使用了一个只播放一个项目的 AVPlayer,所以它可能不需要直接释放任何东西。但就我而言,我使用的是 AVQueuePlayer,所以我一直向它传递新的 AVPlayerItems。我认为它泄漏了我为每个播放器项目(以及关联的音频单元)创建的 Taps,即使播放器项目已被释放。
什么是解除分配 MTAudioProcessingTap 并在我完成其关联的播放器项目时触发其未准备和最终确定回调的正确方法?
更新:我发现它实际上仍然可以通过音频混合访问,但是像这样发布它不会触发 unprepare 和 finalize 回调:
((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor = nil;
这也不是:
MTAudioProcessingTapRef audioProcessingTap = ((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor;
CFRelease(audioProcessingTap);
最佳答案
我遇到了同样的问题。为了让它工作,我必须重置播放器项目的 audioMix
、tap 处理器(Apple 示例项目中的 MYAudioTapProcessor
)并手动释放 MTAudioProcessingTapRef
:
MTAudioProcessingTapRef tap = ((AVMutableAudioMixInputParameters *)_audioTapProcessor.audioMix.inputParameters[0]).audioTapProcessor;
_player.currentItem.audioMix = nil;
_audioTapProcessor = nil;
CFRelease(tap);
这会导致调用 finalize
回调。
编辑:似乎 CFRelease
不是必需的,请参阅评论。
关于ios - 如何发布 MTAudioProcessingTap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19202306/