在 iOS 中通过蓝牙播放时从内置麦克风录制

Posted

技术标签:

【中文标题】在 iOS 中通过蓝牙播放时从内置麦克风录制【英文标题】:Recording from Built-In Mic when Playing through Bluetooth in iOS 【发布时间】:2015-06-03 07:58:51 【问题描述】:

是否可以从 iPhone 的内置麦克风接收音频输入,并同时通过蓝牙耳机播放该音频?

我的目标是始终使用内置麦克风作为输入设备,即使输出设备是耳机,因为内置麦克风在我的用例中更方便。

当输出设备是有线耳机(例如与 iPhone 捆绑的耳机)时,我知道如何实现我的目标。我只需将有线耳机插入,然后调用以下方法:

- (void)selectBuiltInMicrophone

    AVAudiosession *session = [AVAudioSession sharedInstance];
    for (AVAudioSessionPortDescription *port in session.availableInputs)
        if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]) 
            NSError *error;
            [session setPreferredInput:port error:&error];
            break;
        

通过调用上述方法,输入设备将从有线耳机的麦克风切换到iPhone的内置麦克风,而输出设备不受影响,因此iPhone将从内置麦克风录制并通过有线播放耳机。这是我所期望的。

问题是,当耳机是蓝牙耳机时,此方法不起作用。如果我将蓝牙耳机连接到iPhone,然后调用上述方法,内置麦克风将成为输入设备,这很好,但输出设备也会变成iPhone的接收器,这很糟糕。

蓝牙耳机的输入和输出似乎是锁定在一起的:您要么同时使用它们,要么不使用它们。我的目标真的不可能吗?还是有办法克服明显的限制?

【问题讨论】:

你解决了这个问题了吗?您是否尝试过使用overrideOutputAudioPort 函数或其他任何东西? 【参考方案1】:

无法从 iPhone 的内置麦克风接收音频输入,同时通过蓝牙耳机播放该音频

    您可以像对讲机一样使用预防措施。 您必须创建两个会话。意味着在录制音频时,您必须启用带有录制和播放的音频会话。 在播放时,您必须将选项设置为 audiosession (allowingBluetooth)。 录制时您必须设置录制和播放。

【讨论】:

感谢您的回答!我了解您的第 1 点和第 3 点,但不太了解其他两点。你能详细说明一下吗? 这是完全错误的。确实可以从 iPhone 的内置麦克风录制音频并在蓝牙耳机上播放。 @RomanSamoilenko 怎么样?您能否提交并回答如何完成这项工作?【参考方案2】:

您可以在通过蓝牙音频设备播放音频时选择特定的麦克风。

  // set audio session category to .playAndRecord. use do-catch if you need error-handling
  try? AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker, .allowBluetoothA2DP, .allowBluetooth])

  // check if currentRoute is set to a bluetooth audio device
  let btOutputTypes: [AVAudioSession.Port] = [.bluetoothHFP, .bluetoothA2DP, .bluetoothLE]
  let btOutputs = AVAudioSession.sharedInstance().currentRoute.outputs.filter  btOutputTypes.contains($0.portType) 

  // if so, set preferred audio input to built-in mic
  if !btOutputs.isEmpty 
     let builtInMicInput = AVAudioSession.sharedInstance().availableInputs?.filter  $0.portType == .builtInMic .first
     try? AVAudioSession.sharedInstance().setPreferredInput(builtInMicInput)
   else 
     // set default input
     try? AVAudioSession.sharedInstance().setPreferredInput(nil)
  

  try? AVAudioSession.sharedInstance().setActive(true)

或者您可以按照此处的详细说明进行操作 https://developer.apple.com/library/archive/qa/qa1799/_index.html

编辑: 事实证明,在使用蓝牙耳机作为输出的同时,使用内置麦克风作为输入是一种更简单的方法。 只需像这样设置 AVAudioSession 的categoryOptions

// allow only A2DP. you may set other mode or options, excluding .allowBluetooth
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.allowBluetoothA2DP])

通过从 AVAudioSession 的 categoryOptions 中删除 .allowBluetooth,它将不允许使用蓝牙设备作为输入的协议 HFP。因此它会自动将其输入路由更改为内置麦克风。

如果您有多个输入(例如,如果您的设备连接到 usbAudio 或 lineIn 输入设备),您仍然需要使用 setPreferredInput 将输入路由更改为内置麦克风。

【讨论】:

这对我不起作用。每当我将PreferredInput 设置为麦克风时,音频输出也会更改为iPhone 扬声器。我也一直试图弄清楚这一点。我不确定这是否可能。 @gbones 您是否设置了诸如.allowBluetoothA2DPallowBluetooth 之类的蓝牙音频类别选项?如果您设置了适当的类别,上面的代码不会改变音频输出路径。调试 currentRoute 是否有蓝牙设备输出端口。

以上是关于在 iOS 中通过蓝牙播放时从内置麦克风录制的主要内容,如果未能解决你的问题,请参考以下文章

iOS AVAudioSessionRouteChangeReasonOverride:麦克风默认回内置 ipad 麦克风

AudioKit iOS 设置输入输出设备

在 Linux 上使用 bluealsa 从蓝牙耳机录制音频

从 AirPod 麦克风录制音频

ios 内置麦克风录音只有一个声道声音

iOS 无法在扬声器上播放并将音频会话设置为录制