🎙️

AVAudioSessionで録音する際に、音はbluetoothイヤホン、マイクはデバイスマイクを使いたい

2020/12/17に公開

知ってしまえば単純だったんですけど、解決策見つけるまで時間がかかったので残しておきます。

内容はこちらの記事の通りです。この記事でほんと助かりました。
iOS: bluetooth and microphone input2017

課題

音声を聞きながら録音(録音は自分の声のみ)するアプリで、特定のBluetoothイヤホンで音声がブチブチしてしまう問題がありました。
類似機能の他アプリを調べてみたのですが、そもそもBluetoothイヤホンのマイクは使っておらず、デバイスのマイクを使っていました。

では、デバイスのマイクを使うことで対応しましょう、ということでやってみました。

対応方法

.allowBluetoothを使わずに、.allowBluetoothA2DPだけにします。

  try session.setCategory(.playAndRecord,
                          options: [.defaultToSpeaker,
-                                   .allowBluetooth,
                                    .allowAirPlay,
                                    .allowBluetoothA2DP])

なんでこれでスピーカーとマイクが分かれるのか

最初このようなコードを書いてみたのですが、これは出力もデバイスのスピーカーになってしまいました。
Inputだけ変えたのに何でだろうと思うのですが、setPreferredInputはあってもsetPreferredOutputは無いので、基本的にセットになるものなのかもしれません。

// 内蔵マイクを優先的に使用する
if let desc = session.availableInputs?.first(where: { (desc) -> Bool in
    return desc.portType == .builtInMic
}) {
    do {
        try session.setPreferredInput(desc)
    } catch let error {
        print(error)
    }
}

.allowBlueToothに関しては、ハンズフリープロファイル(HFP)を使用するオプションです。ドキュメントを見ると、入力と出力のどちらかでHFPが選択されると、逆も自動的にHFPが設定されると書かれています。

If an application uses the setPreferredInput(_:) method to select a Bluetooth HFP input, the output automatically changes to the corresponding Bluetooth HFP output. Likewise, selecting a Bluetooth HFP output using an MPVolumeView object’s route picker automatically changes the input to the corresponding Bluetooth HFP input. Therefore, both audio input and output are routed to the Bluetooth HFP device even though you only selected the input or output.
https://developer.apple.com/documentation/avfoundation/avaudiosession/categoryoptions/1616518-allowbluetooth

つまり、HFPが使用されている以上、スピーカーとマイクを分けることはできないです。

では、.allowBluetoothA2DPだけにするとどうなるか。
これは、スピーカーとマイクが分かれるというよりも、最初から音楽再生用のオプションなので、Bluetoothイヤホンのマイクが使われないことになります。

最初、.allowBlueTooth.allowBluetoothA2DPの両方を指定してしまっていたのですが、両方指定している場合はHFPの優先度が高くなります。このため、Bluetoothイヤホンのマイクが使われてしまっていました。

Note

If this option and the allowBluetooth option are both set, when a single device supports both the Hands-Free Profile (HFP) and A2DP, the system gives hands-free ports a higher priority for routing.
https://developer.apple.com/documentation/avfoundation/avaudiosession/categoryoptions/1771735-allowbluetootha2dp

Discussion