Подключение Bluetooth-наушников во время записи приложения в фоновом режиме приводит к остановке записи - PullRequest
1 голос
/ 04 октября 2019

Я столкнулся со следующей проблемой и надеюсь, что кто-то еще столкнулся с ней и может предложить решение:

  1. Я использую AVAudioEngine для доступа к микрофону. До iOS 12.4 каждый раз, когда менялся аудио маршрут, я мог перезапускать график AVAudioEngine, чтобы перенастроить его и убедиться, что аудиоформаты ввода / вывода соответствуют новому маршруту ввода / вывода. Из-за изменений, внесенных в iOS 12.4, больше невозможно запускать (или перезапускать) график AVAudioEngine, пока приложение работает в фоновом режиме (если только оно не было прервано).

Ошибка, которую Apple теперь выдает, когда я пытаюсь это сделать:

2019-10-03 18:34:25.702143+0200 [1703:129720] [aurioc] 1590: AUIOClient_StartIO failed (561145187)
2019-10-03 18:34:25.702528+0200 [1703:129720] [avae]            AVAEInternal.h:109   [AVAudioEngineGraph.mm:1544:Start: (err = PerformCommand(*ioNode, kAUStartIO, NULL, 0)): error 561145187
2019-10-03 18:34:25.711668+0200 [1703:129720] [Error] Unable to start audio engine The operation couldn’t be completed. (com.apple.coreaudio.avfaudio error 561145187.)

Я предполагаю, что Apple закрыла уязвимость безопасности там. Поэтому теперь я удалил код для перезапуска графика при изменении аудио маршрута (например, подключены наушники Bluetooth).

Похоже, что при изменении формата аудио ввода / вывода (как это происходит, когда пользователь подключает устройство Bluetooth), запускается уведомление .AVAudioEngingeConfigurationChange, чтобы позволить интегрирующему приложению реагировать на изменение формата. Это действительно то, что я должен был использовать для обработки изменений в форматах ввода-вывода с самого начала, вместо того, чтобы перезагружать график перебором. Согласно документации Apple: «Когда блок ввода-вывода звукового движка наблюдает изменение количества каналов или частоты дискретизации входного или выходного оборудования, звуковой движок останавливается, неинициализируется сам и выдает это уведомление». ( см. документы здесь ). Когда это происходит в то время, когда приложение находится в фоновом режиме, я не могу запустить аудио движок с правильными аудиоформатами ввода / вывода, из-за пункта № 1.

Итак, суть в том, что при закрытииИз-за уязвимости в безопасности Apple представила ошибку, реагирующую на изменения формата аудио ввода-вывода, пока приложение находится в фоновом режиме. Или я что-то упустил?

Я прилагаю фрагмент кода, чтобы лучше описать проблему. Чтобы узнать AppDelegate с технологией plug-and-play, см. Здесь - https://gist.github.com/nevosegal/5669ae8fb6f3fba44505543e43b5d54b.

class RCAudioEngine {
​
    private let audioEngine = AVAudioEngine()

    init() {
        setup()
        start()
        NotificationCenter.default.addObserver(self, selector: #selector(handleConfigurationChange), name: .AVAudioEngineConfigurationChange, object: nil)
    }
​
    @objc func handleConfigurationChange() {
        //attempt to call start()
        //or to audioEngine.reset(), setup() and start()
        //or any other combination that involves starting the audioEngine
        //results in an error 561145187.
        //Not calling start() doesn't return this error, but also doesn't restart
        //the recording.
    }

    public func setup() {
​
        //Setup nodes
        let inputNode = audioEngine.inputNode
        let inputFormat = inputNode.inputFormat(forBus: 0)
        let mainMixerNode = audioEngine.mainMixerNode
​
        //Mute output to avoid feedback
        mainMixerNode.outputVolume = 0.0
​
        inputNode.installTap(onBus: 0, bufferSize: 4096, format: inputFormat) { (buffer, _) -> Void in
            //Do audio conversion and use buffers
        }
    }
​
    public func start() {
        RCLog.debug("Starting audio engine")
        guard !audioEngine.isRunning else {
            RCLog.debug("Audio Engine is already running")
            return
        }
​
        do {
            audioEngine.prepare()
            try audioEngine.start()
        } catch {
            RCLog.error("Unable to start audio engine \(error.localizedDescription)")
        }
    }
}

1 Ответ

0 голосов
/ 04 октября 2019

Я вижу только исправление, которое вошло в iOS 12.4. Я не уверен, вызывает ли это проблему.

С примечаниями к выпуску https://developer.apple.com/documentation/ios_ipados_release_notes/ios_12_4_release_notes

"Устранена проблема, из-за которой запуск приложения в iOS 12.2 или более поздней версии под инструментом Leaks приводил к случайным числамложно-положительных утечек для каждой проверки утечки после первой проверки в данном прогоне. Эта проблема может по-прежнему возникать в Simulator или в приложениях macOS при использовании инструментов из Xcode 10.2 и более поздних версий. (48549361) "

Вы можете поднять вопрос с Apple, если вы являетесь подписанным разработчиком. Они могут помочь вам, если дефект с их стороны.

Вы также можете протестировать в следующем выпуске iOS, чтобы проверить, работает ли ваш код в будущем выпуске (с бета-программой apple)

...