Files
light-code/web/src/apps/muse/voice/store/relatime.ts
2025-12-24 11:21:07 +08:00

80 lines
2.7 KiB
TypeScript

import { WSServer } from '@kevisual/video-tools/src/asr/ws.ts'
import { useVoiceStore } from './voiceStore'
export class Relatime {
asr: WSServer
ready = false
timeoutHandle: NodeJS.Timeout | null = null
startTime: number = 0
isRelatime: boolean = true
constructor() {
// const url = new URL('/ws/asr', "http://localhost:51015")
const url = new URL('/ws/asr', window.location.origin)
url.searchParams.set('id', 'muse-voice-relatime')
const ws = new WSServer({
url: url.toString(),
onConnect: () => {
console.log('WebSocket connected');
ws.emitter.on("message", (data) => {
// console.log("Received message:", data.data);
const json = JSON.parse(data.data);
console.log('json', json);
if (json && json.type === 'connected') {
ws.ws.send(JSON.stringify({ type: 'init' }));
}
if (json && json.type === 'asr' && json.code === 200) {
ws.emitter.emit('asr');
}
if (json && json.type === 'partial' || json.type === 'result') {
const text = json.text || '';
const isPartial = json.type === 'partial';
const isResult = json.type === 'result';
if (isPartial) {
// 部分结果
useVoiceStore.getState().setRelatimeParialText(text);
} else {
// 最终结果
useVoiceStore.getState().setRelatimeFinalText(text);
}
}
});
ws.emitter.once('asr', async () => {
console.log('ASR ready');
this.ready = true;
});
}
})
this.asr = ws
}
send(data: Buffer) {
if (!this.ready) return;
const voice = data.toString('base64');
this.asr.ws.send(JSON.stringify({ voice }));
}
setIsRelatime(isRelatime: boolean) {
this.isRelatime = isRelatime;
}
async sendBase64(data: string, opts?: { isRelatime?: boolean }) {
if (!this.ready) return;
if (opts?.isRelatime !== this.isRelatime) {
return;
}
// console.log('send 花费时间:', Date.now() - this.startTime);
const connected = await this.asr.checkConnected();
if (!connected) return;
this.asr.ws.send(JSON.stringify({ voice: data, format: 'float32', time: Date.now(), ...opts }));
// if (this.timeoutHandle) {
// clearTimeout(this.timeoutHandle);
// }
// this.timeoutHandle = setTimeout(() => {
// this.asr.sendBlankJson()
// this.timeoutHandle = null;
// }, 20000); // 20秒钟没有数据则发送空JSON保持连接
}
setStartTime(time: number) {
this.startTime = time;
}
showCostTime() {
console.log('当前花费时间:', Date.now() - this.startTime);
}
}