【问题标题】:How to use a bluetooth microphone and a built-in speaker at the same time?如何同时使用蓝牙麦克风和内置扬声器?
【发布时间】:2020-07-11 11:14:43
【问题描述】:

我正在尝试在 iOS 中完成一项非常简单的任务。我想从蓝牙麦克风获取音频并使用内置扬声器同时播放音频。

这就是我现在所拥有的。该应用程序允许用户选择扬声器和麦克风源。但是,每当我选择内置扬声器时,应用程序都会切换到内置麦克风。每当我选择蓝牙麦克风时,该应用程序都会使用蓝牙扬声器。我无法单独使用蓝牙麦克风和内置扬声器。

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)
    }


}

这似乎是不可能实现的 (https://stackoverflow.com/a/24519938/6308776),这有点疯狂。我知道在 Android 上可以实现这样一个简单的任务,但对于 iOS 来说似乎是不可能的。有人有什么想法吗?

p/s:我想用蓝牙耳机,不想用wifi传输。

【问题讨论】:

    标签: ios swift iphone bluetooth microphone


    【解决方案1】:

    来自苹果:

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

    ...如果应用程序正在使用 setPreferredInput 选择蓝牙 HFP输入,输出应自动改为蓝牙 与该输入对应的 HFP 输出。此外,选择一个 使用 MPVolumeView 的路由选择器的蓝牙 HFP 输出应该 自动将输入更改为蓝牙 HFP 输入 对应于该输出。换句话说,输入和 输出应始终在选择的同一蓝牙 HFP 设备上结束 即使只设置了输入或输出,也适用于输入/输出 分别。这是预期的行为,但如果它没有发生 我们肯定想知道。

    【讨论】:

    猜你喜欢
    • 2022-06-16
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    相关资源
    最近更新 更多