// CosyVoice 可用性探针:拿本机 .env 的 DASHSCOPE key 打真实语音合成,报「能用/不能用+确切错误」。 // 用法(服务器后端目录内,.env 已配 DASHSCOPE_API_KEY): node scripts/probe-tts.mjs // // 结果解读: // ✅ 出音(音频字节>0) → 该 (model, voice) 可用。 // ❌ ModelNotFound / 未开通 → 百炼账号未开通该 CosyVoice 版本(账号层,去百炼控制台开通)。 // ❌ voice 不匹配/无此音色 → 该版本的预置音色名不对(v2/v3/v3.5 音色不通用)。 import 'dotenv/config'; import { config } from '../src/config.js'; import { synthesizeWs } from '../src/services/ttsWs.js'; // 探测组合:预置音(v2 最可能已开) + 你当前克隆音默认版本(用 v2 音色仅为触发,看是"模型未开"还是"音色不匹配")。 const CASES = [ { label: '预置音 v2', model: 'cosyvoice-v2', voice: 'longwan_v2' }, { label: `克隆默认(${config.tts.cloneModel})`, model: config.tts.cloneModel, voice: 'longwan_v2' }, ]; console.log('DASHSCOPE key:', config.llm.dashscopeKey ? '已配(尾4:' + config.llm.dashscopeKey.slice(-4) + ')' : '❌未配'); console.log('WS 端点:', config.tts.wsUrl); console.log('config.tts:', JSON.stringify(config.tts)); console.log('──────── 探测 ────────'); for (const c of CASES) { process.stdout.write(`· ${c.label} [${c.model} / ${c.voice}] … `); try { const r = await synthesizeWs('你好,这是一次语音合成测试。', { voiceId: c.voice, model: c.model }); const bytes = r?.audio ? Buffer.from(r.audio, 'base64').length : 0; console.log(bytes > 0 ? `✅ 出音 ${bytes} 字节` : '❌ 无音频'); } catch (e) { console.log('❌', String(e?.message || e)); } } process.exit(0);