Les développeurs d'applications musicales interactives, de PNJ dynamiques pour jeux vidéo et d'avatars virtuels (VTubers) se heurtent rapidement aux limites des interfaces graphiques : les actions manuelles dans un navigateur ne peuvent convenir aux flux de production automatisés ni aux charges de synthèse par lots à forte concurrence. Uberduck met à disposition une API REST officielle permettant de générer des pistes vocales rythmées et mélodiques directement par le code.
Pour mettre en place une intégration robuste avec l'API Uberduck, l'architecture s'articule autour de trois volets indispensables : l'authentification HTTP Basic, le choix du mode de synthèse adéquat (rap aligné sur le tempo via /tts/freestyle, contrôle paramétrique de hauteur via /speak, ou conversion vocale via /tts/convert), et la gestion d'une boucle d'interrogation asynchrone (/speak-status) pour récupérer les fichiers audio générés.
1. Authentification et architecture des requêtes
L'API REST d'Uberduck s'appuie sur le protocole standard HTTP Basic Authentication. L'API Key (identifiant) et l'API Secret (mot de passe) sont concaténés avec un séparateur deux-points (:), encodés en Base64, puis passés dans l'en-tête de requête.
Configuration des en-têtes d'autorisation
- Générez votre
API Keyet votreAPI Secretdans les paramètres de votre compte Uberduck. - Construisez l'en-tête HTTP
Authorization:Authorization: Basic base64(API_KEY:API_SECRET) - L'adresse de base du service est
https://api.uberduck.ai.
import base64
import os
API_KEY = os.getenv("UBERDUCK_API_KEY", "your_api_key")
API_SECRET = os.getenv("UBERDUCK_API_SECRET", "your_api_secret")
def get_auth_headers():
token = base64.b64encode(f"{API_KEY}:{API_SECRET}".encode("utf-8")).decode("utf-8")
return {
"Authorization": f"Basic {token}",
"Content-Type": "application/json"
}
2. Comparatif des trois modes de synthèse vocale
Selon que votre système nécessite des rimes calées sur une mesure ou une mélodie chantée avec des transitions fluides, Uberduck propose trois voies techniques :
| Mode de synthèse | Point de terminaison principal | Paramètres essentiels | Cas d'usage recommandé |
|---|---|---|---|
| Texte vers rap (Freestyle) | POST /tts/freestyle | lyrics, bpm, backing_track, voice ou voicemodel_uuid | Morceaux de rap génératifs ; joutes verbales interactives ; poésie rythmée calée sur le tempo |
| Synthèse paramétrique de hauteur et de durée | POST /speak | speech, voicemodel_uuid, pitch, duration, pace | Synthèse orchestrée par des données MIDI ou des partitions avec contrôle précis des phonèmes |
| Conversion vocale (Voice-to-Voice) | POST /tts/convert | voicemodel_uuid, input (URL audio), pitch_shift | Chant mélodique avec vibrato et intonations naturelles à partir d'une voix témoin ou d'un synthétiseur |
3. Mise en place d'un pipeline automatisé de rap
Le point de terminaison /tts/freestyle est spécialement entraîné pour aligner la cadence des syllabes sur le tempo (BPM) et la grille rythmique de la piste d'accompagnement.
Étape 1 : Récupérer les pistes d'accompagnement disponibles
Pour synchroniser vos paroles avec les instrumentales officielles d'Uberduck, interrogez la liste des morceaux :
import requests
def list_backing_tracks():
url = "https://api.uberduck.ai/reference-audio/backing-tracks?detailed=true"
response = requests.get(url, headers=get_auth_headers())
response.raise_for_status()
return response.json() # Renvoie la liste des pistes avec UUID, BPM et genre
Étape 2 : (Optionnel) Générer des paroles rimées
Si votre chaîne de traitement crée les paroles à la volée d'après un thème utilisateur, vous pouvez appeler /tts/lyrics (ou structurer la sortie d'un LLM sous forme de matrice de lignes) :
def generate_lyrics(subject, lines=4):
url = "https://api.uberduck.ai/tts/lyrics"
payload = {
"subject": subject,
"lines": lines
}
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
return response.json() # Renvoie les lignes de rimes structurées
Étape 3 : Déclencher la génération Freestyle
Transmettez la matrice de paroles, le BPM visé, l'UUID de l'instrumentale et l'identifiant du modèle vocal :
def generate_rap_vocal(lyrics_matrix, bpm=90, backing_track_uuid=None, voice="zwf"):
url = "https://api.uberduck.ai/tts/freestyle"
payload = {
"lyrics": lyrics_matrix, # Exemple : [["Le code s'exécute au tempo du serveur", "Les appels d'API riment avec vigueur"]]
"bpm": bpm,
"voice": voice,
"format": "json"
}
if backing_track_uuid:
payload["backing_track"] = backing_track_uuid
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
data = response.json()
return data["uuid"] # Renvoie l'UUID de la tâche asynchrone
4. Configuration des courbes de hauteur et chant mélodique
Le chant mélodique exige une gestion continue de la fréquence fondamentale et de la durée de tenue des phonèmes.
Approche A : Contrôle direct des courbes avec /speak
Pour les modèles de voix compatibles avec les contrôles avancés (vérifiables via GET /voices/{voicemodel_uuid}/detail avec le champ controls: true), /speak accepte des listes numériques pour pitch (demi-tons ou fréquences) et duration (durée par phonème) :
def generate_singing_notes(speech_text, voicemodel_uuid, pitch_curve, duration_curve):
"""
pitch_curve : Tableau numérique des hauteurs cibles par unité phonétique.
duration_curve : Tableau numérique des durées de maintien par phonème.
"""
url = "https://api.uberduck.ai/speak"
payload = {
"speech": speech_text,
"voicemodel_uuid": voicemodel_uuid,
"pitch": pitch_curve,
"duration": duration_curve,
"pace": 1.0
}
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
return response.json()["uuid"]
Approche B : Rendu réaliste via conversion vocale (V2V)
Calculer manuellement des listes de hauteurs phonétiques au niveau du texte brut est complexe et peut produire un rendu artificiel. Dans les systèmes professionnels, la méthode préconisée est le Voice-to-Voice (V2V) :
On génère ou enregistre une piste témoin (guide vocal joué par un synthétiseur MIDI ou chanté a cappella), puis on l'envoie à POST /tts/convert avec un décalage de tonalité pitch_shift :
def convert_guide_vocal_to_singer(guide_audio_url, target_voice_uuid, semitone_shift=0):
url = "https://api.uberduck.ai/tts/convert"
payload = {
"input": guide_audio_url,
"voicemodel_uuid": target_voice_uuid,
"pitch_shift": semitone_shift
}
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
return response.json()["uuid"]
5. Gestion asynchrone et boucle de scrutation
L'inférence neuronale audio nécessite d'importantes ressources de calcul et ne peut s'exécuter dans le délai d'une requête HTTP synchrone classique. Chaque appel de synthèse renvoie un uuid de tâche. Le backend doit interroger régulièrement /speak-status :
import time
def poll_render_completion(job_uuid, max_attempts=30, delay_seconds=2):
status_url = f"https://api.uberduck.ai/speak-status?uuid={job_uuid}"
headers = get_auth_headers()
for attempt in range(max_attempts):
response = requests.get(status_url, headers=headers)
response.raise_for_status()
data = response.json()
# Détection d'échec
if data.get("failed_at"):
raise RuntimeError(f"Échec de la tâche de synthèse : {data}")
# Détection de succès
if data.get("finished_at"):
audio_url = data.get("path")
return audio_url # URL finale de téléchargement sur le CDN
time.sleep(delay_seconds)
raise TimeoutError("Le délai de rendu a expiré.")
6. Script d'orchestration complet en Python
Voici un script fonctionnel regroupant authentification, soumission, interrogation de statut et téléchargement du fichier final :
import requests
import base64
import time
import os
UBERDUCK_API_KEY = os.getenv("UBERDUCK_API_KEY")
UBERDUCK_API_SECRET = os.getenv("UBERDUCK_API_SECRET")
HEADERS = {
"Authorization": f"Basic {base64.b64encode(f'{UBERDUCK_API_KEY}:{UBERDUCK_API_SECRET}'.encode()).decode()}",
"Content-Type": "application/json"
}
def create_rap_track(lyrics, bpm=95, voice="zwf", output_file="vocal_output.wav"):
# 1. Envoi de la demande de synthèse
print("Envoi de la requête de synthèse vocale...")
freestyle_url = "https://api.uberduck.ai/tts/freestyle"
payload = {
"lyrics": lyrics,
"bpm": bpm,
"voice": voice,
"format": "json"
}
resp = requests.post(freestyle_url, json=payload, headers=HEADERS)
resp.raise_for_status()
task_id = resp.json()["uuid"]
print(f"Tâche initiée avec l'UUID : {task_id}")
# 2. Scrutation de l'état d'avancement
status_url = f"https://api.uberduck.ai/speak-status?uuid={task_id}"
audio_url = None
for _ in range(40):
time.sleep(2)
status_resp = requests.get(status_url, headers=HEADERS)
status_resp.raise_for_status()
status_data = status_resp.json()
if status_data.get("failed_at"):
raise RuntimeError("Erreur de rendu signalée par le serveur.")
if status_data.get("finished_at"):
audio_url = status_data.get("path")
print(f"Rendu terminé avec succès : {audio_url}")
break
if not audio_url:
raise TimeoutError("La génération a dépassé 80 secondes.")
# 3. Téléchargement du fichier WAV
audio_data = requests.get(audio_url).content
with open(output_file, "wb") as f:
f.write(audio_data)
print(f"Piste vocale enregistrée sous : {output_file}")
return output_file
if __name__ == "__main__":
bars = [
["La séquence démarre synchronisée sur le beat", "Les rimes se déploient sur le canal d'élite"],
["Cadence millimétrée avec un BPM au carré", "L'API Uberduck transforme l'audio automatisé"]
]
create_rap_track(lyrics=bars, bpm=95)
7. Recommandations pour la mise en production
Lors du déploiement en environnement de production, intégrez les aspects suivants :
- Équilibre entre densité syllabique et BPM : Le nombre de syllabes par vers doit rester proportionnel au tempo. Au-delà de 110 BPM, des vers surchargés risquent de provoquer des chevauchements de prononciation ou des bruits parasites.
- Délégation asynchrone : Une génération complète requiert entre 4 et 15 secondes. Ne bloquez jamais le thread de votre serveur web ; confiez ces tâches à des files d'attente (comme Celery ou BullMQ).
- Abonnements et droits commerciaux : L'utilisation commerciale de l'API requiert un forfait payant adéquat (de type Pro ou Enterprise). Les niveaux gratuits sont cantonnés à l'expérimentation personnelle et non commerciale.
- Chaîne de traitement audio (DSP) : Les fichiers générés sont généralement livrés sous forme de pistes brutes (Dry Stems). Pour un rendu musical de qualité studio, appliquez une chaîne de mixage en aval avec égalisation, compression et réverbération.
Références
- Uberduck API Documentation
- Generate Freestyle - Uberduck Text To Speech API
- Generate Lyrics - Uberduck Text To Speech API
- Generate Speech - Uberduck Text To Speech API
- Voice To Voice Conversion - Uberduck Text To Speech API
- Get text-to-speech request status - Uberduck Text To Speech API
- List Backing Tracks - Uberduck Text To Speech API
- Uberduck AI Pricing and Plans