ESPACE PUBLICITAIRE DISPONIBLE · PARLONS-EN

Comment intégrer l'API Uberduck pour générer des voix de rap et de chant par programmation

365Finds Editorial
11 430 articles Wiki répertoriés

Utilisez 365 Wiki avec votre IA

Copiez le prompt ci-dessous, collez-le dans l’IA que vous utilisez déjà, puis posez directement votre question.

Télécharger le Skill complet

Commencez par essayer le prompt. Si vous utilisez souvent 365 Wiki, installez le Skill 365Wiki complet pour ne plus avoir à le coller. Sans IA habituelle, les versions web de Gemini ou Microsoft Copilot conviennent aussi.

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

  1. Générez votre API Key et votre API Secret dans les paramètres de votre compte Uberduck.
  2. Construisez l'en-tête HTTP Authorization :
    Authorization: Basic base64(API_KEY:API_SECRET)
    
  3. 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èsePoint de terminaison principalParamètres essentielsCas d'usage recommandé
Texte vers rap (Freestyle)POST /tts/freestylelyrics, bpm, backing_track, voice ou voicemodel_uuidMorceaux 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éePOST /speakspeech, voicemodel_uuid, pitch, duration, paceSynthè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/convertvoicemodel_uuid, input (URL audio), pitch_shiftChant 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 :

Références