Камера iOS: `AVCaptureAudioDataOutput` активирует аудиосеанс на лету, избегая заикания фоновой музыки

Я создал камеру с использованием AVFoundation, которая может записывать видео и аудио с помощьюAVCaptureVideoDataOutput а такжеAVCaptureAudioDataOutput . Я создаю сеанс захвата, подключаю все входы и выходы видео- и аудиоданных, а затем камера бездействует. Теперь пользователь может начать запись видео.

Проблема

Проблема в том, что сразу после запуска сеанса захвата (captureSession.startRunning() ), фоновая музыка заикается. Я предполагаю, что это связано с тем, что после запуска сеанса захватаAVCaptureAudioDataOutput внутренне активирует AVAudioSession ( AVAudioSession.setActive(...) ), чего я не хочу. Я хочу, чтобы он бездействовал (и не предоставлял никаких буферов вывода звука), пока я явно не активирую аудиосеанс (после того, как пользователь начнет запись).

Это действительно раздражает, поскольку камера является стартовым экраном в нашем приложении, и каждый раз, когда пользователь открывает или закрывает приложение, его музыка заикается.

Я знаю, что это возможно, потому что Snapchat работает именно так - вы открываете приложение, и фоновый звук продолжает воспроизводиться. Как только вы начинаете запись, фоновая музыка немного заикается, но камера работает плавно и начинает запись, как только короткое заикание закончится.

Мой код:

func configureSession() {

    captureSession.beginConfiguration()

    // Video, Photo and Audio Inputs
    ...

    // Video Output
    ...

    // Audio Output
    audioOutput = AVCaptureAudioDataOutput()
    guard captureSession.canAddOutput(audioOutput!) else {
      throw CameraError.parameter(.unsupportedOutput(outputDescriptor: "audio-output"))
    }
    audioOutput!.setSampleBufferDelegate(self, queue: audioQueue)
    captureSession.addOutput(audioOutput!)

    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord,
                                                    options: [.mixWithOthers,
                                                              .allowBluetoothA2DP,
                                                              .defaultToSpeaker,
                                                              .allowAirPlay])

    captureSession.commitConfiguration()
}

Что я пробовал

Задержка настройкиAVAudioSession.sharedInstance()

Я попытался сначала настроитьAVAudioSession.sharedInstance с категориейAVAudioSession.Category.playback и переключитесь на.playAndRecord однажды я хочу начать запись звука.

Это не сработало, иAVCaptureSessionRuntimeError событие вызывается сразу после запуска камеры с кодом ошибки-10851 , что значитkAudioUnitErr_InvalidPropertyValue . Я думаю, это означает, чтоAVCaptureAudioDataOutput не разрешено записывать из аудиосессии, но я не хочу делать это прямо сейчас - он должен просто быть незанятым.

Задержка добавленияAVCaptureAudioDataOutput выход

Пробовал не добавлять аудиовыход (AVCaptureAudioDataOutput ) в начале, и добавляйте его только «по запросу», как только пользователь начинает запись, и хотя это нормально работало для фоновой музыки (без заикания при запуске, только короткое заикание после того, как пользователь начнет запись, именно так, как я хочу) , из-за этого предварительный просмотр завис на короткое время (потому что сеанс захвата реконфигурируется черезbeginConfiguration + добавление аудиовыхода +commitConfiguration )

Кто-нибудь знает, как можно достичь того, что я пытаюсь сделать здесь, или как это делает Snapchat? Любая помощь приветствуется, спасибо!

# avfoundation avcapturesession
Источник
Codelisting
за 0 против
Лучший ответ

Наконец разобрался. Я просто создал отдельныйAVCaptureSession специально для аудиовхода / вывода, который я синхронизирую с основным сеансом захватаmasterClock . Затем я могу запустить / остановить вторичный сеанс захвата на лету (незадолго до начала записи)

  • 0
    Приятный штрих с синхронизацией! Вы можете принять свой ответ?
за 0 против

В.mixWithOthers похоже, что нужно сделать, чтобы не отвлекаться, но по умолчаниюAVCaptureSession настроитAVAudioSession для вас, так что установите

captureSession.automaticallyConfiguresApplicationAudioSession = false

чтобы он не заменил ваши настройки.

Документация на недвижимость сообщает нам, чтоAVCaptureSession делает больше, чем просто устанавливает.playAndRecord категория, факт, который может быть важен для вашего варианта использования:

the receiver ensures the application's audio session is set to the PlayAndRecord category, and picks an appropriate microphone and polar pattern to match the video camera being used

  • 0
    Спасибо за ответ, но я уже отключил автоматическую настройку. См. Мой ответ для фактического решения
Codelisting
Популярные категории
На заметку программисту