ESPAÇO PUBLICITÁRIO DISPONÍVEL · FALE CONOSCO

Como integrar a API do Uberduck para gerar vocais de rap e canto programaticamente

365Finds Editorial
11.430 artigos Wiki catalogados

Use o 365 Wiki com sua IA

Copie o prompt abaixo, cole na IA que você já usa e faça sua pergunta.

Baixar o Skill completo

Experimente primeiro com o prompt. Se você usa o 365 Wiki com frequência, instale o Skill completo do 365Wiki para não precisar colá-lo novamente. Se não usa uma IA específica, as versões web do Gemini ou Microsoft Copilot também servem.

Desenvolvedores e engenheiros de áudio que criam aplicativos de música interativa, avatares virtuais (VTubers) ou trilhas sonoras dinâmicas para jogos frequentemente esbarram nas limitações de interfaces web manuais: a operação manual no navegador não escala e inviabiliza processos automatizados em lote ou pipelines de produção em tempo real. A Uberduck disponibiliza uma API REST oficial projetada para permitir a síntese programática de vocais musicais diretamente via código.

Integrar a API da Uberduck para gerar vocais cantados e rimados exige a orquestração de três camadas principais: autenticação HTTP Basic, escolha da modalidade de síntese correta (rap sincronizado via /tts/freestyle, síntese paramétrica com curvas de afinação via /speak ou conversão de voz via /tts/convert) e gerenciamento de fila de consulta assíncrona (/speak-status) para recuperação dos arquivos de áudio.


1. Autenticação e arquitetura de requisição

A API REST da Uberduck adota o protocolo padrão de autenticação HTTP Basic. Os desenvolvedores devem codificar suas credenciais combinando a API Key (usuário) e o API Secret (senha) em formato Base64 e enviá-las no cabeçalho das requisições.

Configuração do cabeçalho de autorização

  1. Gere sua API Key e API Secret no painel de configurações da sua conta Uberduck.
  2. Monte o cabeçalho HTTP Authorization:
    Authorization: Basic base64(API_KEY:API_SECRET)
    
  3. A URL base de comunicação é https://api.uberduck.ai.
import base64
import os

API_KEY = os.getenv("UBERDUCK_API_KEY", "sua_api_key")
API_SECRET = os.getenv("UBERDUCK_API_SECRET", "seu_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íntese vocal programática

Dependendo de sua aplicação demandar versos ritmados sobre uma batida ou linhas melódicas contínuas de canto, a Uberduck disponibiliza três estratégias distintas:

Modalidade de sínteseEndpoint principalParâmetros essenciaisCaso de uso ideal
Texto para Rap (Freestyle)POST /tts/freestylelyrics, bpm, backing_track, voice ou voicemodel_uuidGeração de faixas de rap; batalhas de rima interativas; poesia cadenciada e sincronizada ao ritmo
Síntese paramétrica de afinação e tempoPOST /speakspeech, voicemodel_uuid, pitch, duration, paceSíntese de canções a partir de dados MIDI ou partituras numéricas com controle de semitons e fonemas
Conversão vocal (Voice-to-Voice)POST /tts/convertvoicemodel_uuid, input (URL de áudio), pitch_shiftCanto melódico com vibratos e transições naturais a partir de uma faixa guia gravada ou sintetizada

3. Construindo um pipeline automatizado de Rap

O endpoint /tts/freestyle alinha e sincroniza automaticamente a métrica das sílabas ao andamento musical (BPM) e à métrica da base instrumental.

Passo 1: Listar bases instrumentais disponíveis

Para encaixar rimas em bases instrumentais pré-carregadas da biblioteca da Uberduck, consulte a lista de faixas:

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()  # Retorna lista com UUIDs, BPM e metadados de gênero

Passo 2: (Opcional) Gerar letras rimadas dinamicamente

Se a aplicação gerar letras a partir de tópicos enviados pelos usuários, você pode acionar /tts/lyrics (ou utilizar um LLM com saída estruturada em listas de linhas):

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()  # Retorna versos estruturados

Passo 3: Disparar a requisição de Freestyle

Envie a matriz de rimas, o andamento em BPM, o UUID da base musical e o modelo de voz desejado:

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,  # Exemplo: [["Linha um rimando na batida do servidor", "Chamadas de API sintetizando sem pudor"]]
        "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 o UUID da tarefa assíncrona

4. Configuração de afinação e vocais cantados

O canto melódico exige modulação de frequências contínuas e sustentação exata de fonemas.

Abordagem A: Controle paramétrico via /speak

Para modelos que suportam parâmetros avançados (verificáveis via GET /voices/{voicemodel_uuid}/detail analisando controls: true), o endpoint /speak aceita arrays numéricos para pitch (curva de semitons) e duration (tempo de sustentação fonética):

def generate_singing_notes(speech_text, voicemodel_uuid, pitch_curve, duration_curve):
    """
    pitch_curve: Lista numérica representando a curva de semitons para cada fonema.
    duration_curve: Lista de durações temporais de cada unidade 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"]

Abordagem B: Canto realista via conversão de voz (V2V)

Definir manualmente vetores matemáticos para cada fonema pode resultar em um canto robotizado. Em aplicações comerciais, o caminho mais consolidado é o Voice-to-Voice (V2V): Gera-se uma voz guia de referência (por exemplo, um vocal guia extraído de um plugin MIDI ou uma gravação humana limpa) e submete-se ao POST /tts/convert, configurando pitch_shift para transposição de tom:

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 assíncrono e consulta de status

Modelos neurais de geração vocal demandam alto poder de processamento e não retornam o arquivo de áudio imediatamente no handshake HTTP. As requisições retornam um identificador de trabalho (uuid). O backend precisa realizar consultas periódicas ao endpoint /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()
        
        # Verificação de erro no processamento
        if data.get("failed_at"):
            raise RuntimeError(f"Falha na síntese vocal: {data}")
            
        # Verificação de conclusão
        if data.get("finished_at"):
            audio_url = data.get("path")
            return audio_url  # URL final de armazenamento CDN
            
        time.sleep(delay_seconds)
        
    raise TimeoutError("O processamento excedeu o tempo limite.")

6. Script de orquestração ponta a ponta

O código abaixo apresenta uma implementação completa em Python para autenticação, envio de tarefa, espera por conclusão e download do áudio 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. Enviar solicitação de geração de rap
    print("Enviando requisição para síntese vocal...")
    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"Tarefa criada com UUID: {task_id}")
    
    # 2. Consultar status de conclusão
    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("Erro reportado no servidor durante a geração.")
        if status_data.get("finished_at"):
            audio_url = status_data.get("path")
            print(f"Síntese concluída com sucesso: {audio_url}")
            break
            
    if not audio_url:
        raise TimeoutError("O processamento demorou mais que 80 segundos.")
        
    # 3. Baixar e salvar o arquivo WAV
    audio_data = requests.get(audio_url).content
    with open(output_file, "wb") as f:
        f.write(audio_data)
    print(f"Áudio salvo em: {output_file}")
    return output_file

if __name__ == "__main__":
    versos = [
        ["Iniciando o processo com o beat sincronizado", "Sintetizando as rimas no pipeline automatizado"],
        ["O tempo segue firme com o BPM calibrado", "API da Uberduck produzindo o som desejado"]
    ]
    create_rap_track(lyrics=versos, bpm=95)

7. Melhores práticas e considerações de produção

Ao colocar esse pipeline em ambiente de produção, observe os seguintes pontos arquiteturais:

Referências