gpt4 book ai didi

ios - 如何在iOS11中正确停止和删除audioTapProcessor

转载 作者:行者123 更新时间:2023-12-01 19:50:18 26 4
gpt4 key购买 nike

我正在使用与audioTap example from apple类似的audioTapProcessor。

基本上,将创建audioTapProcessor并将其添加到audioMix:

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

CFRelease(audioProcessingTap);

audioMix.inputParameters = @[audioMixInputParameters];

_audioMix = audioMix;
}

创建audioMix后,会将其添加到avPlayer的currentItem中:
self.avPlayer.currentItem.audioMix = audioMix;

当我用完audioTapProcessor后,我会清除对audioTapProcessor和audioMix的引用:
if (self.avPlayer.currentItem.audioMix){

for (AVMutableAudioMixInputParameters *inputParameter in player.currentItem.audioMix.inputParameters) {
inputParameter.audioTapProcessor = nil;

}

player.currentItem.audioMix = nil;
}

这将触发tap_UnprepareCallback和tap_FinalizeCallback函数,并且audioTapProcessor对象将被释放。

直到几天前iOS11出来,这一切都没有问题。

在iOS11设备上,有时我在ClientProcessingTapManager线程上收到EXC_BAD_ACCESS错误。该错误发生在AVFoundation的一类中,因此无法调试。该错误发生在ClientProcessingTap::PerformTap中。

我已将日志记录添加到audioTap回调中,并且看起来只有tap_ProcessCallBack在ClientProcessingTapManager线程上执行。

我认为有时在此线程上触发audioTapProcessor的tap_ProcessCallback方法,而实际的audioTapProcessor已经在另一个线程上释放。

我的问题是:如何正确停止audioTapProcessor并将其从内存中删除?

这是一些输出日志记录示例:
2017-09-22 12:49:26:171 xx[1261:780894] cleaning up audioMix of AvPlayer
2017-09-22 12:49:26:213 xx[1261:781173] into tap_ProcessCallback. thread: ClientProcessingTapManager
2017-09-22 12:49:26:213 xx[1261:781173] end of tap_ProcessCallback
2017-09-22 12:49:26:217 xx[1261:781127] into tap_UnprepareCallback.
2017-09-22 12:49:26:218 xx[1261:781127] end of tap_UnprepareCallback
2017-09-22 12:49:26:218 xx[1261:781127] into tap_FinalizeCallback.
2017-09-22 12:49:26:218 Tunify[1261:781127] end of tap_FinalizeCallback
2017-09-22 12:49:26:218 Tunify[1261:781127] into MYAudioTapProcessor dealloc.
(lldb)

很高兴知道:

我正在使用avPlayers池,所以我正在重用这些对象。当我不清除avPlayers的audioMix时,就不会遇到此错误。如果不清理audioMix对象,则仅当我重用avPlayer并将新的audioMix分配给avPlayer时,才会重新分配audioTapProcessor。

我发现了 related question,但是我已经在触发清理功能。那里的解决方案在iOS11设备上给出了相同的错误

最佳答案

这是iOS 11下AVFoundation中的错误,已在iOS 12中修复。
问题rdar://34977000的雷达

可能的解决方法是在释放AVPlayer / AVPlayerItem之前调用prepareReleaseAudioMix:

+ (void)prepareReleaseAudioMix:(AVAudioMix*)audioMix {
if ( @available(iOS 11.0, *) ) {
// Starting with iOS 11, it is not required to manually nil audioTapProcessor,
// but we need to retain the audioMix for a bit to make sure the processing callback
// will not be called after we release (this is due to a bug in iOS 11 which calls the release
// callback but still calls the processing callback afterwards - it also releases internal data
// on release, so simply checking for release in the processing block is not enough)
// rdar://34977000
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self _prepareReleaseAudioMixNow:audioMix];
});
} else {
// Prior to iOS 11 we need to manually nil the audioTapProcessor
[self _prepareReleaseAudioMixNow:audioMix];
}
}

+ (void)_prepareReleaseAudioMixNow:(AVAudioMix*)audioMix {
for ( AVMutableAudioMixInputParameters *parameters in audioMix.inputParameters ) {
if ( ![parameters isKindOfClass:[AVMutableAudioMixInputParameters class]] )
continue;
parameters.audioTapProcessor = nil;
}
}

关于ios - 如何在iOS11中正确停止和删除audioTapProcessor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46362859/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com