7

MTAudioProcessingTap 的头文件说它的初始化和准备回调将通过取消准备和完成回调来平衡。但是,在Apple 的示例中,这些回调永远不会被调用(我向它们添加了日志记录以便我可以检查)。头文件说当对象被释放时它们将被调用。

在 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。

Apple 的示例使用只播放一个项目的 AVPlayer,因此它可能不需要直接释放任何内容。但就我而言,我使用的是 AVQueuePlayer,所以我不断向它传递新的 AVPlayerItems。我认为它泄漏了我为每个播放器项目(以及相关的音频单元)创建的 Taps,即使播放器项目被释放。

当我完成其关联的播放器项目时,解除分配 MTAudioProcessingTap 并使其 unprepare 和 finalize 回调触发的正确方法是什么?

更新:我发现它实际上仍然可以通过音频混合访问,但是像这样释放它不会触发 unprepare 和 finalize 回调:

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

这也不是:

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

1 回答 1

10

我有同样的问题。为了让它工作,我不得不重置播放器项目的audioMix水龙头处理器(MYAudioTapProcessor在 Apple 的示例项目中)并手动释放MTAudioProcessingTapRef

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

这会导致finalize调用回调。

编辑:似乎不需要CFRelease,请参阅评论。

于 2013-10-11T11:54:35.917 回答