|
|
@ -131,7 +131,7 @@ public class AzureAsrHelper: NSObject { |
|
|
*/ |
|
|
*/ |
|
|
private func preInitializeAudioComponents() { |
|
|
private func preInitializeAudioComponents() { |
|
|
if audioStream == nil { |
|
|
if audioStream == nil { |
|
|
audioStream = AudioStream() |
|
|
audioStream = AudioStream(parentHelper: self) |
|
|
audioStream?.initAudioRecord() |
|
|
audioStream?.initAudioRecord() |
|
|
audioStream?.onAudioData = { [weak self] data in |
|
|
audioStream?.onAudioData = { [weak self] data in |
|
|
self?.recordfile?.saveAudioDataToWav(data) |
|
|
self?.recordfile?.saveAudioDataToWav(data) |
|
|
@ -354,7 +354,7 @@ public class AzureAsrHelper: NSObject { |
|
|
do { |
|
|
do { |
|
|
// 【优化】检查是否已经初始化,避免重复创建 |
|
|
// 【优化】检查是否已经初始化,避免重复创建 |
|
|
if audioStream == nil { |
|
|
if audioStream == nil { |
|
|
audioStream = AudioStream() |
|
|
audioStream = AudioStream(parentHelper: self) |
|
|
audioStream?.initAudioRecord() |
|
|
audioStream?.initAudioRecord() |
|
|
audioStream?.onAudioData = { [weak self] data in |
|
|
audioStream?.onAudioData = { [weak self] data in |
|
|
self?.recordfile?.saveAudioDataToWav(data) |
|
|
self?.recordfile?.saveAudioDataToWav(data) |
|
|
@ -548,6 +548,7 @@ public class AzureAsrHelper: NSObject { |
|
|
public func disableBluetoothAudio() { |
|
|
public func disableBluetoothAudio() { |
|
|
|
|
|
|
|
|
do { |
|
|
do { |
|
|
|
|
|
print("禁用蓝牙音频功能,切换回正常音频模式") |
|
|
audioStream?.setAudioOutputRoute(.speaker) |
|
|
audioStream?.setAudioOutputRoute(.speaker) |
|
|
} catch { |
|
|
} catch { |
|
|
print("disableBluetoothAudio") |
|
|
print("disableBluetoothAudio") |
|
|
@ -559,6 +560,7 @@ public class AzureAsrHelper: NSObject { |
|
|
public func restoreOriginalAudioState() { |
|
|
public func restoreOriginalAudioState() { |
|
|
|
|
|
|
|
|
do { |
|
|
do { |
|
|
|
|
|
print("恢复原始音频设备状态(通常是重新启用蓝牙)") |
|
|
audioStream?.setAudioOutputRoute(.receiver) |
|
|
audioStream?.setAudioOutputRoute(.receiver) |
|
|
} catch { |
|
|
} catch { |
|
|
print("restoreOriginalAudioState") |
|
|
print("restoreOriginalAudioState") |
|
|
@ -632,9 +634,18 @@ public class AzureAsrHelper: NSObject { |
|
|
private var isRunning = false |
|
|
private var isRunning = false |
|
|
public var isWriting = false |
|
|
public var isWriting = false |
|
|
private let bufferSize: Int = 4096 |
|
|
private let bufferSize: Int = 4096 |
|
|
private var writeThread: DispatchQueue? |
|
|
private var writeThread: DispatchQueue? |
|
|
private var currentRoute: AudioOutputRoute? |
|
|
private var currentRoute: AudioOutputRoute? |
|
|
public var onAudioData: ((Data) -> Void)? |
|
|
public var onAudioData: ((Data) -> Void)? |
|
|
|
|
|
|
|
|
|
|
|
// 添加对外部类的弱引用 |
|
|
|
|
|
private weak var parentHelper: AzureAsrHelper? |
|
|
|
|
|
|
|
|
|
|
|
// 添加初始化方法,接收外部类引用 |
|
|
|
|
|
init(parentHelper: AzureAsrHelper) { |
|
|
|
|
|
self.parentHelper = parentHelper |
|
|
|
|
|
super.init() |
|
|
|
|
|
} |
|
|
/** |
|
|
/** |
|
|
* 初始化 |
|
|
* 初始化 |
|
|
*/ |
|
|
*/ |
|
|
@ -654,7 +665,7 @@ public class AzureAsrHelper: NSObject { |
|
|
// 创建新的写线程 |
|
|
// 创建新的写线程 |
|
|
writeThread = DispatchQueue(label: "audio.stream.writer") |
|
|
writeThread = DispatchQueue(label: "audio.stream.writer") |
|
|
startWriteThread() |
|
|
startWriteThread() |
|
|
self.setAudioOutputRoute(.receiver) |
|
|
//self.setAudioOutputRoute(.receiver) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// 获取最佳音频格式 (iOS 通常支持标准采样率) |
|
|
/// 获取最佳音频格式 (iOS 通常支持标准采样率) |
|
|
@ -717,7 +728,8 @@ public class AzureAsrHelper: NSObject { |
|
|
* @param data 音频数据字节数组 |
|
|
* @param data 音频数据字节数组 |
|
|
*/ |
|
|
*/ |
|
|
public func saveAudioDataTo(data: Data) { |
|
|
public func saveAudioDataTo(data: Data) { |
|
|
if audioSourceType != .external { |
|
|
// 通过父类引用调用方法 |
|
|
|
|
|
if audioSourceType != .external || !(parentHelper?.isContinuousRecognitionActive() ?? false) { |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
// print("外部data=\(data)") |
|
|
// print("外部data=\(data)") |
|
|
@ -879,8 +891,7 @@ private func runMicrophoneCapture() { |
|
|
case bluetooth |
|
|
case bluetooth |
|
|
} |
|
|
} |
|
|
public func setAudioOutputRoute(_ route: AudioOutputRoute) { |
|
|
public func setAudioOutputRoute(_ route: AudioOutputRoute) { |
|
|
guard currentRoute != route else { return } |
|
|
|
|
|
print("setAudioOutputRoute") |
|
|
|
|
|
do { |
|
|
do { |
|
|
// |
|
|
// |
|
|
if self.isWriting { |
|
|
if self.isWriting { |
|
|
@ -890,14 +901,15 @@ private func runMicrophoneCapture() { |
|
|
try audioSession.setActive(false) |
|
|
try audioSession.setActive(false) |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
print("setAudioOutputRoutecurrent,route=\(route)") |
|
|
switch route { |
|
|
switch route { |
|
|
case .speaker: |
|
|
case .speaker: |
|
|
|
|
|
print("setAudioOutputRoutecurrent,speaker") |
|
|
// 使用扬声器时必须用videoChat模式 |
|
|
// 使用扬声器时必须用videoChat模式 |
|
|
try audioSession.setCategory( |
|
|
try audioSession.setCategory( |
|
|
.playAndRecord, |
|
|
.playAndRecord, |
|
|
mode: .videoChat, |
|
|
mode: .videoChat, |
|
|
options: [.allowBluetooth, .mixWithOthers, .defaultToSpeaker] |
|
|
options: [.defaultToSpeaker] |
|
|
) |
|
|
) |
|
|
try audioSession.overrideOutputAudioPort(.speaker) |
|
|
try audioSession.overrideOutputAudioPort(.speaker) |
|
|
|
|
|
|
|
|
@ -906,7 +918,7 @@ private func runMicrophoneCapture() { |
|
|
try audioSession.setCategory( |
|
|
try audioSession.setCategory( |
|
|
.playAndRecord, |
|
|
.playAndRecord, |
|
|
mode: .voiceChat, |
|
|
mode: .voiceChat, |
|
|
options: [.allowBluetooth, .mixWithOthers, .defaultToSpeaker] |
|
|
options: [.allowBluetooth] |
|
|
) |
|
|
) |
|
|
try audioSession.overrideOutputAudioPort(.none) |
|
|
try audioSession.overrideOutputAudioPort(.none) |
|
|
|
|
|
|
|
|
|