Как использовать Bluetooth-микрофон и встроенный динамик одновременно? - PullRequest
1 голос
/ 31 марта 2020

Я пытаюсь выполнить очень простую задачу в iOS. Я хотел бы получить звук с микрофона Bluetooth и одновременно воспроизводить его с помощью встроенного динамика.

Вот то, что у меня есть сейчас. Приложение позволяет пользователям выбирать динамик и источник микрофона. Однако всякий раз, когда я выбираю встроенный динамик, приложение переключается на встроенный микрофон. И когда я выбираю микрофон Bluetooth, приложение будет использовать динамик Bluetooth. Я никак не могу использовать микрофон Bluetooth и встроенный динамик по отдельности.

import UIKit
import AVFoundation
import AVKit

class ViewController: UIViewController {

    var engine = AVAudioEngine()
    let player = AVAudioPlayerNode()
    let audioSession = AVAudioSession()
    var routePickerView = AVRoutePickerView(frame: CGRect(x: 0, y: 0, width: 0, height: 50))
    let bus = 0
    var isRunning = false

    @IBOutlet weak var viewHolder: UIStackView!

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpAVRoutePicker()
        setUpAVSession()
    }

    func setUpAVRoutePicker() {
        viewHolder.addArrangedSubview(routePickerView)
    }

    func setUpAVSession() {
        do {
            try audioSession.setCategory(AVAudioSession.Category.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP, .allowAirPlay])
            try audioSession.setMode(AVAudioSession.Mode.default)
            try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
            try audioSession.setActive(true)
        } catch {
            print("Error setting up AV session!")
            print(error)
        }
    }

    @IBAction func start(_ sender: AnyObject) {
        isRunning = !isRunning
        sender.setTitle(isRunning ? "Stop" : "Start", for: .normal)

        if isRunning {
            engine.attach(player)

            let inputFormat = engine.inputNode.inputFormat(forBus: bus)

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

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

            do {
                try engine.start()
            } catch {
                print("Engine start error")
                print(error)
                return
            }
            player.play()
        } else {
            engine.inputNode.removeTap(onBus: bus)
            engine.stop()
            player.stop()
        }

    }

    @IBAction func onInputBtnClicked(_ sender: AnyObject) {
        let controller = UIAlertController(title: "Select Input", message: "", preferredStyle: UIAlertController.Style.actionSheet)

        for input in audioSession.availableInputs ?? [] {
            controller.addAction(UIAlertAction(title: input.portName, style: UIAlertAction.Style.default, handler: { action in
            do {
                try self.audioSession.setPreferredInput(input)
            } catch {
                print("Setting preferred input error")
                print(error)
            }
            }))
        }
        present(controller, animated: true, completion: nil)
    }


}

Кажется, что этого достичь невозможно ({ ссылка }), что является своего рода сумасшедший. Я знаю, что такую ​​простую задачу можно выполнить на Android, но, похоже, на iOS это невозможно. У кого-нибудь есть идеи?

p / s: Я хотел бы использовать гарнитуру Bluetooth, и я не хочу, чтобы передача осуществлялась через Wi-Fi.

1 Ответ

0 голосов
/ 31 марта 2020

Из Apple:

https://forums.developer.apple.com/thread/62954

... если приложение использует setPreferredInput для выбора входа HFP Bluetooth, выход должен автоматически изменить на выход Bluetooth HFP, соответствующий этому входу. Кроме того, выбор выхода Bluetooth HFP с помощью средства выбора маршрута MPVolumeView должен автоматически изменить вход на вход Bluetooth HFP, соответствующий этому выходу. Другими словами, и вход, и выход должны всегда находиться на одном и том же устройстве Bluetooth HFP, выбранном для ввода / вывода, даже если только вход или выход были установлены индивидуально. Это предполагаемое поведение, но если этого не происходит, мы определенно хотим знать об этом.

...