简体   繁体   中英

Record and playback using bluetooth earphone's mic & internal speaker in Swift

I currently have a pair of Bluetooth earbuds. From this post, I have the code needed to retrieve audio from the Bluetooth earbuds' microphone and then playback the audio through the Bluetooth earbuds. However, I want to modify the code so that I can retrieve audio from the Bluetooth earbuds' microphone and then playback the audio through the phone's INTERNAL speaker / through any other pair of earbuds that may be physically connected to the phone. How would I go about doing that? This is my current code:

import UIKit
import AVFoundation

class PlayRecordVC: UIViewController, AVAudioRecorderDelegate {

    let audioSession = AVAudioSession.sharedInstance()
    let player = AVAudioPlayerNode()
    let engine = AVAudioEngine()

    override func viewDidLoad() {
        super.viewDidLoad()

        do{
            try audioSession.setCategory(.playAndRecord, mode: .default, options: [.allowBluetooth])
            try audioSession.overrideOutputAudioPort(.speaker)
            try audioSession.setActive(true)
        } catch{
            print(error.localizedDescription)
        }
        let input = engine.inputNode

        engine.attach(player)

        let bus = 0
        let inputFormat = input.inputFormat(forBus: bus)

        engine.connect(player, to: engine.mainMixerNode, format: inputFormat)

        input.installTap(onBus: bus, bufferSize: 512, format: inputFormat) { (buffer, time) -> Void in
            self.player.scheduleBuffer(buffer)
            print(buffer)
        }
    }

    @IBAction func start(_ sender: UIButton) {
        try! engine.start()
        player.play()
    }

    @IBAction func stop(_ sender: UIButton) {
        engine.stop()
        player.stop()
    }

}

UPDATE:

When I add the line audioSession.overrideOutputAudioPort(.speaker) no audio plays at all (neither from the Bluetooth earbuds nor the phone's internal speaker)

I haven't tested if this actually causes microphone to still be used by the headphones, but by default to route the audio to the speakers instead of the headphones this should work:

try! audioSession.overrideOutputAudioPort(.speaker)  

Here is the documentation of the method.

There is also this category option you could give to the audio session to have that same effect but also avoid it to be reset by gestures (like attaching new headphones).

If after your test you find out this actually moves also the recording to use the internal microphone, I think there is no other way (at least no other way that I found of).

let audioSession = AVAudioSession.sharedInstance()
do {

    try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .allowBluetooth)
    try audioSession.setMode(AVAudioSessionModeDefault)
    try audioSession.setActive(true)
} catch {
print(error)
}

need to define the correct mode I believe. Not exactly sure which mode will work best in your case. https://developer.apple.com/documentation/avfoundation/avaudiosession/mode

This link below has extension for checking if microphone is plugged in. https://stackoverflow.com/a/52460651/8272698

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM