gpt-sovits-sdk
Version:
Node.js SDK for GPT-SoVITS API
300 lines (299 loc) • 11.6 kB
JavaScript
;
/**
* GPT-SoVITS SDK 高级测试脚本
*
* 这个脚本用于测试SDK的高级功能和错误处理,包括:
* 1. 错误处理和重试机制
* 2. 模型配对功能
* 3. 批量处理文本
* 4. 取消请求功能
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("./index");
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
// 创建输出目录
const outputDir = path.join(__dirname, '../test-output/advanced');
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// 创建客户端实例
const client = (0, index_1.createClient)({
baseUrl: 'http://127.0.0.1:9880',
timeout: 60000,
debug: true,
retries: 2
});
/**
* 测试错误处理
*/
async function testErrorHandling() {
console.log('=== 测试错误处理 ===');
// 测试无效URL
try {
console.log('测试无效URL...');
const invalidClient = (0, index_1.createClient)({
baseUrl: 'http://invalid-url-that-does-not-exist:9880',
timeout: 5000, // 设置较短的超时时间
retries: 1
});
await invalidClient.getRoot();
console.log('❌ 应该抛出错误,但没有');
}
catch (error) {
if (error instanceof index_1.GPTSoVITSError) {
console.log('✅ 正确捕获了错误:', error.message);
console.log('- 错误代码:', error.code);
console.log('- 请求URL:', error.url);
console.log('- 请求方法:', error.method);
}
else {
console.log('✅ 捕获了错误 (非SDK错误类型):', error);
}
}
// 测试无效的模型路径
try {
console.log('\n测试无效的模型路径...');
await client.setGptModel('non-existent-model-path.ckpt');
console.log('❌ 应该抛出错误,但没有');
}
catch (error) {
if (error instanceof index_1.GPTSoVITSError) {
console.log('✅ 正确捕获了错误:', error.message);
}
else {
console.log('✅ 捕获了错误 (非SDK错误类型):', error);
}
}
console.log('错误处理测试完成');
}
/**
* 测试模型配对功能
*/
async function testModelPairing() {
console.log('\n=== 测试模型配对功能 ===');
try {
// 获取所有模型
const models = await client.getModels();
// 添加空值检查
const gptModels = models?.gpt_models || [];
const sovitsModels = models?.sovits_models || [];
if (gptModels.length === 0 || sovitsModels.length === 0) {
console.log('⚠️ 缺少必要的模型,跳过模型配对测试');
return [];
}
console.log(`找到 ${gptModels.length} 个GPT模型和 ${sovitsModels.length} 个SoVITS模型`);
// 尝试自动配对模型
const pairs = [];
// 基于名称相似度进行配对
for (const gptModel of gptModels) {
// 提取GPT模型名称的基本部分(去除后缀和版本号)
const gptBaseName = gptModel.name.replace(/\.ckpt$|\.pth$|-e\d+$|-epoch\d+$/, '');
// 查找匹配的SoVITS模型
const matchingSovitsModels = sovitsModels.filter(sovitsModel => {
const sovitsBaseName = sovitsModel.name.replace(/\.ckpt$|\.pth$|-e\d+$|-epoch\d+$/, '');
return sovitsBaseName === gptBaseName ||
sovitsBaseName.includes(gptBaseName) ||
gptBaseName.includes(sovitsBaseName);
});
if (matchingSovitsModels.length > 0) {
// 使用最匹配的SoVITS模型
pairs.push({
name: gptBaseName,
gptModel,
sovitsModel: matchingSovitsModels[0]
});
}
}
console.log(`自动配对了 ${pairs.length} 对模型`);
pairs.forEach((pair, index) => {
console.log(`配对 ${index + 1}: ${pair.name}`);
console.log(` GPT: ${pair.gptModel.path}`);
console.log(` SoVITS: ${pair.sovitsModel.path}`);
});
// 如果有配对的模型,测试第一对
if (pairs.length > 0) {
const pair = pairs[0];
console.log(`\n测试模型配对: ${pair.name}`);
// 设置模型
await client.setGptModel(pair.gptModel.path);
await client.setSovitsModel(pair.sovitsModel.path);
// 获取参考音频
const referenceAudios = await client.getReferenceAudios();
const audios = referenceAudios?.audios || [];
if (audios.length > 0) {
const refAudio = audios[0];
console.log(`使用参考音频: ${refAudio.name}`);
// 执行TTS
const outputPath = path.join(outputDir, `model_pair_${pair.name}_${Date.now()}.wav`);
await client.textToSpeechDirect({
text: '这是模型配对测试,验证自动配对的模型是否能正常工作。',
textLang: index_1.TextLanguage.CHINESE,
refAudioPath: refAudio.path,
promptLang: index_1.TextLanguage.CHINESE,
mediaType: index_1.MediaType.WAV
}, outputPath);
console.log('✅ 模型配对测试成功,音频已保存到:', outputPath);
}
else {
console.log('⚠️ 没有找到参考音频,无法完成模型配对测试');
}
}
return pairs;
}
catch (error) {
console.error('❌ 模型配对测试失败:', error);
return [];
}
}
/**
* 测试批量处理文本
*/
async function testBatchProcessing(modelPairs) {
console.log('\n=== 测试批量处理文本 ===');
if (!modelPairs || modelPairs.length === 0) {
console.log('⚠️ 没有可用的模型配对,跳过批量处理测试');
return;
}
try {
// 使用第一对模型
const pair = modelPairs[0];
// 获取参考音频
const referenceAudios = await client.getReferenceAudios();
const audios = referenceAudios?.audios || [];
if (audios.length === 0) {
console.log('⚠️ 没有找到参考音频,无法完成批量处理测试');
return;
}
const refAudio = audios[0];
// 设置模型
await client.setGptModel(pair.gptModel.path);
await client.setSovitsModel(pair.sovitsModel.path);
// 准备测试文本
const testTexts = [
'这是第一条测试文本,用于批量处理测试。',
'这是第二条测试文本,验证SDK的批量处理能力。',
'这是第三条测试文本,测试SDK的稳定性和性能。'
];
console.log(`开始批量处理 ${testTexts.length} 条文本...`);
// 批量处理
for (let i = 0; i < testTexts.length; i++) {
const text = testTexts[i];
console.log(`处理文本 ${i + 1}/${testTexts.length}: ${text}`);
const outputPath = path.join(outputDir, `batch_${i + 1}_${Date.now()}.wav`);
await client.textToSpeechDirect({
text,
textLang: index_1.TextLanguage.CHINESE,
refAudioPath: refAudio.path,
promptLang: index_1.TextLanguage.CHINESE,
mediaType: index_1.MediaType.WAV
}, outputPath);
console.log(`✅ 文本 ${i + 1} 处理完成: ${outputPath}`);
}
console.log('✅ 批量处理测试成功');
}
catch (error) {
console.error('❌ 批量处理测试失败:', error);
}
}
/**
* 测试取消请求功能
*/
async function testCancelRequest() {
console.log('\n=== 测试取消请求功能 ===');
try {
// 获取参考音频
const referenceAudios = await client.getReferenceAudios();
const audios = referenceAudios?.audios || [];
if (audios.length === 0) {
console.log('⚠️ 没有找到参考音频,无法完成取消请求测试');
return;
}
const refAudio = audios[0];
// 创建一个长文本,确保处理需要一定时间
const longText = '这是一个非常长的文本,用于测试取消请求功能。'.repeat(20);
console.log('发起长文本TTS请求...');
// 创建一个Promise,在短时间后取消请求
const cancelPromise = new Promise(resolve => {
setTimeout(() => {
console.log('取消请求...');
client.abort();
resolve();
}, 2000); // 2秒后取消
});
// 创建TTS请求
const ttsPromise = client.textToSpeech({
text: longText,
textLang: index_1.TextLanguage.CHINESE,
refAudioPath: refAudio.path,
promptLang: index_1.TextLanguage.CHINESE,
mediaType: index_1.MediaType.WAV
});
// 等待取消操作完成
await cancelPromise;
try {
// 尝试等待TTS请求完成(应该会失败)
await ttsPromise;
console.log('❌ 请求应该被取消,但成功完成了');
}
catch (error) {
console.log('✅ 请求被成功取消:', error.message);
}
console.log('✅ 取消请求测试完成');
}
catch (error) {
console.error('❌ 取消请求测试失败:', error);
}
}
/**
* 运行所有高级测试
*/
async function runAdvancedTests() {
console.log('开始高级测试 GPT-SoVITS SDK...\n');
// 测试错误处理
await testErrorHandling();
// 测试模型配对
const modelPairs = await testModelPairing();
// 测试批量处理
await testBatchProcessing(modelPairs);
// 测试取消请求
await testCancelRequest();
console.log('\n高级测试完成!');
}
// 执行高级测试
runAdvancedTests().catch(error => {
console.error('测试过程中发生错误:', error);
});