我正在使用类似于的audioTapProcessor苹果的 audioTap 示例 https://developer.apple.com/library/content/samplecode/AudioTapProcessor/Introduction/Intro.html.
基本上,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时,audioTapProcessors才会被释放。
我找到了一个相关问题 https://stackoverflow.com/questions/19202306/how-do-you-release-an-mtaudioprocessingtap,但我已经触发了清理功能。那里的解决方案在 iOS11 设备上给出了相同的错误