const fs = require('fs') const path = require('path') const envPath = path.join(process.env.USERPROFILE || 'C:\\Users\\Administrator', 'Toolbox_local_creds.env.local') if (fs.existsSync(envPath)) { const text = fs.readFileSync(envPath, 'utf8') for (const line of text.split(/\r?\n/)) { if (!line || /^\s*#/.test(line)) continue const i = line.indexOf('=') if (i < 0) continue const k = line.slice(0, i).trim(), v = line.slice(i + 1).trim().replace(/^["']|["']$/g, '') if (k && !(k in process.env)) process.env[k] = v } } global.__builtin_fetch = globalThis.fetch const API_KEY = process.env.DASHSCOPE_API_KEY const CANDIDATES = [] CANDIDATES.push({ name: 'A1 Qwen-TTS 推荐 Fallback-A:multimodal-generation/generation (model=qwen3-tts-flash, voice=Cherry, 同步audio.url)', url: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', body: { model: 'qwen3-tts-flash', input: { text: '热身开合跳', voice: 'Cherry', language_type: 'Chinese' } } }) CANDIDATES.push({ name: 'A2 qwen-audio-3.0-tts-flash Cherry', url: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', body: { model: 'qwen-audio-3.0-tts-flash', input: { text: '热身开合跳', voice: 'Cherry', language_type: 'Chinese' } } }) CANDIDATES.push({ name: 'A3 qwen3-tts-flash 中文女声 Xiaobei', url: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation', body: { model: 'qwen3-tts-flash', input: { text: '热身开合跳,加油坚持。', voice: 'Xiaobei', language_type: 'Chinese' } } }) CANDIDATES.push({ name: 'A4 CosyVoice WorkspaceId 端点占位(有 WorkspaceId 就填,否则直接走 Fallback A)', url: 'https://dashscope.aliyuncs.com/api/v1/services/audio/tts/SpeechSynthesizer', body: { model: 'cosyvoice-v3-flash', input: { text: '热身开合跳', voice: 'longanyang', format: 'mp3', sample_rate: 24000 } } }) ;(async () => { for (const c of CANDIDATES) { console.log('\n======== 试 ' + c.name + ' ========') try { const resp = await global.__builtin_fetch(c.url, { method: 'POST', headers: Object.assign({ 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, c.headers || {}), body: JSON.stringify(c.body), }) console.log('status=', resp.status, 'CT=', resp.headers.get('content-type')) const ct = resp.headers.get('content-type') || '' if (ct.indexOf('application/json') >= 0) { const j = await resp.json() console.log('json=', JSON.stringify(j).slice(0, 500)) } else { const buf = Buffer.from(await resp.arrayBuffer()) console.log('bytes=', buf.length, 'HEAD=', [...buf.slice(0, 4)].map(b => b.toString(16)).join(' ')) const p = path.join(process.env.TEMP || '.', 'tts_test_' + Date.now() + '.mp3') fs.writeFileSync(p, buf) console.log('saved mp3=', p, 'sizeKB=', Math.round(buf.length/1024)) } } catch (e) { console.error('ERR', e && e.message ? e.message : e) } } })()