Browse Source

feat(azure_speech): 添加iOS项目基础文件和音频接收器HFP支持

修复音频会话配置逻辑,优化蓝牙耳机兼容性
添加iOS Runner项目文件和测试用例
更新音频接收器以支持HFP模式
newdev_shunjiawei
liwei1dao 9 months ago
parent
commit
7ee76a9248
  1. 81
      local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift
  2. 2
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleCommandSender.kt
  3. 2
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

81
local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift

@ -55,6 +55,7 @@ public class SimpleAudioReceiver: NSObject {
//public var onAudioData: ((Data) -> Void)?
public var recordfile: RecordFile?
public var isHeadphones = true
public var isReceiverHFP = false // 是否是接收HFP音频
/**
* 初始化
@ -119,6 +120,7 @@ public class SimpleAudioReceiver: NSObject {
print("AudioStream音频配置设置完成")
}
/**
* 开始音频输入
*/
@ -129,9 +131,11 @@ public class SimpleAudioReceiver: NSObject {
print("startAudioRecord=audioSourceType\(audioSourceType)")
switch audioSourceType {
case .microphone:
runMicrophoneCapture()
isReceiverHFP = true
runMicrophoneCapture()
case .external:
runExternalCapture()
isReceiverHFP = false
runExternalCapture()
}
}
@ -225,20 +229,14 @@ public class SimpleAudioReceiver: NSObject {
*/
private func runExternalCapture() {
if audioSourceType == .external {
// do {
// try audioSession.setCategory(.playback,
// mode: .videoChat,
// options: [ .mixWithOthers,.allowBluetoothA2DP // 允许蓝牙耳机,不占用hfp链路
// ]) // 添加音频优先级控制
// try audioSession.overrideOutputAudioPort(.none)
// try audioSession.setActive(true)
// } catch {
// print("设置音频会话失败: \(error.localizedDescription)")
// }
do {
// 根据通话状态进行安全的音频会话配置
try safeConfigureAudioSessionForMic()
} catch {
print("设置音频会话失败: \(error.localizedDescription)")
}
//pushAudioData(data: Data())
micCapture.stopCapture()
}
}
/**
@ -254,26 +252,47 @@ public class SimpleAudioReceiver: NSObject {
let desiredCategory: AVAudioSession.Category
let desiredMode: AVAudioSession.Mode
let desiredOptions: AVAudioSession.CategoryOptions
if isTelephonyActive() {
// 通话中:录音优先,避免 A2DP(仅播放),改用 HFP(.allowBluetooth)
desiredCategory = .record
desiredMode = .voiceChat
desiredOptions = [.allowBluetooth]
} else {
if(isHeadphones){
// 非通话:保持原有逻辑,但使用 .allowBluetooth 以支持录音(而不是 A2DP)
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.allowBluetooth, .mixWithOthers, .defaultToSpeaker]
//desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}else{
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.mixWithOthers, .defaultToSpeaker]
if isReceiverHFP {
if isTelephonyActive() {
// 通话中:录音优先,避免 A2DP(仅播放),改用 HFP(.allowBluetooth)
desiredCategory = .record
desiredMode = .voiceChat
desiredOptions = [.allowBluetooth]
} else {
if(isHeadphones){
// 非通话:保持原有逻辑,但使用 .allowBluetooth 以支持录音(而不是 A2DP)
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.allowBluetooth, .mixWithOthers, .defaultToSpeaker]
//desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}else{
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}
}
}else{
if isTelephonyActive() {
// 通话中:录音优先,避免 A2DP(仅播放),改用 HFP(.allowBluetooth)
desiredCategory = .record
desiredMode = .voiceChat
desiredOptions = [.allowBluetoothA2DP]
} else {
if(isHeadphones){
// 非通话:保持原有逻辑,但使用 .allowBluetooth 以支持录音(而不是 A2DP)
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.allowBluetoothA2DP, .mixWithOthers, .defaultToSpeaker]
//desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}else{
desiredCategory = .playAndRecord
desiredMode = .videoChat
desiredOptions = [.mixWithOthers, .defaultToSpeaker]
}
}
}
// 仅在类别或模式变化时才调用 setCategory,避免触发不必要的 categoryChange
let needsSetCategory = (audioSession.category != desiredCategory) || (audioSession.mode != desiredMode)
if needsSetCategory {

2
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleCommandSender.kt

@ -456,7 +456,7 @@ class BleCommandSender {
fun processDeviceNotification(data: ByteArray) {
Log.d(
TAG,
"收到设备主动上报: ${data.joinToString(", ") { "0x${(it.toInt() and 0xFF).toString(16)}" }}"
"ble指令----------- 收到设备主动上报: ${data.joinToString(", ") { "0x${(it.toInt() and 0xFF).toString(16)}" }}"
)
if (data.size < 3) {
Log.e(TAG, "设备主动上报数据格式错误:数据长度过短")

2
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

@ -973,7 +973,7 @@ object BleService {
}
// 通知特征数据(命令和控制)
BleConst.NOTIFY_CHAR_UUID -> {
Log.i(TAG, "收到通知特征数据(命令和控制)")
Log.i(TAG, "ble指令----------- 收到通知特征数据(命令和控制)")
// 判断数据类型
when {
// 设备响应 (0xBB开头)

Loading…
Cancel
Save