Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into liwei_temp3

newdev_shunjiawei
fdp 1 year ago
parent
commit
3b5fd269d9
  1. 3
      lib/modules/home/views/home_view.dart
  2. 64
      lib/modules/meeting/views/bottomSheet/navigation_bar_bottom_sheet.dart
  3. 26
      lib/modules/translation/views/translation_view.dart
  4. 7
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt
  5. 20
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt
  6. 16
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift
  7. 8
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift
  8. 79
      local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift

3
lib/modules/home/views/home_view.dart

@ -91,6 +91,7 @@ class HomeView extends GetView<HomeController> {
// 设备状态卡片 // 设备状态卡片
IntroStepBuilder( IntroStepBuilder(
key: const ValueKey('home_device_status'), // 添加唯一key
group: 'home', group: 'home',
order: 1, order: 1,
onWidgetLoad: () { onWidgetLoad: () {
@ -115,6 +116,7 @@ class HomeView extends GetView<HomeController> {
SizedBox(height: 20.h), SizedBox(height: 20.h),
IntroStepBuilder( IntroStepBuilder(
key: const ValueKey('home_wakeup_guide'), // 添加唯一key
group: 'home', group: 'home',
order: 2, order: 2,
getOverlayPosition: IntroOverlayBuilder.overlayPosition, getOverlayPosition: IntroOverlayBuilder.overlayPosition,
@ -719,6 +721,7 @@ class HomeView extends GetView<HomeController> {
Expanded( Expanded(
flex: 1, flex: 1,
child: IntroStepBuilder( child: IntroStepBuilder(
key: const ValueKey('home_ai_assistant'), // 添加唯一key
group: 'home', group: 'home',
order: 3, order: 3,
getOverlayPosition: IntroOverlayBuilder.overlayPosition, getOverlayPosition: IntroOverlayBuilder.overlayPosition,

64
lib/modules/meeting/views/bottomSheet/navigation_bar_bottom_sheet.dart

@ -35,38 +35,38 @@ class NavigationBarBottomSheet extends GetView<MeetingHomeController> {
controller.addMeetingAudio(); controller.addMeetingAudio();
}, },
), ),
if (controller.meetingController.type == 1) // if (controller.meetingController.type == 1)
_buildItem( // _buildItem(
context, // 传递 context 参数 // context, // 传递 context 参数
'audioVideoRecording'.tr, // 对应中文:音、视频录音 // 'audioVideoRecording'.tr, // 对应中文:音、视频录音
Icons.videocam, // Icons.videocam,
Colors.green, // Colors.green,
onTap: controller.bleManager.isConnected // onTap: controller.bleManager.isConnected
? () async { // ? () async {
Get.back(); // Get.back();
await Get.toNamed(Routes.meetingRecord, arguments: { // await Get.toNamed(Routes.meetingRecord, arguments: {
'audioTypes': 1, // 'audioTypes': 1,
}); // });
controller.addMeetingAudio(); // controller.addMeetingAudio();
} // }
: null, // : null,
), // ),
if (controller.meetingController.type == 1) // if (controller.meetingController.type == 1)
_buildItem( // _buildItem(
context, // 传递 context 参数 // context, // 传递 context 参数
'callRecording'.tr, // 对应中文:通话录音 // 'callRecording'.tr, // 对应中文:通话录音
Icons.phone, // Icons.phone,
Colors.orange, // Colors.orange,
onTap: controller.bleManager.isConnected // onTap: controller.bleManager.isConnected
? () async { // ? () async {
Get.back(); // Get.back();
await Get.toNamed(Routes.meetingRecord, arguments: { // await Get.toNamed(Routes.meetingRecord, arguments: {
'audioTypes': 2, // 'audioTypes': 2,
}); // });
controller.addMeetingAudio(); // controller.addMeetingAudio();
} // }
: null, // : null,
), // ),
_buildItem( _buildItem(
context, // 传递 context 参数 context, // 传递 context 参数
'importAudio'.tr, // 对应中文:导入音频 'importAudio'.tr, // 对应中文:导入音频

26
lib/modules/translation/views/translation_view.dart

@ -1115,19 +1115,19 @@ class TranslationView extends GetView<TranslationController> {
} }
: null, : null,
), ),
_buildModeItem( // _buildModeItem(
context, // context,
'audioVideoTranslation'.tr, // 'audioVideoTranslation'.tr,
Icons.videocam, // Icons.videocam,
Colors.orange, // Colors.orange,
onTap: controller.bleManager.isConnected // onTap: controller.bleManager.isConnected
? () async { // ? () async {
Get.back(); // Get.back();
await controller.changeTranslationMode('audioVideo'); // await controller.changeTranslationMode('audioVideo');
await controller.startRecognition(); // await controller.startRecognition();
} // }
: null, // : null,
), // ),
_buildModeItem( _buildModeItem(
context, context,
'callTranslation'.tr, 'callTranslation'.tr,

7
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt

@ -504,10 +504,9 @@ class AzureAsrHelper(private val context: Context) {
} }
// 启动音频处理 // 启动音频处理
audioStream!!.startAudioRecord( when(audioSourceType) { audioStream!!.startAudioRecord(SimpleAudioReceiver.AudioSourceType.MICROPHONE
AudioSourceType.MICROPHONE -> SimpleAudioReceiver.AudioSourceType.MICROPHONE
AudioSourceType.EXTERNAL -> SimpleAudioReceiver.AudioSourceType.EXTERNAL ,audioDataCallback)
},audioDataCallback)
audioStream!!.recordfile!!.closeFile(true) audioStream!!.recordfile!!.closeFile(true)

20
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt

@ -85,7 +85,8 @@ class SimpleAudioReceiver(private val context: Context) {
* 初始化音频录制 * 初始化音频录制
*/ */
fun initAudioRecord() { fun initAudioRecord() {
val format = getOptimalAudioFormat()
pushAudioStream = AudioInputStream.createPushStream(format)
isRunning.set(true) isRunning.set(true)
Log.d(TAG, "initAudioRecord: ${isRunning}") Log.d(TAG, "initAudioRecord: ${isRunning}")
startWriteThread() // 再启动数据读取线程 startWriteThread() // 再启动数据读取线程
@ -142,7 +143,7 @@ class SimpleAudioReceiver(private val context: Context) {
if(audioDataCallback!=null){ if(audioDataCallback!=null){
audioDataCallback?.onAudio(finalData) audioDataCallback?.onAudio(finalData)
} }
if(pushAudioStream!=null){ if(pushAudioStream!=null&&audioDataCallback==null){
pushAudioStream?.write(finalData) pushAudioStream?.write(finalData)
} }
if(recordfile!=null){ if(recordfile!=null){
@ -184,8 +185,6 @@ class SimpleAudioReceiver(private val context: Context) {
* @param callback 音频数据回调,可为空 * @param callback 音频数据回调,可为空
*/ */
fun startAudioRecord(audioSourceType: AudioSourceType, callback: AudioDataCallback?) { fun startAudioRecord(audioSourceType: AudioSourceType, callback: AudioDataCallback?) {
val format = getOptimalAudioFormat()
pushAudioStream = AudioInputStream.createPushStream(format)
this.audioSourceType = audioSourceType this.audioSourceType = audioSourceType
this.audioDataCallback = callback this.audioDataCallback = callback
writeQueue.clear() writeQueue.clear()
@ -240,8 +239,6 @@ class SimpleAudioReceiver(private val context: Context) {
try { try {
// 首先设置通话音频模式 // 首先设置通话音频模式
//setupCommunicationAudioMode() //setupCommunicationAudioMode()
val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100)
val sampleRate = supportedSampleRates.firstOrNull { rate -> val sampleRate = supportedSampleRates.firstOrNull { rate ->
val bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat) val bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat)
@ -278,7 +275,7 @@ class SimpleAudioReceiver(private val context: Context) {
} }
audioRecord?.startRecording() audioRecord?.startRecording()
Log.d("TAG", "通话模式录音开始,采样率: $sampleRate Hz") Log.d("TAG", "通话模式录音开始,采样率: $sampleRate Hz")
} catch (e: Exception) { } catch (e: Exception) {
@ -316,7 +313,8 @@ class SimpleAudioReceiver(private val context: Context) {
//setupCommunicationAudioMode() //setupCommunicationAudioMode()
// 停止录音 // 停止录音
audioRecord?.startRecording() audioRecord?.startRecording()
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "继续录音失败: ${e.message}") Log.e(TAG, "继续录音失败: ${e.message}")
} }
@ -331,11 +329,7 @@ class SimpleAudioReceiver(private val context: Context) {
// 停止录音 // 停止录音
audioRecord?.stop() audioRecord?.stop()
if(pushAudioStream != null){
pushAudioStream?.close()
pushAudioStream = null
}
// 恢复音频模式 这里会导致关闭麦克风卡住待优化 // 恢复音频模式 这里会导致关闭麦克风卡住待优化
//restoreCommunicationAudioMode() //restoreCommunicationAudioMode()

16
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift

@ -639,7 +639,7 @@ public class AzureAsrHelper: NSObject {
do { do {
print("禁用蓝牙音频功能,切换回正常音频模式") print("禁用蓝牙音频功能,切换回正常音频模式")
// audioStream?.disableBluetoothAudio() audioStream?.disableBluetoothAudio()
} catch { } catch {
print("disableBluetoothAudio") print("disableBluetoothAudio")
} }
@ -651,7 +651,7 @@ public class AzureAsrHelper: NSObject {
do { do {
print("恢复原始音频设备状态(通常是重新启用蓝牙)") print("恢复原始音频设备状态(通常是重新启用蓝牙)")
//audioStream?.restoreOriginalAudioState() audioStream?.restoreOriginalAudioState()
} catch { } catch {
print("restoreOriginalAudioState") print("restoreOriginalAudioState")
} }
@ -677,10 +677,18 @@ public class AzureAsrHelper: NSObject {
audioStream?.recordfile = RecordFile() audioStream?.recordfile = RecordFile()
} }
self.audioSourceType = .microphone
// 修复:移除多余的 audioDataCallback 参数 // 修复:移除多余的 audioDataCallback 参数
// 修复:添加类型转换
audioStream?.startAudioRecord( audioStream?.startAudioRecord(
audioSourceType: audioSourceType == .microphone ? .microphone : .external, audioSourceType: {
switch audioSourceType {
case .microphone:
return SimpleAudioReceiver.AudioSourceType.microphone
case .external:
return SimpleAudioReceiver.AudioSourceType.external
}
}(),
audioDataCallback: audioDataCallback audioDataCallback: audioDataCallback
) )

8
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift

@ -530,18 +530,16 @@ private func sendAstEvent(_ event: [String: Any]) {
if (type == 0) { if (type == 0) {
// 默认(如果有耳机选耳机,否则使用系统扬声器) // 默认(如果有耳机选耳机,否则使用系统扬声器)
azureAsrHelper.restoreOriginalAudioState(); azureAsrHelper.restoreOriginalAudioState();
// azureTtsHelper.setAudioOutputDevice() azureTtsHelper.setAudioOutputDevice()
} else if (type == 1) { } else if (type == 1) {
// 强制使用声器 // 强制使用声器
azureAsrHelper.disableBluetoothAudio(); azureAsrHelper.disableBluetoothAudio();
// azureTtsHelper.setAudioOutputDevice() azureTtsHelper.setAudioOutputDevice()
} else if (type == 2) { } else if (type == 2) {
// 强制使用耳机 // 强制使用耳机
azureAsrHelper.restoreOriginalAudioState(); azureAsrHelper.restoreOriginalAudioState();
//azureTtsHelper.setAudioOutputDevice() azureTtsHelper.setAudioOutputDevice()
} }

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

@ -392,7 +392,82 @@ public class SimpleAudioReceiver: NSObject {
} }
// MARK: - 协议定义
/**
* 禁用蓝牙音频功能,切换回正常音频模式
* 强制使用设备内置扬声器或听筒
*/
public func disableBluetoothAudio() {
do {
print("禁用蓝牙音频功能,切换回正常音频模式")
// 暂停当前音频引擎
if _isWriting {
audioEngine?.pause()
try audioSession.setActive(false)
}
// 设置音频会话为不允许蓝牙
try audioSession.setCategory(
.playAndRecord,
mode: .videoChat,
options: [.defaultToSpeaker, .mixWithOthers] // 移除 .allowBluetooth
)
// 强制使用扬声器
try audioSession.overrideOutputAudioPort(.speaker)
// 重新激活音频会话
if _isWriting {
try audioSession.setActive(true)
try audioEngine?.start()
}
// 更新当前路由状态
currentRoute = .speaker
} catch {
print("禁用蓝牙音频失败: \(error.localizedDescription)")
}
}
/**
* 恢复原始音频设备状态(重新启用蓝牙)
* 允许系统自动选择最佳音频设备
*/
public func restoreOriginalAudioState() {
do {
print("恢复原始音频设备状态(重新启用蓝牙)")
// 暂停当前音频引擎
if _isWriting {
audioEngine?.pause()
try audioSession.setActive(false)
}
// 恢复完整的蓝牙音频支持
try audioSession.setCategory(
.playAndRecord,
mode: .videoChat,
options: [.defaultToSpeaker, .allowBluetooth, .mixWithOthers]
)
// 取消音频端口覆盖,让系统自动选择
try audioSession.overrideOutputAudioPort(.none)
// 重新激活音频会话
if _isWriting {
try audioSession.setActive(true)
try audioEngine?.start()
}
// 重置路由状态,让系统自动选择
currentRoute = nil
} catch {
print("恢复原始音频状态失败: \(error.localizedDescription)")
}
}
public func stopMicrophoneCapture() { public func stopMicrophoneCapture() {
@ -596,5 +671,5 @@ private class LinkedBlockingQueue<T> {
} }
} }
// MARK: - 协议定义

Loading…
Cancel
Save