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

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)
}
}
}