|
export class ElevenLabsClient { |
|
private apiKey: string; |
|
private baseUrl = "https://api.elevenlabs.io/v1"; |
|
|
|
constructor(apiKey: string) { |
|
this.apiKey = apiKey; |
|
} |
|
|
|
async getVoices(): Promise<any[]> { |
|
const response = await fetch(`${this.baseUrl}/voices`, { |
|
headers: { |
|
"xi-api-key": this.apiKey, |
|
}, |
|
}); |
|
|
|
if (!response.ok) { |
|
throw new Error(`Failed to get voices: ${response.statusText}`); |
|
} |
|
|
|
const data = await response.json(); |
|
return data.voices; |
|
} |
|
|
|
async deleteVoice(voiceId: string): Promise<void> { |
|
const response = await fetch(`${this.baseUrl}/voices/${voiceId}`, { |
|
method: "DELETE", |
|
headers: { |
|
"xi-api-key": this.apiKey, |
|
}, |
|
}); |
|
|
|
if (!response.ok) { |
|
console.error("ElevenLabs error:", await response.text()); |
|
throw new Error(`Failed to delete voice: ${response.statusText}`); |
|
} |
|
} |
|
|
|
async addVoice(name: string, audioFile: File): Promise<string> { |
|
const formData = new FormData(); |
|
formData.append("name", name); |
|
formData.append("files", audioFile); |
|
formData.append("description", "Voice generated for NotMe game"); |
|
|
|
const response = await fetch(`${this.baseUrl}/voices/add`, { |
|
method: "POST", |
|
headers: { |
|
"xi-api-key": this.apiKey, |
|
}, |
|
body: formData, |
|
}); |
|
|
|
if (!response.ok) { |
|
console.error("ElevenLabs error:", await response.text()); |
|
throw new Error(`Failed to add voice: ${response.statusText}`); |
|
} |
|
|
|
const data = await response.json(); |
|
return data.voice_id; |
|
} |
|
|
|
async generateSpeech(voiceId: string, text: string): Promise<Buffer> { |
|
const response = await fetch( |
|
`${this.baseUrl}/text-to-speech/${voiceId}/stream`, |
|
{ |
|
method: "POST", |
|
headers: { |
|
"xi-api-key": this.apiKey, |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify({ |
|
text, |
|
model_id: "eleven_monolingual_v1", |
|
voice_settings: { |
|
stability: 0.5, |
|
similarity_boost: 0.75, |
|
}, |
|
}), |
|
} |
|
); |
|
|
|
if (!response.ok) { |
|
throw new Error(`Failed to generate speech: ${response.statusText}`); |
|
} |
|
|
|
const arrayBuffer = await response.arrayBuffer(); |
|
return Buffer.from(arrayBuffer); |
|
} |
|
} |
|
|