Files
2026-09-24 16:25:22 +08:00

83 lines
2.4 KiB
Plaintext

import { XuiTextToVoiceOpts, XuiTextToVoiceResult, XTTSImpl } from "../interface.uts"
import { XuiTextToVoiceFailImpl } from "../unierror.uts"
import { AVSpeechBoundary, AVSpeechSynthesisVoice, AVSpeechSynthesizer, AVSpeechSynthesizerDelegate, AVSpeechUtterance } from "AVFAudio";
import { NSObject } from "ObjectiveC";
import {AVPlayerLayer} from "AVFoundation"
let tts:AVSpeechSynthesizer|null = null
class TtsObj implements XTTSImpl {
config : XuiTextToVoiceOpts;
constructor(opts : XuiTextToVoiceOpts) {
this.config = opts;
}
isPlaying() : boolean {
return tts!.isSpeaking;
}
play(c : string) {
console.log(c)
let utterance = new AVSpeechUtterance(string = c)
utterance.voice = new AVSpeechSynthesisVoice(language = "zh-CN")
tts!.speak(utterance)
}
stop() {
tts!.stopSpeaking(at = AVSpeechBoundary.immediate)
this.config.onStop?.()
}
}
// 委托类
class TTSDelegate implements AVSpeechSynthesizerDelegate<AVSpeechSynthesizerDelegate>{
private config: XuiTextToVoiceOpts
constructor(opts : XuiTextToVoiceOpts) {
this.config = opts
}
speechSynthesizer(synthesizer: AVSpeechSynthesizer, @argumentLabel("didStart") utterance: AVSpeechUtterance) {
this.config.onStart?.()
}
speechSynthesizer(synthesizer: AVSpeechSynthesizer, @argumentLabel("didFinish") utterance: AVSpeechUtterance) {
this.config.onDone?.()
}
speechSynthesizer(synthesizer: AVSpeechSynthesizer, @argumentLabel("didCancel") utterance: AVSpeechUtterance) {
this.config.onDone?.()
}
speechSynthesizer(synthesizer: AVSpeechSynthesizer, @argumentLabel("didPause") utterance: AVSpeechUtterance) {
this.config.onStop?.()
}
}
let TtsObjIml:TtsObj|null = null;
let ttsDelegate:TTSDelegate|null = null;
export class xTtsImplIns {
public static play(c:string){
TtsObjIml?.play(c)
}
public static isPlaying() : boolean {
return TtsObjIml?.isPlaying()??false
}
public static stop(){
TtsObjIml?.stop()
}
}
export function XTtsSpeek(opts : XuiTextToVoiceOpts) {
tts = null;
DispatchQueue.main.async(execute=():void => {
try {
tts = new AVSpeechSynthesizer()
TtsObjIml = new TtsObj(opts)
ttsDelegate = new TTSDelegate(opts)
tts!.delegate = ttsDelegate!
opts.success?.(TtsObjIml!)
opts.complete?.(null)
} catch (error) {
console.error("TMUI Error:",error)
opts.fail?.(new XuiTextToVoiceFailImpl(1001))
opts.complete?.(null)
}
})
}