How to use internal mic for input and bluetooth for output

Viewed 420

I'm currently trying to have my device to record audio for a capture session through device mic while having audio output on a bluetooth device (AirPods).

The reason I am doing this is because with bluetooth headphones and especially AirPods when the bluetooth mic is active the playback quality is horrible.

I tried using setPreferredInput but it changes both input and output, here's what I have so far.

   do {
        let session = AVAudioSession.sharedInstance()
        try session.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker, .allowBluetooth, .mixWithOthers])
        print(session.currentRoute.outputs)
        try session.setAllowHapticsAndSystemSoundsDuringRecording(true)
        try session.setActive(true, options: .notifyOthersOnDeactivation)
        if let mic = session.availableInputs?.first(where: {$0.portType == AVAudioSession.Port.builtInMic}) {
            try session.setPreferredInput(mic)
        }
    } catch let err {
        print("Audio session err", err.localizedDescription)
    }

Also I saw an old api that could have helped but it seems to be long depreciated now (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput) for AudioSession.

There are other apps on the App Store that seem to have achieved the split recording so it seems to be possible.

1 Answers

Get rid of allowBluetooth and use allowBluetoothA2DP. You also don't want defaultToSpeaker here.

"Allow Bluetooth" actually means "prefer HFP" which is why the audio is so bad. HFP is a low-bandwidth bidirectional protocol used generally for phone calls. The enum name is very confusing IMO. People get confused about it all the time.

A2DP is a high-bandwidth unidirectional protocol (it doesn't support a microphone). When you request that, the headset's microphone will be disabled, and you'll get the iPhone's microphone by default (provided there isn't some other wired microphone available, but that's very unlikely).

Related