Files
server-configs/edge-tts/tts-converter.js
2026-02-13 22:24:27 +08:00

100 lines
3.1 KiB
JavaScript

const edgeTTS = require('edge-tts');
const path = require('path');
const fs = require('fs');
// 默认配置
const VOICE = "zh-CN-XiaoxiaoNeural";
const OUTPUT_DIR = "/root/.openclaw/media/tts";
async function textToSpeech(text, options = {}) {
const voice = options.voice || VOICE;
const rate = options.rate || "+0%";
const pitch = options.pitch || "+0Hz";
const outputFile = options.output || path.join(OUTPUT_DIR, `tts_${Date.now()}.mp3`);
// 确保输出目录存在
fs.mkdirSync(path.dirname(outputFile), { recursive: true });
try {
const communicate = edgeTTS.Communicate(text, voice, {
rate: rate,
pitch: pitch
});
await communicate.save(outputFile);
console.log(`✅ TTS 生成成功: ${outputFile}`);
return outputFile;
} catch (error) {
console.error(`❌ TTS 生成失败: ${error.message}`);
return null;
}
}
async function listVoices() {
try {
const voices = await edgeTTS.getVoices();
console.log(`\n可用语音 (${voices.length} 个):\n`);
// 中文语音
const zhVoices = voices.filter(v => v.Lang.startsWith('zh'));
console.log("中文语音:");
zhVoices.forEach(v => console.log(` - ${v.Name} (${v.Lang})`));
// 英文语音
const enVoices = voices.filter(v => v.Lang.startsWith('en'));
console.log("\n英文语音:");
enVoices.forEach(v => console.log(` - ${v.Name} (${v.Lang})`));
return voices;
} catch (error) {
console.error(`获取语音列表失败: ${error.message}`);
return [];
}
}
// 命令行参数处理
async function main() {
const args = process.argv.slice(2);
if (args.includes('--list-voices') || args.includes('-L')) {
await listVoices();
return;
}
if (args.length === 0) {
console.log("用法:");
console.log(" node tts-converter.js \"文本内容\"");
console.log(" node tts-converter.js \"文本\" --voice zh-CN-XiaoxiaoNeural --rate +10%");
console.log(" node tts-converter.js --list-voices");
console.log("\n选项:");
console.log(" --voice, -v 语音名称");
console.log(" --rate, -r 语速 (+/-百分比)");
console.log(" --pitch, -p 音调 (+/-Hz)");
console.log(" --output, -o 输出文件路径");
return;
}
// 解析参数
let text = args[0];
let options = {
voice: VOICE,
rate: "+0%",
pitch: "+0Hz",
output: path.join(OUTPUT_DIR, `tts_${Date.now()}.mp3`)
};
for (let i = 1; i < args.length; i += 2) {
const key = args[i].replace(/^--/, '');
const value = args[i + 1];
if (key === 'voice' || key === 'v') options.voice = value;
if (key === 'rate' || key === 'r') options.rate = value;
if (key === 'pitch' || key === 'p') options.pitch = value;
if (key === 'output' || key === 'o') options.output = value;
}
await textToSpeech(text, options);
}
main();