Уменьшает ли iOS громкость динамиков для приложений, использующих микрофон?

#ios #swift #iphone #microphone #avaudioengine

Вопрос:

Я разрабатываю приложение Xcode/Swift/SwiftUI для визуализации музыки в реальном времени. Я разрешаю пользователю нажимать кнопку для переключения между входом микрофона и входом воспроизведения файлов (но никогда не одновременно). Мое приложение отлично работает на моем Mac и на моем iPad, но на моем iPhone звук из динамика только на половине громкости (и, похоже, поступает только из задних динамиков)-даже когда я нахожусь в режиме воспроизведения файлов. Я проследил проблему до одной оскорбительной строки в моем коде, а именно до объявления

let mic = engine.inputNode // where engine = AVAudioEngine()

Когда я комментирую эту строку, уровень динамика iPhone (для режима воспроизведения файлов) в порядке. Но когда я не комментирую это, уровень громкоговорителя iPhone едва слышен. Даже когда я заключаю эту строку в условную if(micEnabled){} конструкцию, уровень звука сначала в порядке; но как только я выбираю микрофон, а затем переключаюсь обратно в режим воспроизведения файлов, громкость снова уменьшается.

Я подозреваю, что iOS обнаруживает, когда объявляется микрофон, и автоматически уменьшает громкость динамика, чтобы избежать обратной связи со звуком. Это имело бы смысл, потому что никто не хочет, чтобы играла музыка, когда они разговаривают по телефону. Но также имело бы смысл предоставить разработчикам способ переопределить эту функцию, если они хотят справиться с ней самостоятельно. В моем случае, для случая с микрофонным входом, я намеренно назначаю аудиопотоку нулевую громкость после его прослушивания и перед подключением к громкоговорителю.

Мой исходный код доступен здесь. Весь аудиокод находится внутри класса MuVis / Shared / AudioManager.swift.

Может ли кто-нибудь помочь мне настроить режим воспроизведения файлов на полную громкость на моем iPhone, а также предоставить пользователю возможность выбрать режим ввода микрофона?

Комментарии:

1. Проверьте категорию и параметры вашей аудиосессии. В частности, убедитесь, что вы не включили .duckOthers . Какую категорию вы настроили? (Я полагаю .playAndRecord ?)

2. Я не использую AVAudioSession. Вместо этого я использую AVAudio.

3. Вы всегда используете AVAudioSession. Именно так вы сообщаете о намерениях своего приложения операционной системе. Он активируется автоматически, если вы используете AVAudio, но это не значит, что вам не нужно его настраивать.

4. Спасибо за ваше руководство. До сих пор я был исключительно разработчиком macOS. Поскольку AVAudioSession недоступен в macOS, я избегал этого. Я просто попытался вставить AVAudioSession в свое приложение (внутри #if os(iOS){} конструкции) и установить его категорию для воспроизведения и записи, но это не решает проблему громкости моего iPhone. Я отредактирую свой вопрос, чтобы вставить ссылку на мой исходный код, и, надеюсь, вы сможете помочь мне больше.

Ответ №1:

Большое спасибо Робу Нейпиру за то, что указал мне правильное направление для решения моей проблемы.

Как разработчик только для macOS, я проигнорировал AVAudioSession (так как это приводило к ошибкам компилятора в macOS). Когда я преобразовал свое приложение MuVis только для macOS в мультиплатформенное, я просто запустил новый проект Xcode с соответствующими настройками мультиплатформенности, а затем вставил существующий код в shared папку. После устранения нескольких ошибок (в основном вызовов NSObject ) он волшебным образом сработал на всех платформах Apple, за исключением проблемы со звуком iPhone, описанной в моем вопросе. После небольшого исследования и множества проб и ошибок я обнаружил, что моя проблема с громкостью звука решена путем вставки следующего кода в мою setupAudio() функцию:

     #if os(iOS)
        // For iOS devices, set the audioSession category, mode, and options:
        let session = AVAudioSession.sharedInstance()  // Get the singleton instance of an AVAudioSession.
        do {
            if(filePlayEnabled) {
                // This is required by iOS to prevent output audio from going only to the iPhone's rear speaker.
                try session.setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.default, options: [.defaultToSpeaker])
            }
            else {
                try session.setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.default, options: [])
            }
        } catch { print("Failed to set audioSession category.") }
    #endif
 

Еще раз спасибо тебе, Роб.