@aituber-onair/voice
Version:
Voice synthesis library for AITuber OnAir
62 lines (61 loc) • 2.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.VoicePeakEngine = void 0;
const voiceEngine_1 = require("../constants/voiceEngine");
/**
* VoicePeak voice synthesis engine
*/
class VoicePeakEngine {
constructor() {
this.apiEndpoint = voiceEngine_1.VOICEPEAK_API_URL;
}
async fetchAudio(input, speaker) {
const talk = input;
const ttsQueryResponse = await fetch(`${this.apiEndpoint}/audio_query?speaker=${speaker}&text=${encodeURIComponent(talk.message)}`, { method: 'POST' });
if (!ttsQueryResponse.ok) {
throw new Error('Failed to fetch TTS query.');
}
const ttsQueryJson = await ttsQueryResponse.json();
// set emotion from talk.style
ttsQueryJson['emotion'] = this.mapEmotionStyle(talk.style || 'neutral');
const synthesisResponse = await fetch(`${this.apiEndpoint}/synthesis?speaker=${speaker}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(ttsQueryJson),
});
if (!synthesisResponse.ok) {
throw new Error('Failed to fetch TTS synthesis result.');
}
const blob = await synthesisResponse.blob();
return await blob.arrayBuffer();
}
/**
* Map emotion style to VoicePeak's emotion parameters
*/
mapEmotionStyle(style) {
switch (style.toLowerCase()) {
case 'happy':
case 'fun':
return 'happy';
case 'angry':
return 'angry';
case 'sad':
return 'sad';
case 'surprised':
return 'surprised';
default:
return 'neutral';
}
}
getTestMessage(textVoiceText) {
return textVoiceText || 'ボイスピークを使用します';
}
/**
* Set custom API endpoint URL
* @param apiUrl custom API endpoint URL
*/
setApiEndpoint(apiUrl) {
this.apiEndpoint = apiUrl;
}
}
exports.VoicePeakEngine = VoicePeakEngine;