Guide d'intégration AITuberKit × AICU API
Comment brancher la synthèse vocale (TTS) d'AICU sur AITuberKit
Présentation
AITuberKit est une application web pour converser avec des personnages IA. Pointez-la vers l'endpoint TTS de l'AICU API et vous obtenez une voix japonaise de haute qualité.
- Démo : https://aituberkit.shirai.as/
- GitHub : https://github.com/kaitas/aituber-kit
Variables d'environnement
Ajoutez ce qui suit à .env.local :
# Réglages de l'AICU API
AICU_API_KEY=aicu_live_xxxxxxxxxxxxxxxx
AICU_API_URL=https://api.aicu.ai/v1
# Réglages du personnage (utilisez soit slug, soit char_id)
AICU_SLUG=luc4 # Slug du personnage
# AICU_CHAR_ID=0 # ou l'identifiant numérique
Exemples TypeScript
Client TTS
// lib/aicu-tts.ts
interface TTSOptions {
text: string;
slug?: string; // Slug du personnage (recommandé)
char_id?: number; // ou l'identifiant numérique
voice?: string;
seed?: number;
instruct?: string;
force?: boolean; // Contourner le cache
}
export async function generateSpeech(options: TTSOptions): Promise<ArrayBuffer> {
const response = await fetch(`${process.env.AICU_API_URL}/tts/generate`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AICU_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: options.text,
slug: options.slug || process.env.AICU_SLUG,
char_id: options.char_id,
voice: options.voice,
seed: options.seed,
instruct: options.instruct,
force: options.force,
format: 'mp3',
}),
});
if (!response.ok) {
throw new Error(`TTS Error: ${response.status}`);
}
// Journaliser les en-têtes de réponse
const cacheHit = response.headers.get('X-Cache-Hit');
const creditsUsed = response.headers.get('X-Credits-Used');
console.log(`Cache: ${cacheHit}, Credits: ${creditsUsed}`);
return response.arrayBuffer();
}
Hook React
// hooks/useAicuTTS.ts
import { useState, useCallback } from 'react';
export function useAicuTTS() {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const speak = useCallback(async (text: string) => {
setIsLoading(true);
setError(null);
try {
const res = await fetch('/api/tts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text }),
});
if (!res.ok) throw new Error('TTS failed');
const audioBlob = await res.blob();
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
await audio.play();
// Nettoyage
audio.onended = () => URL.revokeObjectURL(audioUrl);
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
} finally {
setIsLoading(false);
}
}, []);
return { speak, isLoading, error };
}
Route d'API (Next.js)
// app/api/tts/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const { text, slug, char_id, force } = await request.json();
const response = await fetch('https://api.aicu.ai/v1/tts/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AICU_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text,
slug: slug || process.env.AICU_SLUG || 'luc4',
char_id,
force,
format: 'mp3',
}),
});
if (!response.ok) {
return NextResponse.json(
{ error: 'TTS generation failed' },
{ status: response.status }
);
}
const audioBuffer = await response.arrayBuffer();
return new NextResponse(audioBuffer, {
headers: {
'Content-Type': 'audio/mpeg',
'X-Cache-Hit': response.headers.get('X-Cache-Hit') || 'false',
'X-Slug': response.headers.get('X-Slug') || '',
'X-Credits-Used': response.headers.get('X-Credits-Used') || '0',
},
});
}
Réglages des personnages (CharID)
| char_id | slug | Nom | Voix | Seed | Modèle | État |
|---|---|---|---|---|---|---|
| 0 | luc4 | LuC4 | luc4 | — | eleven_multilingual_v2 | public |
| 1 | elena | Elena Bloom | elena | 330 | eleven_multilingual_v2 | public |
| 2 | mei | Mei Soleil | mei | 721 | eleven_multilingual_v2 | public |
| 3 | mina | Mina Azure | mina | 105 | eleven_multilingual_v2 | public |
| 4 | nao | Nao Verde | nao | — | eleven_v4 | public |
| 5 | saki | Saki Noire | saki | 1035 | eleven_multilingual_v2 | public |
| 6 | marsha | Marsha Arancia | marsha | 414 | eleven_multilingual_v2 | public |
Ce tableau est un instantané. GET /v1/char contient toujours la liste à jour, et c'est le seul endroit qui la contient — voir l'API Personnages. Une voix sans seed est fixée à un modèle à la place.
Utilisation :
// Sélection par slug (recommandé)
await generateSpeech({ text: 'こんにちは', slug: 'luc4' });
// Sélection par char_id
await generateSpeech({ text: 'こんにちは', char_id: 0 });
Direction du style vocal (instruct)
Utilisez le paramètre instruct pour orienter le débit et l'intonation :
// Un salut plein d'entrain
await generateSpeech({
text: 'おはようございます!',
voice: 'mei',
instruct: 'Speak with energy and excitement',
});
// Une explication posée
await generateSpeech({
text: '本日の予定を説明します。',
voice: 'serena',
instruct: 'Speak calmly and clearly like a professional narrator',
});
// Un chuchotement
await generateSpeech({
text: '秘密だよ...',
voice: 'vivian',
instruct: 'Whisper softly',
});
Dépannage
401 Unauthorized
→ La clé API n'est pas valide. Émettez-en une nouvelle depuis le tableau de bord.
402 Payment Required
→ Vous n'avez plus de crédits. Achetez un complément ou passez à une offre supérieure.
429 Too Many Requests
→ Vous avez atteint la limite de débit. Vérifiez les limites qui s'appliquent à votre offre.
Assistance
- Tableau de bord de l'AICU API : https://api.aicu.ai/dashboard
- GitHub d'AITuberKit : https://github.com/kaitas/aituber-kit
- Contact : https://aicu.ai/contact
© 2026 AICU Inc.