AVAudioSession 无法识别来自蓝牙设备的音频
AVAudioSession does not recognise audio from bluetooth device
我正在使用 AVAudioSession 来收听语音输入。它适用于有线耳机,但不适用于连接的蓝牙设备。以下是我用来设置蓝牙麦克风输入的代码
func setupSessionForRecording() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: [.allowBluetooth])
} catch let error as NSError {
debugPrint("Error in listening "+error.localizedDescription)
}
var inputsPriority: [(type: String, input: AVAudioSessionPortDescription?)] = [
(AVAudioSessionPortLineIn, nil),
(AVAudioSessionPortHeadsetMic, nil),
(AVAudioSessionPortBluetoothHFP, nil),
(AVAudioSessionPortUSBAudio, nil),
(AVAudioSessionPortCarAudio, nil),
(AVAudioSessionPortBuiltInMic, nil),
]
for availableInput in audioSession.availableInputs! {
guard let index = inputsPriority.index(where: { [=10=].type == availableInput.portType }) else { continue }
inputsPriority[index].input = availableInput
}
guard let input = inputsPriority.filter({ [=10=].input != nil }).first?.input else {
fatalError("No Available Ports For Recording")
}
do {
try audioSession.setPreferredInput(input)
try audioSession.setMode(AVAudioSessionModeMeasurement)
try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
try audioSession.setPreferredIOBufferDuration(10)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
此代码停止从设备麦克风获取输入,我还在蓝牙耳机中听到它已准备好收听的声音,但它没有从设备获取任何输入。
此外,
当我尝试在蓝牙耳机中播放任何音频时,它不起作用。这是播放音频的代码
do {
let output = AVAudioSession.sharedInstance().currentRoute.outputs[0].portType
if output == "Receiver" || output == "Speaker"{
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
}
else{
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
}
print("Voice Out \(output)" )
} catch let error as NSError {
print("audioSession error: \(error.localizedDescription)")
os_log("Error during changing the current audio route: %@" , log: PollyVoiceViewController.log, type: .error, error)
} catch {
os_log("Unknown error during changing the current audio route", log: PollyVoiceViewController.log, type: .error)
}
do {
let soundData = try Data(contentsOf: url as URL)
self.audioPlayer = try AVAudioPlayer(data: soundData)
self.audioPlayer?.prepareToPlay()
self.audioPlayer?.volume = 3.0
self.audioPlayer?.delegate = self
self.audioPlayer?.play()
} catch let error as NSError {
print("Error getting the audio file"+error.description)
}
原因是:BluetoothHFP 在AVAudioSessionModeMeasurement
模式下不可用
设置try audioSession.setMode(AVAudioSessionModeMeasurement)
后,audioSession.availableInputs
不包含BluetoothHFP
。
This mode is intended for apps that need to minimize the amount of system-supplied signal processing to input and output signals. If recording on devices with more than one built-in microphone, the primary microphone is used.
的文档中
AVAudioSessionPortDescription
必须在 availableInputs
数组中。
The value of the inPort parameter must be one of the AVAudioSessionPortDescription objects in the availableInputs array. If this parameter specifies a port that is not already part of the current audio route and the app’s session controls audio routing, this method initiates a route change to use the preferred port.
并且必须在设置模式后设置。
You must set a preferred input port only after setting the audio session’s category and mode and activating the session.
我正在使用 AVAudioSession 来收听语音输入。它适用于有线耳机,但不适用于连接的蓝牙设备。以下是我用来设置蓝牙麦克风输入的代码
func setupSessionForRecording() { let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: [.allowBluetooth]) } catch let error as NSError { debugPrint("Error in listening "+error.localizedDescription) } var inputsPriority: [(type: String, input: AVAudioSessionPortDescription?)] = [ (AVAudioSessionPortLineIn, nil), (AVAudioSessionPortHeadsetMic, nil), (AVAudioSessionPortBluetoothHFP, nil), (AVAudioSessionPortUSBAudio, nil), (AVAudioSessionPortCarAudio, nil), (AVAudioSessionPortBuiltInMic, nil), ] for availableInput in audioSession.availableInputs! { guard let index = inputsPriority.index(where: { [=10=].type == availableInput.portType }) else { continue } inputsPriority[index].input = availableInput } guard let input = inputsPriority.filter({ [=10=].input != nil }).first?.input else { fatalError("No Available Ports For Recording") } do { try audioSession.setPreferredInput(input) try audioSession.setMode(AVAudioSessionModeMeasurement) try audioSession.setActive(true, with: .notifyOthersOnDeactivation) try audioSession.setPreferredIOBufferDuration(10) } catch { fatalError("Error Setting Up Audio Session") } }
此代码停止从设备麦克风获取输入,我还在蓝牙耳机中听到它已准备好收听的声音,但它没有从设备获取任何输入。
此外,
当我尝试在蓝牙耳机中播放任何音频时,它不起作用。这是播放音频的代码
do { let output = AVAudioSession.sharedInstance().currentRoute.outputs[0].portType if output == "Receiver" || output == "Speaker"{ try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker) } else{ try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none) } print("Voice Out \(output)" ) } catch let error as NSError { print("audioSession error: \(error.localizedDescription)") os_log("Error during changing the current audio route: %@" , log: PollyVoiceViewController.log, type: .error, error) } catch { os_log("Unknown error during changing the current audio route", log: PollyVoiceViewController.log, type: .error) } do { let soundData = try Data(contentsOf: url as URL) self.audioPlayer = try AVAudioPlayer(data: soundData) self.audioPlayer?.prepareToPlay() self.audioPlayer?.volume = 3.0 self.audioPlayer?.delegate = self self.audioPlayer?.play() } catch let error as NSError { print("Error getting the audio file"+error.description) }
原因是:BluetoothHFP 在AVAudioSessionModeMeasurement
模式下不可用
设置try audioSession.setMode(AVAudioSessionModeMeasurement)
后,audioSession.availableInputs
不包含BluetoothHFP
。
的文档中This mode is intended for apps that need to minimize the amount of system-supplied signal processing to input and output signals. If recording on devices with more than one built-in microphone, the primary microphone is used.
AVAudioSessionPortDescription
必须在 availableInputs
数组中。
The value of the inPort parameter must be one of the AVAudioSessionPortDescription objects in the availableInputs array. If this parameter specifies a port that is not already part of the current audio route and the app’s session controls audio routing, this method initiates a route change to use the preferred port.
并且必须在设置模式后设置。
You must set a preferred input port only after setting the audio session’s category and mode and activating the session.