@aituber-onair/core
Version:
Core library for AITuber OnAir providing voice synthesis and chat processing
56 lines • 1.92 kB
JavaScript
import { VOICEPEAK_API_URL } from '../../../constants';
/**
* VoicePeak voice synthesis engine
*/
export class VoicePeakEngine {
constructor() {
this.apiEndpoint = 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';
default:
return 'neutral';
}
}
getTestMessage(textVoiceText) {
return textVoiceText || 'ボイスピークを使用します';
}
/**
* Set custom API endpoint URL
* @param apiUrl custom API endpoint URL
*/
setApiEndpoint(apiUrl) {
this.apiEndpoint = apiUrl;
}
}
//# sourceMappingURL=VoicePeakEngine.js.map