Files
2026-06-19 18:45:55 +08:00

76 lines
2.0 KiB
TypeScript

/**
* 阿里云语音服务模块入口
* 整合 CosyVoice (TTS) 和 FunASR (ASR) 功能
*/
import * as cosyvoice from './cosyvoice';
import * as funasr from './funasr';
import * as enrollment from './enrollment';
import logger from '../log/main';
export {
cosyvoice,
funasr,
enrollment
};
// 导出主要函数
export const {
synthesizeSpeech,
getAvailableVoices
} = cosyvoice;
export const {
recognizeAudio,
detectAudioFormat
} = funasr;
// 导出类型
export type {
CosyVoiceConfig,
CosyVoiceResult
} from './cosyvoice';
export type {
FunAsrConfig,
FunAsrResult,
AsrSentence,
AsrWord
} from './funasr';
/**
* 执行声音复刻流程
*/
export async function enrollVoice(params: {
apiKey: string,
audioPath: string,
name: string
}): Promise<{ success: boolean, voiceId?: string, error?: string }> {
try {
logger.info('[Aliyun] 开始执行声音复刻', { name: params.name, audioPath: params.audioPath });
// 1. 上传文件获取 URL
const audioUrl = await enrollment.uploadFileToLease(params.apiKey, params.audioPath);
// 2. 创建音色
// 使用 name 作为 prefix,但需过滤非法字符(仅允许数字、字母、下划线)
// 阿里云要求 prefix: [a-zA-Z0-9_]{1,10}
// 如果 name 有中文,替换为 custom
let prefix = params.name.replace(/[^a-zA-Z0-9_]/g, '');
// 阿里云要求 prefix: [a-zA-Z0-9_]{1,10}
// 如果处理后为空,或者还是太长,则进行截断或使用默认值
if (!prefix) {
prefix = 'custom';
} else if (prefix.length > 10) {
prefix = prefix.substring(0, 10);
}
const voiceId = await enrollment.createVoice(params.apiKey, audioUrl, prefix);
return { success: true, voiceId };
} catch (error: any) {
logger.error('[Aliyun] 声音复刻失败', error);
return { success: false, error: error.message };
}
}