feat: realistic face avatar + voice input + ASR endpoint
This commit is contained in:
@@ -12,6 +12,18 @@ interface TtsResult {
|
||||
durationMs: number
|
||||
}
|
||||
|
||||
const VALID_VOICES = new Set([
|
||||
'zh-CN-XiaoxiaoNeural', 'zh-CN-XiaoyiNeural', 'zh-CN-YunjianNeural',
|
||||
'zh-CN-YunxiNeural', 'zh-CN-YunxiaNeural', 'zh-CN-YunyangNeural',
|
||||
'zh-CN-liaoning-XiaobeiNeural', 'zh-CN-shaanxi-XiaoniNeural',
|
||||
])
|
||||
|
||||
function validateVoice(voice: string): void {
|
||||
if (!VALID_VOICES.has(voice)) {
|
||||
throw new Error(`不支持的语音: ${voice}`)
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TtsService {
|
||||
private readonly logger = new Logger(TtsService.name)
|
||||
@@ -23,6 +35,7 @@ export class TtsService {
|
||||
}
|
||||
|
||||
async synthesize(text: string, voice: string = 'zh-CN-XiaoxiaoNeural'): Promise<TtsResult> {
|
||||
validateVoice(voice)
|
||||
const hash = crypto.createHash('md5').update(text + voice).digest('hex')
|
||||
const filePath = path.join(CACHE_DIR, `${hash}.mp3`)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user