【问题标题】:Does iOS Reduce Speaker Volume for Apps Using a Microphone?iOS 是否会降低使用麦克风的应用程序的扬声器音量?
【发布时间】:2021-11-24 09:29:38
【问题描述】:

我正在开发一个用于实时音乐可视化的 Xcode/Swift/SwiftUI 应用程序。我允许用户按下按钮在麦克风输入和文件播放输入之间切换(但不能同时进行)。我的应用程序在我的 Mac 和 iPad 上运行良好,但在我的 iPhone 上,扬声器音频只有一半音量(并且似乎只来自后置扬声器)——即使我处于文件播放模式。我已将问题追溯到我的代码中的一个违规行 - 即声明

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

当我注释掉这一行时,iPhone 扬声器级别(用于文件播放模式)很好。但是当我取消评论时,iPhone 扬声器的音量几乎听不见。即使我将这条线包裹在有条件的if(micEnabled){} 构造中,一开始的声音水平也很好;但是当我选择麦克风然后切换回文件播放时,音量再次降低。

我怀疑 iOS 会检测到何时声明了麦克风并自动降低扬声器音量以避免音频反馈。这是有道理的,因为没有人希望在打电话时播放音乐。但是,如果他们想自己处理它,为开发人员提供一种覆盖此功能的方法也是有意义的。在我的情况下,对于麦克风输入的情况,我特意将音频流在被点击之后和进入扬声器之前分配为零音量。

我的源代码可用here。所有的音频代码都在 MuVis / Shared / AudioManager.swift 类中。

谁能帮我在我的 iPhone 上让文件播放模式以全音量工作 - 同时还允许用户选择麦克风输入模式?

【问题讨论】:

  • 检查您的 AVAudioSession 的类别和选项。特别是,确保您没有启用.duckOthers。你配置了什么分类? (我假设.playAndRecord?)
  • 我没有使用 AVAudioSession。我正在使用 AVAudioEngine。
  • 你一直在使用 AVAudioSession。这就是您将应用程序的意图传达给操作系统的方式。如果您使用 AVAudioEngine,它会自动激活,但这并不意味着您不需要配置它。
  • 感谢您的指导。到目前为止,我一直是纯粹的 macOS 开发人员。由于 AVAudioSession 在 macOS 中不可用,因此我避免了它。我刚刚尝试将 AVAudioSession 插入我的应用程序(在 #if os(iOS){} 构造内)并将其类别设置为 playAndRecord,但这并不能解决我的 iPhone 音量问题。我将编辑我的问题以插入指向我的源代码的链接,希望您能指导我更多。

标签: ios swift iphone microphone avaudioengine


【解决方案1】:

非常感谢 Rob Napier 为我指明了解决问题的正确方向。

作为仅 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

再次感谢罗伯。

【讨论】:

    猜你喜欢
    • 2013-06-10
    • 1970-01-01
    • 2019-07-04
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 2016-05-20
    相关资源
    最近更新 更多