Я столкнулся со следующей проблемой и надеюсь, что кто-то еще столкнулся с ней и может предложить решение:
- Я использую
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)")
}
}
}