You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
743 lines
24 KiB
743 lines
24 KiB
import Flutter
|
|
import UIKit
|
|
import AVFoundation
|
|
|
|
@main
|
|
@objc class AppDelegate: FlutterAppDelegate {
|
|
private var classicBluetoothHelper: ClassicBluetoothHelper?
|
|
private var mediaButtonHelper: Any?
|
|
// 添加Azure语音服务辅助类
|
|
private var azureAsrHelper: Any?
|
|
private var azureTtsHelper: Any?
|
|
// 添加火山AI服务
|
|
private var volcanoAIService: VolcanoAIService?
|
|
// 语音交互服务
|
|
private var voiceInteractionService: VoiceInteractionService?
|
|
|
|
private var audioSessionManager: AudioSessionManager?
|
|
|
|
override func application(
|
|
_ application: UIApplication,
|
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
) -> Bool {
|
|
|
|
// 获取flutter控制器
|
|
guard let controller = window?.rootViewController as? FlutterViewController else {
|
|
NSLog("AppDelegate: Flutter控制器不可用")
|
|
return false
|
|
}
|
|
|
|
// 初始化音频会话管理器
|
|
audioSessionManager = AudioSessionManager.shared
|
|
|
|
|
|
// 统一注册所有方法通道
|
|
registerMethodChannel()
|
|
|
|
GeneratedPluginRegistrant.register(with: self)
|
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
|
}
|
|
|
|
private func registerMethodChannel() {
|
|
let controller = window?.rootViewController as? FlutterViewController
|
|
guard let controller = controller else {
|
|
NSLog("AppDelegate: FlutterViewController 不可用")
|
|
return
|
|
}
|
|
|
|
// 注册经典蓝牙方法通道
|
|
registerClassicBluetoothChannels(controller: controller)
|
|
|
|
// 仅在iOS 13.0及以上版本注册媒体按钮通道和Azure语音服务通道
|
|
if #available(iOS 13.0, *) {
|
|
// 注册媒体按钮方法通道
|
|
registerMediaButtonChannels(controller: controller)
|
|
|
|
// 注册Azure ASR方法通道
|
|
registerAzureAsrChannels(controller: controller)
|
|
|
|
// 注册Azure TTS方法通道
|
|
registerAzureTtsChannels(controller: controller)
|
|
|
|
// 注册火山AI服务方法通道
|
|
registerVolcanoAIServiceChannels(controller: controller)
|
|
|
|
// 注册语音交互服务方法通道
|
|
registerVoiceInteractionChannels(controller: controller)
|
|
}
|
|
}
|
|
|
|
// MARK: - 经典蓝牙通道
|
|
|
|
private func registerClassicBluetoothChannels(controller: FlutterViewController) {
|
|
// 初始化蓝牙辅助类
|
|
if classicBluetoothHelper == nil {
|
|
classicBluetoothHelper = ClassicBluetoothHelper()
|
|
}
|
|
|
|
guard let classicBluetoothHelper = self.classicBluetoothHelper else {
|
|
NSLog("AppDelegate: 经典蓝牙辅助实例不可用")
|
|
return
|
|
}
|
|
|
|
// 注册经典蓝牙方法通道
|
|
let classicBluetoothChannel = FlutterMethodChannel(
|
|
name: "com.deep_voice.classic_bluetooth",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
classicBluetoothChannel.setMethodCallHandler { [weak self, weak classicBluetoothHelper] (call, result) in
|
|
guard let _ = self, let classicBluetoothHelper = classicBluetoothHelper else {
|
|
result(FlutterError(code: "UNAVAILABLE", message: "经典蓝牙辅助实例不可用", details: nil))
|
|
return
|
|
}
|
|
|
|
switch call.method {
|
|
case "isBluetoothEnabled":
|
|
result(classicBluetoothHelper.isBluetoothEnabled())
|
|
|
|
case "getConnectedHeadsetDevices":
|
|
// 获取已连接的耳机设备
|
|
classicBluetoothHelper.getConnectedHeadsetDevices { devices, error in
|
|
if let error = error {
|
|
result(FlutterError(code: "GET_DEVICES_FAILED", message: error, details: nil))
|
|
} else {
|
|
result(devices)
|
|
}
|
|
}
|
|
case "initialize":
|
|
classicBluetoothHelper.initialize()
|
|
result(true)
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 注册蓝牙流通道
|
|
let classicBluetoothStreamChannel = FlutterEventChannel(
|
|
name: "com.deep_voice.classic_bluetooth_events",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 创建蓝牙流处理器(作为局部变量)
|
|
let bluetoothStreamHandler = BluetoothStreamHandler(bluetoothHelper: classicBluetoothHelper)
|
|
classicBluetoothStreamChannel.setStreamHandler(bluetoothStreamHandler)
|
|
}
|
|
|
|
// MARK: - 消息通道设置
|
|
|
|
// MARK: - 蓝牙媒体按键通道
|
|
|
|
@available(iOS 13.0, *)
|
|
private func registerMediaButtonChannels(controller: FlutterViewController) {
|
|
// 初始化媒体按钮辅助类
|
|
if mediaButtonHelper == nil {
|
|
mediaButtonHelper = BluetoothMediaButtonHelper()
|
|
}
|
|
// guard let mediaButtonHelper = self.mediaButtonHelper as? BluetoothMediaButtonHelper else {
|
|
// NSLog("AppDelegate: 媒体按钮辅助实例不可用")
|
|
// return
|
|
// }
|
|
// mediaButtonHelper.startButtonListening()
|
|
// 注册媒体按钮方法通道
|
|
let mediaButtonChannel = FlutterMethodChannel(
|
|
name: "com.deep_voice.bluetooth_media_button",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
mediaButtonChannel.setMethodCallHandler { [weak self] (call, result) in
|
|
guard let _ = self, let mediaButtonHelper = self?.mediaButtonHelper as? BluetoothMediaButtonHelper else {
|
|
result(FlutterError(code: "UNAVAILABLE", message: "媒体按钮辅助实例不可用", details: nil))
|
|
return
|
|
}
|
|
|
|
switch call.method {
|
|
case "startButtonListening":
|
|
let success = mediaButtonHelper.startButtonListening()
|
|
result(success)
|
|
|
|
case "stopButtonListening":
|
|
let success = mediaButtonHelper.stopButtonListening()
|
|
result(success)
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 注册媒体按钮流通道
|
|
let mediaButtonStreamChannel = FlutterEventChannel(
|
|
name: "com.deep_voice.bluetooth_media_button_events",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 创建媒体按钮流处理器
|
|
let mediaButtonStreamHandler = MediaButtonStreamHandler(mediaButtonHelper: mediaButtonHelper as! BluetoothMediaButtonHelper)
|
|
mediaButtonStreamChannel.setStreamHandler(mediaButtonStreamHandler)
|
|
}
|
|
|
|
|
|
// 注册Azure ASR通道
|
|
@available(iOS 13.0, *)
|
|
private func registerAzureAsrChannels(controller: FlutterViewController) {
|
|
// 注册Azure ASR方法通道
|
|
let azureAsrChannel = FlutterMethodChannel(
|
|
name: "com.deep_voice.azure_asr",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 初始化Azure ASR辅助类
|
|
azureAsrHelper = AzureAsrHelper()
|
|
|
|
// 设置ASR方法处理器
|
|
azureAsrChannel.setMethodCallHandler { [weak self] (call, result) in
|
|
guard let self = self,
|
|
let asrHelper = self.azureAsrHelper as? AzureAsrHelper else {
|
|
result(FlutterError(code: "UNAVAILABLE", message: "Azure ASR辅助实例不可用", details: nil))
|
|
return
|
|
}
|
|
|
|
switch call.method {
|
|
case "initialize":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let key = args["subscriptionKey"] as? String,
|
|
let region = args["region"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "初始化参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
let languages = args["supportedLanguages"] as? [String]
|
|
let success = asrHelper.initialize(speechSubscriptionKey: key, serviceRegion: region, supportedLanguages: languages)
|
|
result(success)
|
|
|
|
case "recognizeOnce":
|
|
let success = asrHelper.recognizeOnce()
|
|
result(success)
|
|
|
|
case "startContinuousRecognition":
|
|
let success = asrHelper.startContinuousRecognition()
|
|
result(success)
|
|
|
|
case "stopContinuousRecognition":
|
|
let success = asrHelper.stopContinuousRecognition()
|
|
result(success)
|
|
|
|
case "isContinuousRecognitionActive":
|
|
let isActive = asrHelper.isContinuousRecognitionActive()
|
|
result(isActive)
|
|
|
|
case "dispose":
|
|
asrHelper.dispose()
|
|
result(true)
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 注册Azure ASR流通道
|
|
let azureAsrStreamChannel = FlutterEventChannel(
|
|
name: "com.deep_voice.azure_asr_events",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 创建ASR流处理器
|
|
let asrStreamHandler = AsrStreamHandler(azureAsrHelper: azureAsrHelper as! AzureAsrHelper)
|
|
azureAsrStreamChannel.setStreamHandler(asrStreamHandler)
|
|
}
|
|
|
|
// 注册Azure TTS通道
|
|
@available(iOS 13.0, *)
|
|
private func registerAzureTtsChannels(controller: FlutterViewController) {
|
|
// 注册Azure TTS方法通道
|
|
let azureTtsChannel = FlutterMethodChannel(
|
|
name: "com.deep_voice.azure_tts",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 初始化Azure TTS辅助类
|
|
azureTtsHelper = AzureTtsHelper()
|
|
|
|
// 设置TTS方法处理器
|
|
azureTtsChannel.setMethodCallHandler { [weak self] (call, result) in
|
|
guard let self = self,
|
|
let ttsHelper = self.azureTtsHelper as? AzureTtsHelper else {
|
|
result(FlutterError(code: "UNAVAILABLE", message: "Azure TTS辅助实例不可用", details: nil))
|
|
return
|
|
}
|
|
|
|
switch call.method {
|
|
case "initialize":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let key = args["subscriptionKey"] as? String,
|
|
let region = args["region"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "初始化参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
let language = args["language"] as? String ?? "zh-CN"
|
|
let success = ttsHelper.initialize(speechSubscriptionKey: key, serviceRegion: region, language: language)
|
|
result(success)
|
|
|
|
case "setVoice":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let voiceName = args["voiceName"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "语音名称参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
let success = ttsHelper.setVoice(voiceName: voiceName)
|
|
result(success)
|
|
|
|
case "setSpeechParams":
|
|
guard let args = call.arguments as? [String: Any] else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "语音参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
let rate = args["rate"] as? Int ?? 0
|
|
let pitch = args["pitch"] as? Int ?? 0
|
|
let volume = args["volume"] as? Int ?? 100
|
|
|
|
let success = ttsHelper.setSpeechParams(rate: rate, pitch: pitch, volume: volume)
|
|
result(success)
|
|
|
|
case "speakText":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let text = args["text"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "文本参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
let success = ttsHelper.speakText(text: text)
|
|
result(success)
|
|
|
|
case "stopSpeaking":
|
|
let success = ttsHelper.stopSpeaking()
|
|
result(success)
|
|
|
|
case "isSpeaking":
|
|
let isSpeaking = ttsHelper.isSpeaking()
|
|
result(isSpeaking)
|
|
|
|
case "dispose":
|
|
ttsHelper.dispose()
|
|
result(true)
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 注册Azure TTS流通道
|
|
let azureTtsStreamChannel = FlutterEventChannel(
|
|
name: "com.deep_voice.azure_tts_events",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 创建TTS流处理器
|
|
let ttsStreamHandler = TtsStreamHandler(azureTtsHelper: azureTtsHelper as! AzureTtsHelper)
|
|
azureTtsStreamChannel.setStreamHandler(ttsStreamHandler)
|
|
}
|
|
|
|
// 注册火山AI服务方法通道
|
|
@available(iOS 13.0, *)
|
|
private func registerVolcanoAIServiceChannels(controller: FlutterViewController) {
|
|
guard let volcanoAIService = volcanoAIService else {
|
|
return
|
|
}
|
|
|
|
// 注册火山AI方法通道
|
|
let volcanoAIChannel = FlutterMethodChannel(
|
|
name: "com.deep_voice.volcano_ai",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
volcanoAIChannel.setMethodCallHandler { [weak self, weak volcanoAIService] (call, result) in
|
|
guard let _ = self, let volcanoAIService = volcanoAIService else {
|
|
result(FlutterError(code: "UNAVAILABLE", message: "火山AI服务实例不可用", details: nil))
|
|
return
|
|
}
|
|
|
|
switch call.method {
|
|
case "initialize":
|
|
let apiKey = call.arguments as? String ?? ""
|
|
let success = volcanoAIService.initialize(apiKey: apiKey)
|
|
result(success)
|
|
|
|
case "sendMessage":
|
|
guard let arguments = call.arguments as? [String: Any],
|
|
let message = arguments["message"] as? String,
|
|
let systemPrompt = arguments["systemPrompt"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
if message.isEmpty {
|
|
result(FlutterError(code: "EMPTY_MESSAGE", message: "消息不能为空", details: nil))
|
|
return
|
|
}
|
|
|
|
// 异步发送消息
|
|
Task {
|
|
do {
|
|
// 创建用户消息
|
|
let userMessage = volcanoAIService.createUserMessage(content: message)
|
|
|
|
// 发送消息并等待响应
|
|
let response = try await volcanoAIService.sendMessage(
|
|
messages: [userMessage],
|
|
systemPrompt: systemPrompt
|
|
)
|
|
|
|
// 返回响应
|
|
DispatchQueue.main.async {
|
|
result(response)
|
|
}
|
|
} catch {
|
|
// 处理错误
|
|
DispatchQueue.main.async {
|
|
result(FlutterError(
|
|
code: "AI_ERROR",
|
|
message: "AI请求失败: \(error.localizedDescription)",
|
|
details: nil
|
|
))
|
|
}
|
|
}
|
|
}
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 注册火山AI流通道
|
|
let volcanoAIStreamChannel = FlutterEventChannel(
|
|
name: "com.deep_voice.volcano_ai_stream",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 创建火山AI流处理器(作为局部变量)
|
|
let volcanoAIStreamHandler = VolcanoAIStreamHandler(volcanoAIService: volcanoAIService)
|
|
volcanoAIStreamChannel.setStreamHandler(volcanoAIStreamHandler)
|
|
}
|
|
|
|
// 注册语音交互服务方法通道
|
|
@available(iOS 13.0, *)
|
|
private func registerVoiceInteractionChannels(controller: FlutterViewController) {
|
|
// 初始化语音交互服务
|
|
voiceInteractionService = VoiceInteractionService.shared
|
|
|
|
// 注册语音交互服务方法通道
|
|
let voiceInteractionChannel = FlutterMethodChannel(
|
|
name: "com.deep_voice.voice_interaction",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
voiceInteractionChannel.setMethodCallHandler { [weak self, weak voiceInteractionService] (call, result) in
|
|
guard let _ = self, let voiceInteractionService = voiceInteractionService else {
|
|
result(FlutterError(code: "UNAVAILABLE", message: "语音交互服务实例不可用", details: nil))
|
|
return
|
|
}
|
|
|
|
switch call.method {
|
|
case "startService":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let azureKey = args["azure_speech_key"] as? String,
|
|
let azureRegion = args["azure_speech_region"] as? String,
|
|
let volcanoKey = args["volcano_ai_api_key"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGS", message: "启动服务参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
let success = voiceInteractionService.start(azureKey: azureKey, azureRegion: azureRegion, volcanoKey: volcanoKey)
|
|
result(success)
|
|
|
|
case "stopService":
|
|
voiceInteractionService.stop()
|
|
result(true)
|
|
|
|
case "isServiceRunning":
|
|
let isRunning = voiceInteractionService.isServiceRunning()
|
|
result(isRunning)
|
|
|
|
case "pauseVoiceInteraction":
|
|
voiceInteractionService.pauseVoiceInteraction()
|
|
result(true)
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 注册语音交互流通道
|
|
let voiceInteractionStreamChannel = FlutterEventChannel(
|
|
name: "com.deep_voice.voice_interaction_events",
|
|
binaryMessenger: controller.binaryMessenger
|
|
)
|
|
|
|
// 创建语音交互流处理器(作为局部变量)
|
|
let voiceInteractionStreamHandler = VoiceInteractionStreamHandler(voiceInteractionService: voiceInteractionService!)
|
|
voiceInteractionStreamChannel.setStreamHandler(voiceInteractionStreamHandler)
|
|
}
|
|
}
|
|
|
|
// 蓝牙事件流处理器
|
|
class BluetoothStreamHandler: NSObject, FlutterStreamHandler, BluetoothEventHandler {
|
|
private let bluetoothHelper: ClassicBluetoothHelper
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
init(bluetoothHelper: ClassicBluetoothHelper) {
|
|
self.bluetoothHelper = bluetoothHelper
|
|
super.init()
|
|
|
|
// 设置事件处理器
|
|
bluetoothHelper.setEventHandler(self)
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
// NSLog("BluetoothStreamHandler: 开始监听蓝牙事件")
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
// NSLog("BluetoothStreamHandler: 取消监听蓝牙事件")
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
// 实现BluetoothEventHandler协议
|
|
func sendEvent(_ event: [String: Any]) {
|
|
NSLog("BluetoothStreamHandler: 接收到蓝牙事件: \(event)")
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.eventSink?(event)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 媒体按钮事件流处理器
|
|
@available(iOS 13.0, *)
|
|
class MediaButtonStreamHandler: NSObject, FlutterStreamHandler, MediaButtonEventHandler {
|
|
private let mediaButtonHelper: BluetoothMediaButtonHelper
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
init(mediaButtonHelper: BluetoothMediaButtonHelper) {
|
|
self.mediaButtonHelper = mediaButtonHelper
|
|
super.init()
|
|
|
|
// 设置事件处理器
|
|
mediaButtonHelper.setEventHandler(self)
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
NSLog("MediaButtonStreamHandler: 开始监听媒体按钮事件")
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
NSLog("MediaButtonStreamHandler: 取消监听媒体按钮事件")
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
// 实现MediaButtonEventHandler协议
|
|
func sendEvent(_ event: [String: Any]) {
|
|
NSLog("MediaButtonStreamHandler: 收到按钮事件 \(event)")
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.eventSink?(event)
|
|
}
|
|
}
|
|
}
|
|
|
|
// ASR事件处理器协议
|
|
@available(iOS 13.0, *)
|
|
protocol AsrEventHandler: AnyObject {
|
|
func sendEvent(_ event: [String: Any])
|
|
}
|
|
|
|
// ASR事件流处理器
|
|
@available(iOS 13.0, *)
|
|
class AsrStreamHandler: NSObject, FlutterStreamHandler, AsrEventHandler {
|
|
private let azureAsrHelper: AzureAsrHelper
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
init(azureAsrHelper: AzureAsrHelper) {
|
|
self.azureAsrHelper = azureAsrHelper
|
|
super.init()
|
|
|
|
// 设置事件处理器
|
|
azureAsrHelper.setEventHandler { [weak self] event in
|
|
self?.sendEvent(event)
|
|
}
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
NSLog("AsrStreamHandler: 开始监听ASR事件")
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
NSLog("AsrStreamHandler: 取消监听ASR事件")
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
// 实现AsrEventHandler协议
|
|
func sendEvent(_ event: [String: Any]) {
|
|
// NSLog("AsrStreamHandler: 收到事件 \(event)")
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.eventSink?(event)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TTS事件处理器协议
|
|
@available(iOS 13.0, *)
|
|
protocol TtsEventHandler: AnyObject {
|
|
func sendEvent(_ event: [String: Any])
|
|
}
|
|
|
|
// TTS事件流处理器
|
|
@available(iOS 13.0, *)
|
|
class TtsStreamHandler: NSObject, FlutterStreamHandler, TtsEventHandler {
|
|
private let azureTtsHelper: AzureTtsHelper
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
init(azureTtsHelper: AzureTtsHelper) {
|
|
self.azureTtsHelper = azureTtsHelper
|
|
super.init()
|
|
|
|
// 设置事件处理器
|
|
azureTtsHelper.setEventHandler { [weak self] event in
|
|
self?.sendEvent(event)
|
|
}
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
NSLog("TtsStreamHandler: 开始监听TTS事件")
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
NSLog("TtsStreamHandler: 取消监听TTS事件")
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
// 实现TtsEventHandler协议
|
|
func sendEvent(_ event: [String: Any]) {
|
|
NSLog("TtsStreamHandler: 收到事件 \(event)")
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.eventSink?(event)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 火山AI事件流处理器
|
|
@available(iOS 13.0, *)
|
|
class VolcanoAIStreamHandler: NSObject, FlutterStreamHandler {
|
|
private let volcanoAIService: VolcanoAIService
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
init(volcanoAIService: VolcanoAIService) {
|
|
self.volcanoAIService = volcanoAIService
|
|
super.init()
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
// 处理来自Flutter的流式请求
|
|
func handleStreamRequest(messages: [[String: Any]], systemPrompt: String) {
|
|
volcanoAIService.sendMessageStream(messages: messages, systemPrompt: systemPrompt, streamCallback: VolcanoAIService.StreamCallback(
|
|
onToken: { [weak self] token in
|
|
guard let self = self, let eventSink = self.eventSink else { return }
|
|
|
|
let event: [String: Any] = [
|
|
"type": "token",
|
|
"token": token
|
|
]
|
|
|
|
DispatchQueue.main.async {
|
|
eventSink(event)
|
|
}
|
|
},
|
|
onComplete: { [weak self] in
|
|
guard let self = self, let eventSink = self.eventSink else { return }
|
|
|
|
let event: [String: Any] = [
|
|
"type": "complete"
|
|
]
|
|
|
|
DispatchQueue.main.async {
|
|
eventSink(event)
|
|
}
|
|
},
|
|
onError: { [weak self] error in
|
|
guard let self = self, let eventSink = self.eventSink else { return }
|
|
|
|
let event: [String: Any] = [
|
|
"type": "error",
|
|
"error": error.localizedDescription
|
|
]
|
|
|
|
DispatchQueue.main.async {
|
|
eventSink(event)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
}
|
|
|
|
// 语音交互事件处理器协议
|
|
@available(iOS 13.0, *)
|
|
protocol VoiceInteractionEventHandler: AnyObject {
|
|
func sendEvent(_ event: [String: Any])
|
|
}
|
|
|
|
// 语音交互流处理器
|
|
@available(iOS 13.0, *)
|
|
class VoiceInteractionStreamHandler: NSObject, FlutterStreamHandler, VoiceInteractionEventHandler {
|
|
private let voiceInteractionService: VoiceInteractionService
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
init(voiceInteractionService: VoiceInteractionService) {
|
|
self.voiceInteractionService = voiceInteractionService
|
|
super.init()
|
|
|
|
// 设置事件处理器
|
|
voiceInteractionService.setEventHandler(self)
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
NSLog("VoiceInteractionStreamHandler: 开始监听语音交互事件")
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
NSLog("VoiceInteractionStreamHandler: 取消监听语音交互事件")
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
// 实现VoiceInteractionEventHandler协议
|
|
func sendEvent(_ event: [String: Any]) {
|
|
NSLog("VoiceInteractionStreamHandler: 收到事件 \(event)")
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.eventSink?(event)
|
|
}
|
|
}
|
|
}
|
|
|