@tencentcloud/call-uikit-react
Version:
An Open-source Voice & Video Calling UI Component Based on Tencent Cloud Service.
133 lines (113 loc) • 3.92 kB
text/typescript
import { mitt } from "./utils/index";
interface IInitASRParams {
trtcCloudInstance: any;
getNickName?: (userId: string) => Promise<userInfo>;
}
interface ITranslationContent {
language: string;
content: string;
}
interface ITranslationInfo {
roundId: string;
sender: string;
nick?: string;
text: string;
end: boolean;
translation: ITranslationContent[];
};
export const ASREvent = {
TRANSCRIPTION: 'transcription',
}
const NAME = {
ON_RECV_CUSTOM_CMD_MESSAGE: 'onRecvCustomCmdMsg',
CUSTOM_MESSAGE_ASR_ID: 1,
USER_SPEAK: 10000,
}
interface userInfo {
userId: string;
nick: string;
avatar?: string;
[key: string]: any;
}
export default class AIAssistant {
emitter: any;
trtcCloudInstance: any;
getNickName: (userId: string) => Promise<userInfo>;
translationInfoList: ITranslationInfo[] = [];
constructor() {
this.emitter = mitt();
this.trtcCloudInstance = null;
};
initASR(params: IInitASRParams) {
const { trtcCloudInstance, getNickName } = params;
this.getNickName = getNickName;
this.trtcCloudInstance = trtcCloudInstance;
this.trtcCloudInstance.on(NAME.ON_RECV_CUSTOM_CMD_MESSAGE, this.handleCustomMessage, this);
};
on(type: string, handler: (event: any) => void) {
this.emitter.on(type, handler);
};
emit(type: string, events: any) {
this.emitter.emit(type, events)
};
off(type: string, handler: (event: any) => void) {
this.emitter.off(type, handler);
};
destroyASR() {
this.trtcCloudInstance.off(NAME.ON_RECV_CUSTOM_CMD_MESSAGE, this.handleCustomMessage, this);
this.translationInfoList = [];
this.trtcCloudInstance = null;
};
handleAIMessage = (data: any) => {
if (data?.type !== NAME.USER_SPEAK) return;
const { sender = '', payload } = data;
const { text = '', translation_text: translationText = '', end, roundid: roundId, translation_language: language = '' } = payload;
if (!roundId) return;
const translationInfo = this.translationInfoList.find(obj => obj.roundId === roundId);
if (translationInfo) {
translationInfo.text = text ? text : translationInfo.text;
translationInfo.end = end; // not change sender
const translationContent = (translationInfo.translation || []).find(obj => obj.language === language);
if (translationContent) {
translationContent.content = translationText;
} else if (language) {
translationInfo.translation.push({ language, content: translationText });
}
} else {
const translationContent: ITranslationContent = { language, content: translationText };
const translationValue: ITranslationInfo = {
roundId,
sender,
text,
end,
translation: language ? [translationContent] : [],
};
this.translationInfoList.push(translationValue);
// 异步获取昵称
this.getNickName?.(sender)?.then((res) => {
const item = this.translationInfoList.find(item => item.roundId === roundId);
if (item) {
item.nick = res?.nick || '';
this.emit(ASREvent.TRANSCRIPTION, { subtitleInfoList: this.translationInfoList });
}
});
}
this.emit(ASREvent.TRANSCRIPTION, { subtitleInfoList: this.translationInfoList });
if (end) {
const id = roundId;
setTimeout(() => {
if (this?.translationInfoList?.length > 0) {
this.translationInfoList = this.translationInfoList.filter(obj => obj.roundId !== id);
this.emit(ASREvent.TRANSCRIPTION, { subtitleInfoList: this.translationInfoList });
}
}, 8000);
}
};
handleCustomMessage = (userId: string, cmdId: number, seq: number, data: any) => {
if (cmdId === NAME.CUSTOM_MESSAGE_ASR_ID) {
const decodeData = new TextDecoder().decode(data);
const jsonData = JSON.parse(decodeData || '');
this.handleAIMessage(jsonData);
}
};
}