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.
182 lines
5.5 KiB
182 lines
5.5 KiB
import Flutter
|
|
import UIKit
|
|
|
|
public class AzureSpeechPlugin: NSObject, FlutterPlugin {
|
|
private var ttsHelper: AzureTtsHelper?
|
|
private var asrHelper: AzureAsrHelper?
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
let channel = FlutterMethodChannel(name: "azure_speech", binaryMessenger: registrar.messenger())
|
|
let instance = AzureSpeechPlugin()
|
|
registrar.addMethodCallDelegate(instance, channel: channel)
|
|
|
|
// 初始化事件通道
|
|
let eventChannel = FlutterEventChannel(name: "azure_speech/asr_events", binaryMessenger: registrar.messenger())
|
|
eventChannel.setStreamHandler(AsrStreamHandler(instance: instance))
|
|
}
|
|
|
|
override init() {
|
|
super.init()
|
|
ttsHelper = AzureTtsHelper()
|
|
asrHelper = AzureAsrHelper()
|
|
|
|
// 设置ASR事件处理
|
|
asrHelper?.setEventHandler { [weak self] event in
|
|
self?.handleAsrEvent(event)
|
|
}
|
|
}
|
|
|
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
switch call.method {
|
|
// TTS相关方法
|
|
case "initializeTts":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let subscriptionKey = args["subscriptionKey"] as? String,
|
|
let serviceRegion = args["serviceRegion"] as? String else {
|
|
result(false)
|
|
return
|
|
}
|
|
|
|
let language = args["language"] as? String ?? "zh-CN"
|
|
let success = ttsHelper?.initialize(speechSubscriptionKey: subscriptionKey, serviceRegion: serviceRegion, language: language) ?? false
|
|
result(success)
|
|
|
|
case "setTtsVoice":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let voiceName = args["voiceName"] as? String else {
|
|
result(false)
|
|
return
|
|
}
|
|
|
|
let success = ttsHelper?.setVoice(voiceName: voiceName) ?? false
|
|
result(success)
|
|
|
|
case "setTtsSpeechParams":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let rate = args["rate"] as? Int,
|
|
let pitch = args["pitch"] as? Int,
|
|
let volume = args["volume"] as? Int else {
|
|
result(false)
|
|
return
|
|
}
|
|
|
|
let success = ttsHelper?.setSpeechParams(rate: rate, pitch: pitch, volume: volume) ?? false
|
|
result(success)
|
|
|
|
case "speakText":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let text = args["text"] as? String else {
|
|
result(false)
|
|
return
|
|
}
|
|
|
|
ttsHelper?.speakText(text: text) { success, _ in
|
|
result(success)
|
|
}
|
|
|
|
case "stopSpeaking":
|
|
let success = ttsHelper?.stopSpeaking() ?? false
|
|
result(success)
|
|
|
|
case "isSpeaking":
|
|
let speaking = ttsHelper?.isSpeaking() ?? false
|
|
result(speaking)
|
|
|
|
case "setTtsAudioOutputType":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let outputType = args["outputType"] as? String else {
|
|
result(false)
|
|
return
|
|
}
|
|
|
|
var type: AzureTtsHelper.AudioOutputType = .auto
|
|
switch outputType.uppercased() {
|
|
case "SPEAKER":
|
|
type = .speaker
|
|
case "EARPIECE":
|
|
type = .earpiece
|
|
default:
|
|
type = .auto
|
|
}
|
|
|
|
let success = ttsHelper?.setAudioOutputType(outputType: type) ?? false
|
|
result(success)
|
|
|
|
// ASR相关方法
|
|
case "initializeAsr":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let subscriptionKey = args["subscriptionKey"] as? String,
|
|
let serviceRegion = args["serviceRegion"] as? String,
|
|
let supportedLanguages = args["supportedLanguages"] as? [String] else {
|
|
result(false)
|
|
return
|
|
}
|
|
|
|
let success = asrHelper?.initialize(speechSubscriptionKey: subscriptionKey, serviceRegion: serviceRegion, supportedLanguages: supportedLanguages) ?? false
|
|
result(success)
|
|
|
|
case "recognizeOnce":
|
|
asrHelper?.recognizeOnce { success, text, language, error in
|
|
var resultMap: [String: Any] = ["success": success]
|
|
if success {
|
|
resultMap["text"] = text
|
|
resultMap["language"] = language
|
|
} else {
|
|
resultMap["error"] = error
|
|
}
|
|
result(resultMap)
|
|
}
|
|
|
|
case "startContinuousRecognition":
|
|
let success = asrHelper?.startContinuousRecognition() ?? false
|
|
result(success)
|
|
|
|
case "stopContinuousRecognition":
|
|
let success = asrHelper?.stopContinuousRecognition() ?? false
|
|
result(success)
|
|
|
|
case "isContinuousRecognitionActive":
|
|
let isActive = asrHelper?.isContinuousRecognitionActive() ?? false
|
|
result(isActive)
|
|
|
|
case "dispose":
|
|
ttsHelper?.dispose()
|
|
asrHelper?.dispose()
|
|
result(nil)
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// 设置事件接收器
|
|
func setEventSink(_ sink: FlutterEventSink?) {
|
|
self.eventSink = sink
|
|
}
|
|
|
|
// 处理ASR事件
|
|
private func handleAsrEvent(_ event: [String: Any]) {
|
|
self.eventSink?(event)
|
|
}
|
|
}
|
|
|
|
// ASR事件流处理器
|
|
class AsrStreamHandler: NSObject, FlutterStreamHandler {
|
|
private weak var plugin: AzureSpeechPlugin?
|
|
|
|
init(instance: AzureSpeechPlugin) {
|
|
self.plugin = instance
|
|
super.init()
|
|
}
|
|
|
|
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
plugin?.setEventSink(events)
|
|
return nil
|
|
}
|
|
|
|
func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
plugin?.setEventSink(nil)
|
|
return nil
|
|
}
|
|
}
|