Los desarrolladores e ingenieros de audio que construyen aplicaciones interactivas de música, personajes virtuales (VTubers) o experiencias de videojuegos a menudo se enfrentan a un cuello de botella con las interfaces web: el flujo de trabajo manual en el navegador no permite la automatización ni soporta llamadas concurrentes en entornos de producción. Uberduck ofrece una API REST oficial diseñada para sintetizar voces musicales directamente mediante código.
Para integrar la API de Uberduck en una arquitectura automatizada de rap y canto, es necesario coordinar tres capas técnicas: autenticación HTTP Basic, selección del modo de síntesis adecuado (/tts/freestyle sincronizado con el tempo, /speak con curvas de tono o conversión vocal /tts/convert), y un bucle de sondeo asíncrono sobre /speak-status para obtener los archivos de audio renderizados.
1. Autenticación y arquitectura de peticiones
La API REST de Uberduck utiliza el protocolo estándar de autenticación HTTP Basic. Los desarrolladores deben combinar su API Key (nombre de usuario) y API Secret (contraseña) en una cadena codificada en Base64 e insertarla en el encabezado de la solicitud.
Configuración del encabezado de autorización
- Obtén tu
API KeyyAPI Secretdesde el panel de control de Uberduck. - Construye el encabezado HTTP
Authorization:Authorization: Basic base64(API_KEY:API_SECRET) - La URL base del servicio es
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. Modalidades de síntesis vocal programática
Dependiendo de si tu aplicación requiere rimas estructuradas sobre un compás o una melodía cantada continua, Uberduck ofrece tres alternativas:
| Modalidad | Endpoint principal | Parámetros clave | Caso de uso recomendado |
|---|---|---|---|
| Texto a rap (Freestyle) | POST /tts/freestyle | lyrics, bpm, backing_track, voice o voicemodel_uuid | Pistas de rap generativo; batallas de rap dinámicas; lírica sincronizada con el tempo |
| Síntesis paramétrica de tono y duración | POST /speak | speech, voicemodel_uuid, pitch, duration, pace | Síntesis precisa guiada por datos MIDI o partituras donde se controlan semitonos y fonemas |
| Conversión vocal (Voice-to-Voice) | POST /tts/convert | voicemodel_uuid, input (URL de audio), pitch_shift | Canto melódico con vibrato y modulación natural a partir de una voz guía o sintetizador |
3. Construcción del pipeline automatizado de rap
El endpoint /tts/freestyle está optimizado para ajustar sílabas al pulso musical (BPM) y al compás de la pista de acompañamiento.
Paso 1: Consultar pistas instrumentales disponibles
Si deseas que la voz encaje con instrumentales de la biblioteca de Uberduck, puedes consultar los temas disponibles:
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() # Devuelve la lista de pistas con UUID, BPM y género
Paso 2: (Opcional) Generar letras con rima
Si el pipeline genera las rimas automáticamente a partir de una temática del usuario, puedes consultar /tts/lyrics (o estructurar la respuesta de un LLM en matrices de cadenas):
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() # Devuelve las barras estructuradas
Paso 3: Enviar la solicitud de Freestyle
Envía la matriz de letras (versos agrupados), el tempo deseado en BPM, el UUID del ritmo y el modelo de voz:
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, # Ejemplo: [["El código fluye al compás del servidor", "Llamadas API rimando con vigor"]]
"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"] # Retorna el UUID de la tarea asíncrona
4. Configuración de líneas melódicas y voz cantada
El canto melódico requiere un control continuo de las frecuencias fundamentales y de la duración de cada sonido.
Enfoque A: Control paramétrico con /speak
Para modelos de voz que admiten controles expresivos (verificables mediante GET /voices/{voicemodel_uuid}/detail comprobando que controls: true), el endpoint /speak acepta arreglos de pitch (curva tonal) y duration (duración por fonema):
def generate_singing_notes(speech_text, voicemodel_uuid, pitch_curve, duration_curve):
"""
pitch_curve: Lista de números que representan semitonos o frecuencias diana.
duration_curve: Lista de números con la duración de cada unidad fonética.
"""
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"]
Enfoque B: Canto natural mediante conversión vocal (V2V)
Definir manualmente curvas numéricas para cada fonema puede sonar robótico y complejo de calcular. En producción, la alternativa más orgánica es Voice-to-Voice (V2V):
Se genera una voz guía preliminar (por ejemplo, con un sintetizador vocal MIDI o una toma guía humana) y se pasa a POST /tts/convert, ajustando pitch_shift para cambiar la tonalidad si es necesario:
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. Ciclo de vida asíncrono y sondeo de tareas
Debido a la alta demanda computacional de las redes neuronales de audio, las peticiones devuelven un identificador de tarea (uuid). El backend debe consultar periódicamente el estado en /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()
# Detección de fallos
if data.get("failed_at"):
raise RuntimeError(f"La tarea de síntesis falló: {data}")
# Comprobación de éxito
if data.get("finished_at"):
audio_url = data.get("path")
return audio_url # URL final del archivo de audio renderizado
time.sleep(delay_seconds)
raise TimeoutError("El renderizado excedió el tiempo límite.")
6. Script completo de orquestación
A continuación se muestra un script de integración integral en Python listo para ejecutar:
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. Enviar solicitud de síntesis de rap
print("Enviando petición a Uberduck API...")
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"Tarea iniciada con UUID: {task_id}")
# 2. Sondeo de estado
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("Error en el servidor al procesar el audio.")
if status_data.get("finished_at"):
audio_url = status_data.get("path")
print(f"Renderizado completado: {audio_url}")
break
if not audio_url:
raise TimeoutError("La generación tardó más de 80 segundos.")
# 3. Descarga del archivo final
audio_data = requests.get(audio_url).content
with open(output_file, "wb") as f:
f.write(audio_data)
print(f"Audio guardado exitosamente en {output_file}")
return output_file
if __name__ == "__main__":
barras = [
["Iniciando la secuencia con el beat automatizado", "Sintetizando las rimas el proceso está activado"],
["El compás se mantiene exacto con el BPM en control", "La API de Uberduck domina la sesión de rock and roll"]
]
create_rap_track(lyrics=barras, bpm=95)
7. Buenas prácticas y consideraciones de producción
Al desplegar este pipeline en entornos comerciales, ten en cuenta los siguientes factores:
- Densidad silábica y tempo: El número de sílabas por verso debe guardar coherencia con la velocidad en BPM. A ritmos superiores a 110 BPM, letras excesivamente densas provocan artefactos vocales o cortes bruscos de dicción.
- Desacoplamiento asíncrono: La generación toma entre 4 y 15 segundos. No bloquees los hilos de tus controladores HTTP; utiliza colas de mensajería como Celery o BullMQ para procesar el audio en segundo plano.
- Licencias y planes comerciales: El acceso por API y el uso de los archivos generados en productos con fines comerciales requieren planes de pago (Pro o Enterprise). Los niveles gratuitos están restringidos a fines no comerciales.
- Postprocesamiento de audio: El audio devuelto se entrega generalmente sin masterizar (Dry Stem). Para una mezcla comercial competitiva, añade una cadena de procesamiento con ecualización, compresión dinámica y reverberación.
Referencias
- 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