Browse Source

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

newdev_shunjiawei
lxm 1 year ago
parent
commit
4dcbd7e8b1
  1. 99
      lib/core/widgets/intro_overlay_builder.dart
  2. 6
      lib/modules/agent/views/agent_view.dart
  3. 2
      lib/modules/home/views/home_view.dart
  4. 3
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt
  5. 376
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift
  6. 27
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/IntegratedSpeechTranslationService.swift
  7. 6
      local_plugins/azure_speech/ios/azure_speech/Sources/tools/SimpleAudioReceiver.swift
  8. 16
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt
  9. 18
      local_plugins/chat_api/ios/chat_api/Sources/chat_api/ChatApiService.swift

99
lib/core/widgets/intro_overlay_builder.dart

@ -44,7 +44,7 @@ class IntroOverlayBuilder {
child: Lottie.asset('assets/lottie/intro_foriday.json'), child: Lottie.asset('assets/lottie/intro_foriday.json'),
), ),
Padding( Padding(
padding: EdgeInsets.only(bottom: 20.w), padding: EdgeInsets.only(bottom: 10.w),
child: Text( child: Text(
isWakeup ? '我在呢~' : title, isWakeup ? '我在呢~' : title,
style: TextStyle( style: TextStyle(
@ -74,50 +74,71 @@ class IntroOverlayBuilder {
Function? onNext, Function? onNext,
Function? onFinish, Function? onFinish,
}) { }) {
return Column( double height =
crossAxisAlignment: (params.offset?.dy ?? 0) - ScreenUtil().statusBarHeight - 20.w;
alignment ? CrossAxisAlignment.start : CrossAxisAlignment.end, double left = params.offset?.dx ?? 0;
children: [ double right = 1.sw - left - params.size.width;
Padding( return SizedBox(
padding: EdgeInsets.only(bottom: 10.w), height: height,
child: Text( child: Column(
text, mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: TextStyle( children: [
fontSize: 15.sp, Container(
color: Colors.white, padding: EdgeInsetsGeometry.all(12.w),
fontWeight: FontWeight.bold, alignment: Alignment.centerRight,
), child: _button(
),
),
Row(
children: [
if (onNext != null)
_button(
buttonText,
() {
params.onNext!();
onNext();
},
),
if (onFinish != null)
_button(
buttonText,
() {
params.onFinish();
onFinish();
},
),
if (onNext != null || onFinish != null) const Spacer(),
_button(
'跳过', '跳过',
() { () {
params.onFinish(); params.onFinish();
}, },
isSkip: true, isSkip: true,
), ),
], ),
), Padding(
], padding: EdgeInsets.only(
left: alignment ? left : 12.w,
right: alignment ? 12.w : right,
),
child: Column(
crossAxisAlignment:
alignment ? CrossAxisAlignment.start : CrossAxisAlignment.end,
children: [
Padding(
padding: EdgeInsets.only(bottom: 10.w),
child: Text(
text,
style: TextStyle(
fontSize: 15.sp,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
Row(
children: [
if (onNext != null)
_button(
buttonText,
() {
params.onNext!();
onNext();
},
),
if (onFinish != null)
_button(
buttonText,
() {
params.onFinish();
onFinish();
},
),
],
),
],
),
),
],
),
); );
} }

6
lib/modules/agent/views/agent_view.dart

@ -242,6 +242,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
? IntroStepBuilder( ? IntroStepBuilder(
group: 'ai', group: 'ai',
order: 4, order: 4,
getOverlayPosition:
IntroOverlayBuilder.overlayPosition,
overlayBuilder: (params) { overlayBuilder: (params) {
return IntroOverlayBuilder.aiBuilder( return IntroOverlayBuilder.aiBuilder(
params, params,
@ -504,6 +506,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
return IntroStepBuilder( return IntroStepBuilder(
group: 'ai', group: 'ai',
order: 1, order: 1,
getOverlayPosition:
IntroOverlayBuilder.overlayPosition,
overlayBuilder: (params) { overlayBuilder: (params) {
return IntroOverlayBuilder.aiBuilder( return IntroOverlayBuilder.aiBuilder(
params, params,
@ -751,6 +755,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
widgetParams!.onNext!(); widgetParams!.onNext!();
controller.sendMessage(); controller.sendMessage();
}, },
getOverlayPosition:
IntroOverlayBuilder.overlayPosition,
overlayBuilder: (params) { overlayBuilder: (params) {
widgetParams = params; widgetParams = params;
return IntroOverlayBuilder.aiBuilder( return IntroOverlayBuilder.aiBuilder(

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

@ -101,6 +101,7 @@ class HomeView extends GetView<HomeController> {
onWidgetLoad: () { onWidgetLoad: () {
controller.noviceGuideService.startHomeGuide(); controller.noviceGuideService.startHomeGuide();
}, },
getOverlayPosition: IntroOverlayBuilder.overlayPosition,
overlayBuilder: (params) { overlayBuilder: (params) {
return IntroOverlayBuilder.aiBuilder( return IntroOverlayBuilder.aiBuilder(
params, params,
@ -743,6 +744,7 @@ class HomeView extends GetView<HomeController> {
Intro.of(Get.context!).dispose(); Intro.of(Get.context!).dispose();
controller.exploreAIFeatures(); controller.exploreAIFeatures();
}, },
getOverlayPosition: IntroOverlayBuilder.overlayPosition,
overlayBuilder: (params) { overlayBuilder: (params) {
return IntroOverlayBuilder.aiBuilder( return IntroOverlayBuilder.aiBuilder(
params, params,

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

@ -145,8 +145,9 @@ class SimpleAudioReceiver(private val context: Context) {
} }
pushAudioStream?.write(finalData) pushAudioStream?.write(finalData)
if(recordfile!=null){
recordfile?.saveAudioDataToWav(finalData) recordfile?.saveAudioDataToWav(finalData)
}
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "写入失败: ${e.message}") Log.e(TAG, "写入失败: ${e.message}")

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

@ -20,16 +20,40 @@ import ble_service
// 日志对象 // 日志对象
private let log = OSLog(subsystem: "com.azure.speech", category: "AzureSpeechPlugin") private let log = OSLog(subsystem: "com.azure.speech", category: "AzureSpeechPlugin")
// 替换原有的 StreamHandler 类
private typealias AsrEventStreamHandler = BaseEventStreamHandler
private typealias TtsEventStreamHandler = BaseEventStreamHandler
private typealias AudioDataEventStreamHandler = BaseEventStreamHandler
private typealias AstEventStreamHandler = BaseEventStreamHandler
// 事件类型枚举
public enum EventType {
case asr
case tts
case audioData
case ast
}
/**
* 通道配置结构体
*/
private struct ChannelConfig {
let methodChannelName: String
let eventChannelName: String
let eventType: EventType
let methodHandler: (FlutterMethodCall, @escaping FlutterResult) -> Void
}
// ASR相关 // ASR相关
private var asrChannel: FlutterMethodChannel? private var asrChannel: FlutterMethodChannel?
private var asrEventChannel: FlutterEventChannel? private var asrEventChannel: FlutterEventChannel?
private var asrEventSink: FlutterEventSink? internal var asrEventSink: FlutterEventSink?
private let azureAsrHelper = AzureAsrHelper() private let azureAsrHelper = AzureAsrHelper()
// TTS相关 // TTS相关
private var ttsChannel: FlutterMethodChannel? private var ttsChannel: FlutterMethodChannel?
private var ttsEventChannel: FlutterEventChannel? private var ttsEventChannel: FlutterEventChannel?
private var ttsEventSink: FlutterEventSink? internal var ttsEventSink: FlutterEventSink?
private let azureTtsHelper = AzureTtsHelper() private let azureTtsHelper = AzureTtsHelper()
// 是否已添加TTS事件监听器 // 是否已添加TTS事件监听器
@ -37,98 +61,152 @@ import ble_service
// AST相关 // AST相关
private var astChannel: FlutterMethodChannel? private var astChannel: FlutterMethodChannel?
private var astEventChannel: FlutterEventChannel? private var astEventChannel: FlutterEventChannel?
internal var astEventSink: FlutterEventSink?
private let azureAstHelper = IntegratedSpeechTranslationService() private let azureAstHelper = IntegratedSpeechTranslationService()
// 音频数据相关
private var audioDataEventChannel: FlutterEventChannel?
internal var audioDataEventSink: FlutterEventSink?
// 创建事件回调 // 创建事件回调
private var astEventCallback: AstEventCallback? private var astEventCallback: AstEventCallback?
// 是否已添加AST事件监听器 // 是否已添加AST事件监听器
private var isAstListenerAdded = false private var isAstListenerAdded = false
// 当前的连续识别回调 // 当前的连续识别回调
private var currentAsrCallback: AsrCallbackWrapper? private var currentAsrCallback: AsrCallbackWrapper?
// 插件注册 // 添加音频数据回调实例作为类属性
public static func register(with registrar: FlutterPluginRegistrar) { private lazy var audioDataCallback: AudioDataCallbackImpl = {
let instance = AzureSpeechPlugin() return AudioDataCallbackImpl { [weak self] data in
// 2. 初始化BleService并注册回调 self?.handleAudioData(data)
BleService.shared.addCallback(instance)
// 初始化ASR通道
let asrChannel = FlutterMethodChannel(name: "azure_speech/asr", binaryMessenger: registrar.messenger())
registrar.addMethodCallDelegate(instance, channel: asrChannel)
instance.asrChannel = asrChannel
// 设置ASR通道处理器 - 使用实例方法
asrChannel.setMethodCallHandler { [weak instance] (call, result) in
instance?.handleAsrMethodCall(call, result: result)
} }
}()
// 初始化TTS通道
let ttsChannel = FlutterMethodChannel(name: "azure_speech/tts", binaryMessenger: registrar.messenger())
registrar.addMethodCallDelegate(instance, channel: ttsChannel) /**
instance.ttsChannel = ttsChannel * 初始化通道的通用方法
* @param registrar Flutter插件注册器
// 设置TTS通道处理器 - 使用实例方法 * @param config 通道配置
ttsChannel.setMethodCallHandler { [weak instance] (call, result) in */
instance?.handleTtsMethodCall(call, result: result) private func setupChannel(registrar: FlutterPluginRegistrar, config: ChannelConfig) {
// 初始化方法通道
let methodChannel = FlutterMethodChannel(name: config.methodChannelName, binaryMessenger: registrar.messenger())
methodChannel.setMethodCallHandler { [weak self] (call, result) in
config.methodHandler(call, result)
} }
// 初始化事件通道
let eventChannel = FlutterEventChannel(name: config.eventChannelName, binaryMessenger: registrar.messenger())
eventChannel.setStreamHandler(BaseEventStreamHandler(instance: self, eventType: config.eventType))
// 初始化AST通道 // 保存通道引用
let astChannel = FlutterMethodChannel(name: "azure_speech/ast", binaryMessenger: registrar.messenger()) switch config.eventType {
registrar.addMethodCallDelegate(instance, channel: astChannel) case .asr:
instance.astChannel = astChannel self.asrChannel = methodChannel
self.asrEventChannel = eventChannel
// 设置AST通道处理器 - 使用实例方法 case .tts:
astChannel.setMethodCallHandler { [weak instance] (call, result) in self.ttsChannel = methodChannel
instance?.handleAstMethodCall(call, result: result) self.ttsEventChannel = eventChannel
case .audioData:
self.audioDataEventChannel = eventChannel
case .ast:
self.astChannel = methodChannel
self.astEventChannel = eventChannel
} }
// 初始化ASR事件通道
let asrEventChannel = FlutterEventChannel(name: "azure_speech/asr_events", binaryMessenger: registrar.messenger())
asrEventChannel.setStreamHandler(instance)
instance.asrEventChannel = asrEventChannel
// 初始化TTS事件通道
let ttsEventChannel = FlutterEventChannel(name: "azure_speech/tts_events", binaryMessenger: registrar.messenger())
ttsEventChannel.setStreamHandler(instance)
instance.ttsEventChannel = ttsEventChannel
// 初始化TTS事件通道
let astEventChannel = FlutterEventChannel(name: "azure_speech/asr_events", binaryMessenger: registrar.messenger())
astEventChannel.setStreamHandler(instance)
instance.astEventChannel = astEventChannel
} }
// 发送ASR事件方法 /**
internal func sendAsrEvent(_ event: [String: Any]) { * 统一的事件发送方法
if asrEventSink == nil { * @param event 事件数据
os_log("无法发送ASR事件:事件通道未准备好", log: log, type: .error) * @param type 事件类型
return */
} private func sendEvent(_ event: [String: Any], type: EventType) {
let eventSink: FlutterEventSink?
DispatchQueue.main.async { [weak self] in let logMessage: String
guard let self = self else { return }
self.asrEventSink?(event) switch type {
} case .asr:
eventSink = asrEventSink
logMessage = "无法发送ASR事件:事件通道未准备好"
case .tts:
eventSink = ttsEventSink
logMessage = "无法发送TTS事件:事件通道未准备好"
case .audioData:
eventSink = audioDataEventSink
logMessage = "无法发送音频数据事件:事件通道未准备好"
case .ast:
eventSink = astEventSink
logMessage = "无法发送AST事件:事件通道未准备好"
} }
// 发送TTS事件方法 guard eventSink != nil else {
private func sendTtsEvent(_ event: [String: Any]) { os_log("%@", log: log, type: .error, logMessage)
if ttsEventSink == nil { return
os_log("无法发送TTS事件:事件通道未准备好", log: log, type: .error) }
return
} DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
eventSink?(event)
}
}
// 插件注册
public static func register(with registrar: FlutterPluginRegistrar) {
let instance = AzureSpeechPlugin()
BleService.shared.addCallback(instance)
DispatchQueue.main.async { [weak self] in // 配置所有通道
guard let self = self else { return } let channelConfigs = [
self.ttsEventSink?(event) ChannelConfig(
methodChannelName: "azure_speech/asr",
eventChannelName: "azure_speech/asr_events",
eventType: .asr,
methodHandler: instance.handleAsrMethodCall
),
ChannelConfig(
methodChannelName: "azure_speech/tts",
eventChannelName: "azure_speech/tts_events",
eventType: .tts,
methodHandler: instance.handleTtsMethodCall
),
ChannelConfig(
methodChannelName: "azure_speech/ast",
eventChannelName: "azure_speech/ast_events",
eventType: .ast,
methodHandler: instance.handleAstMethodCall
)
]
// 批量初始化通道
for config in channelConfigs {
instance.setupChannel(registrar: registrar, config: config)
} }
// 单独处理音频数据事件通道(只有事件通道)
let audioDataEventChannel = FlutterEventChannel(name: "azure_speech/audio_data_events", binaryMessenger: registrar.messenger())
audioDataEventChannel.setStreamHandler(BaseEventStreamHandler(instance: instance, eventType: .audioData))
instance.audioDataEventChannel = audioDataEventChannel
} }
// 简化的事件发送方法
internal func sendAsrEvent(_ event: [String: Any]) {
sendEvent(event, type: .asr)
}
private func sendTtsEvent(_ event: [String: Any]) {
sendEvent(event, type: .tts)
}
private func sendAudioDataEvent(_ event: [String: Any]) {
sendEvent(event, type: .audioData)
}
private func sendAstEvent(_ event: [String: Any]) {
sendEvent(event, type: .ast)
}
// 设置TTS事件监听器 // 设置TTS事件监听器
private func setupTtsEventListener() { internal func setupTtsEventListener() {
if !isTtsListenerAdded { if !isTtsListenerAdded {
azureTtsHelper.addListener(self) azureTtsHelper.addListener(self)
isTtsListenerAdded = true isTtsListenerAdded = true
@ -136,18 +214,25 @@ import ble_service
} }
// // 处理Flutter方法调用 /**
// public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { * 处理音频数据
// switch call.method { * @param data 音频数据
// case "azure_speech/asr": */
// handleAsrMethodCall(call, result) private func handleAudioData(_ data: Data) {
// case "azure_speech/tts": guard audioDataEventSink != nil else {
// handleTtsMethodCall(call, result) print("音频数据事件通道未准备好")
// default: return
// // 处理未识别的通道 }
// result(FlutterMethodNotImplemented)
// } let eventMap: [String: Any] = [
// } "type": "audioData",
"data": FlutterStandardTypedData(bytes: data),
"timestamp": Int(Date().timeIntervalSince1970 * 1000),
"size": data.count
]
print("音频数据大小: \(data.count)")
sendAudioDataEvent(eventMap)
}
// MARK: - ASR 方法处理 // MARK: - ASR 方法处理
@ -299,19 +384,8 @@ import ble_service
do { do {
if acceptAudioData { if acceptAudioData {
// 创建音频数据回调实现类 // 使用复用的音频数据回调实例
let audioCallback = AudioDataCallbackImpl { [weak self] audioData in try azureAsrHelper.enableRecord(filePath: filePath, audioDataCallback: audioDataCallback)
// 构建音频数据事件映射
let audioEvent: [String: Any] = [
"type": "audioData",
"data": audioData,
"timestamp": Date().timeIntervalSince1970 * 1000,
"size": audioData.count
]
// 发送音频数据事件到 Flutter 层
self?.sendAsrEvent(audioEvent)
}
try azureAsrHelper.enableRecord(filePath: filePath, audioDataCallback: audioCallback)
} else { } else {
try azureAsrHelper.enableRecord(filePath: filePath) try azureAsrHelper.enableRecord(filePath: filePath)
} }
@ -325,9 +399,10 @@ import ble_service
case "pauseRecord": case "pauseRecord":
azureAsrHelper.pauseRecord() azureAsrHelper.pauseRecord()
result(true) result(true)
// case "resumeRecord":
// azureAsrHelper.resumeRecord() case "resumeRecord":
// result(true) azureAsrHelper.resumeRecord()
result(true)
case "stopRecord": case "stopRecord":
guard let args = call.arguments as? [String: Any], guard let args = call.arguments as? [String: Any],
@ -851,57 +926,60 @@ extension AzureSpeechPlugin: BleService.Callback {
public func onDeviceInfoReceived(infoType: Int, infoData: [String: Any]) { public func onDeviceInfoReceived(infoType: Int, infoData: [String: Any]) {
} }
} }
// MARK: - 事件处理 /**
extension AzureSpeechPlugin: FlutterStreamHandler { * 通用事件流处理器基类
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { */
// 根据通道类型设置事件接收器 private class BaseEventStreamHandler: NSObject, FlutterStreamHandler {
if let args = arguments as? [String: Any], private weak var instance: AzureSpeechPlugin?
let channel = args["channel"] as? String { private let eventType: AzureSpeechPlugin.EventType
if channel == "asr" { /**
asrEventSink = events * 初始化事件流处理器
} else if channel == "tts" { * @param instance AzureSpeechPlugin实例
ttsEventSink = events * @param eventType 事件类型
setupTtsEventListener() */
} init(instance: AzureSpeechPlugin, eventType: AzureSpeechPlugin.EventType) {
} else if arguments == nil { self.instance = instance
// 如果没有指定通道,尝试弄清楚是哪个通道在监听 self.eventType = eventType
if asrEventSink == nil && ttsEventSink != nil { super.init()
asrEventSink = events }
} else if asrEventSink != nil && ttsEventSink == nil {
ttsEventSink = events func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
setupTtsEventListener() switch eventType {
} else { case .asr:
// 无法确定哪个通道,默认设置为ASR instance?.asrEventSink = events
asrEventSink = events case .tts:
} instance?.ttsEventSink = events
instance?.setupTtsEventListener()
case .audioData:
instance?.audioDataEventSink = events
print("音频数据事件通道已准备好")
case .ast:
instance?.astEventSink = events
} }
return nil return nil
} }
public func onCancel(withArguments arguments: Any?) -> FlutterError? { func onCancel(withArguments arguments: Any?) -> FlutterError? {
// 根据通道类型清除事件接收器 switch eventType {
if let args = arguments as? [String: Any], case .asr:
let channel = args["channel"] as? String { instance?.asrEventSink = nil
case .tts:
if channel == "asr" { instance?.ttsEventSink = nil
asrEventSink = nil case .audioData:
} else if channel == "tts" { instance?.audioDataEventSink = nil
ttsEventSink = nil print("音频数据事件通道已取消")
} case .ast:
} else { instance?.astEventSink = nil
// 如果没有指定通道,清除所有通道
asrEventSink = nil
ttsEventSink = nil
} }
return nil return nil
} }
} }
// MARK: - TTS 事件监听实现 // MARK: - TTS 事件监听实现
extension AzureSpeechPlugin: TtsEventListener { extension AzureSpeechPlugin: TtsEventListener {
// 使用@objc特性为方法提供一个不同的Objective-C选择器名称 // 使用@objc特性为方法提供一个不同的Objective-C选择器名称
@ -942,19 +1020,6 @@ extension AzureSpeechPlugin: TtsEventListener {
} }
} }
// MARK: - 音频数据监听实现
extension AzureSpeechPlugin: AudioDataListener {
public func onAudioData(_ data: Data) {
if ttsEventSink == nil { return }
let eventMap: [String: Any] = [
"type": "audio_data",
"data": FlutterStandardTypedData(bytes: data)
]
sendTtsEvent(eventMap)
}
}
// MARK: - 音频数据回调实现 // MARK: - 音频数据回调实现
@ -978,6 +1043,7 @@ private class AudioDataCallbackImpl: SimpleAudioReceiver.AudioDataCallback {
* @param data 音频数据 * @param data 音频数据
*/ */
func onAudio(_ data: Data) { func onAudio(_ data: Data) {
print("音频数据回调方法: \(data.count)")
callback(data) callback(data)
} }
} }

27
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/IntegratedSpeechTranslationService.swift

@ -485,22 +485,13 @@ import os.log
// 合成进行中事件 - 修改为返回音频数据 // 合成进行中事件 - 修改为返回音频数据
synthesizer?.addSynthesizingEventHandler { [weak self] (synthesizer, event) in synthesizer?.addSynthesizingEventHandler { [weak self] (synthesizer, event) in
guard let self = self else { return } guard let self = self else { return }
// 安全解包audioData
// 安全解包audioData
guard let audioData = event.result.audioData else { guard let audioData = event.result.audioData else {
os_log("合成进行中事件,音频数据为空", log: self.log, type: .debug) os_log("合成进行中事件,音频数据为空", log: self.log, type: .debug)
return return
} }
os_log("合成进行中事件,音频数据长度: %d bytes", log: self.log, type: .debug, audioData.count)
os_log("合成进行中事件,音频数据长度: %d bytes", log: self.log, type: .debug, audioData.count)
DispatchQueue.main.async {
// 立即返回当前生成的音频数据
self.eventCallback?.onSynthesisAudioGenerated(text: "", audioData: audioData)
}
} }
// 合成完成事件 // 合成完成事件
@ -508,11 +499,19 @@ import os.log
guard let self = self else { return } guard let self = self else { return }
os_log("合成完成事件", log: self.log, type: .info) os_log("合成完成事件", log: self.log, type: .info)
// 安全解包audioData
guard let audioData = event.result.audioData else {
os_log("合成完成事件,音频数据为空", log: self.log, type: .debug)
return
}
os_log("合成完成事件,音频数据长度: %d bytes", log: self.log, type: .debug, audioData.count)
DispatchQueue.main.async { DispatchQueue.main.async {
self.serviceState.isSynthesizing = false self.serviceState.isSynthesizing = false
self.eventCallback?.onStateChanged(component: "Synthesis", isActive: false) // 立即返回当前生成的音频数据
self.eventCallback?.onSynthesisAudioGenerated(text: "", audioData: audioData)
self.eventCallback?.onStateChanged(component: "Synthesis", isActive: false)
} }
} }
// 合成取消事件 // 合成取消事件

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

@ -140,8 +140,10 @@ public class SimpleAudioReceiver: NSObject {
guard let dataToWrite = self.writeQueue.take() else { continue } guard let dataToWrite = self.writeQueue.take() else { continue }
do { do {
if let callback = self.audioDataCallback {
callback.onAudio(dataToWrite) if self.audioDataCallback != nil {
print("写入数据长度: \(dataToWrite.count)")
self.audioDataCallback!.onAudio(dataToWrite)
} }
try self.pushAudioStream?.write(dataToWrite) try self.pushAudioStream?.write(dataToWrite)
if self.recordfile != nil { if self.recordfile != nil {

16
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt

@ -636,13 +636,15 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "onFunctionCallResult回调异常: ${e.message}", e) Log.e(TAG, "onFunctionCallResult回调异常: ${e.message}", e)
} }
// 将结果发送回OpenAI继续对话 if (functionName != "set_user_profile_field"){
sendFunctionCallResultInternal( // 将结果发送回OpenAI继续对话
sessionid= sessionid, sendFunctionCallResultInternal(
messages = currentMessages, sessionid= sessionid,
functionCall = functionCall, messages = currentMessages,
functionResult = gson.toJson(result) functionCall = functionCall,
) functionResult = gson.toJson(result)
)
}
} }
} }
} catch (e: Exception) { } catch (e: Exception) {

18
local_plugins/chat_api/ios/chat_api/Sources/chat_api/ChatApiService.swift

@ -524,14 +524,16 @@ getSessionCallback(sessionId)?.onFunctionCall(sessionId, jsonFunctionCall)
functionCall, functionCall,
result result
) )
if (firstToolCall.name != "set_user_profile_field"){
// 将结果发送回OpenAI继续对话 // 将结果发送回OpenAI继续对话
await self.sendFunctionCallResultInternal( await self.sendFunctionCallResultInternal(
sessionId: sessionId, sessionId: sessionId,
messages: self.currentMessages, messages: self.currentMessages,
functionCall: functionCall, functionCall: functionCall,
functionResult: self.jsonToString(result) ?? "{}" functionResult: self.jsonToString(result) ?? "{}"
) )
}
} }
} }
} catch { } catch {

Loading…
Cancel
Save