如何在iOS11中正确停止和删除audioTapProcessor [英] How to correctly stop and remove an audioTapProcessor in iOS11

查看:182
本文介绍了如何在iOS11中正确停止和删除audioTapProcessor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用与 audioTap示例类似的audioTapProcessor来自苹果.

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

Basically, the audioTapProcessor is created and added to the audioMix:

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

    CFRelease(audioProcessingTap);

    audioMix.inputParameters = @[audioMixInputParameters];

    _audioMix = audioMix;
}

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

When the audioMix is created, it is added to the currentItem of the avPlayer:

self.avPlayer.currentItem.audioMix = audioMix;

当我用完audioTapProcessor后,我会清除对audioTapProcessor和audioMix的引用:

When i'm done with the audioTapProcessor, I clean out references to the audioTapProcessor and the 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对象将被释放.

This triggers the tap_UnprepareCallback and the tap_FinalizeCallback functions, and the audioTapProcessor objects get's deallocated.

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

This worked without any issues until iOS11 came out a couple of days ago.

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

On iOS11 devices, I sometimes receive an EXC_BAD_ACCESS error on the ClientProcessingTapManager Thread. The error occurs in one of the classes of AVFoundation, so I can't debug. The error occurs somewhere in ClientProcessingTap::PerformTap.

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

I have added logging to the audioTap callbacks, and it looks like only the tap_ProcessCallBack is executed on the ClientProcessingTapManager thread.

我认为有时在此线程上触发audioTapProcessor的tap_ProcessCallback方法,而实际的audioTapProcessor已经在另一个线程上解除分配.

I think that sometimes the tap_ProcessCallback method of an audioTapProcessor is triggered on this thread, while the actual audioTapProcessor is already deallocated on another Thread.

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

My question is: how can I correctly stop an audioTapProcessor and remove it from memory?

这是一些输出日志记录示例:

This is some example output logging:

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) 


很高兴知道


Good to know:

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

I'm usng a pool of avPlayers, so i'm reusing these objects. When I don't clean out the audioMix of my avPlayers I don't run into this error. Without the cleaning up of the audioMix objects, the audioTapProcessors are only deallocated when I reuse an avPlayer and assign a new audioMix to the avPlayer.

我找到了相关问题,但我已经触发了清理功能.那里的解决方案在iOS11设备上也给出了相同的错误

I found a related question, but i'm already triggering the cleanup functions. The solution there gives the same error on iOS11 devices

推荐答案

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

This is a bug in AVFoundation under iOS 11. It has been fixed in iOS 12. A radar for the issue rdar://34977000

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

A possible workaround is to call prepareReleaseAudioMix: just before releasing the AVPlayer / AVPlayerItem

+ (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;
    }
}

这篇关于如何在iOS11中正确停止和删除audioTapProcessor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆