GPT-6 Sol e Claude Opus 5.5 disponíveisGPT-6 Sol pela metade do preço do 5.6 Sol

Seedance 2.0 e lip sync: prompts de diálogo e 4 clipes reais

A boca segue o prompt, e a nossa gravação voltou na faixa de áudio.

Kiki, OmniaKey COO11 min de leitura
Nesta página

O Seedance 2.0 mexe a boca conforme o prompt. Dois clipes de 5 segundos em 720P, iguais exceto pelo áudio ligado ou desligado, abriram e fecharam a boca. Nossa gravação de 1,8 segundo passou pelo reference_to_video e a frase voltou na faixa de saída. Áudio sozinho é recusado. A BytePlus cobra $0.15 por segundo em 720P, então 5 segundos custam $0.75.

Resposta curta

  • A boca vem do prompt. Dois clipes de 5 segundos em 720P com o mesmo prompt, um com áudio gerado e outro mudo, passaram por fechada → entreaberta → bem aberta.
  • Áudio sozinho não entra. A série 2.0 exige pelo menos uma imagem ou um vídeo de referência (API de criação de tarefa da BytePlus, conferida em 3 de novembro de 2026).
  • O áudio de referência aceita até 3 clipes, de 2 a 15 segundos cada, 15 segundos no total, em wav ou mp3, 15 MB por arquivo.
  • O áudio é usado. Nosso mp3 de 1,8 segundo voltou na faixa de saída, com a frase completa.
  • Pelo preço por segundo da BytePlus, 720P custa $0.15 por segundo, e 5 segundos dão $0.75.
  • Quatro clipes do mesmo dia: 720P com áudio, 720P mudo, imagem para vídeo em 720P quadrado e 480P com áudio de referência.

O Seedance 2.0 faz lip sync?

A documentação oficial não usa a expressão «lip sync». O que ela descreve é a geração conjunta de imagem e som, mais um conselho: colocar o diálogo entre aspas duplas.

A página Seed da ByteDance apresenta o Seedance 2.0 como «a unified multimodal audio-video joint generation architecture that supports text, image, audio, and video inputs» (conferida em 3 de novembro de 2026). O guia do BytePlus ModelArk repete a ideia e lista «Generate videos with audio» entre os recursos (página atualizada em 29 de setembro de 2026).

Procurando nessas páginas, «lip sync» e «talking» não aparecem nenhuma vez. «mouth» aparece uma vez, num prompt de exemplo, e «dialogue» duas, sempre sobre geração de áudio. O mais perto de uma instrução é esta frase: «It is recommended to put dialogue content in double quotes to optimize the audio generation effect» (API de criação de tarefa, atualizada em 28 de outubro de 2026).

Ou seja, o recurso fica no meio do caminho: o modelo entrega imagem e faixa de áudio, mas nenhuma página oficial promete que os lábios acompanham cada sílaba. Nos nossos quatro clipes a boca se mexeu com o áudio ligado e desligado, o que é esperado de um modelo de vídeo cujo prompt diz que alguém está falando.

Tem gente testando. Um comentário no Hacker News de 18 de fevereiro de 2026 enviou uma música junto com o vídeo e concluiu que «the model did reference the singing music I provided, but it reinterpreted it on its own» (comentário). Uma issue no GitHub de 3 de junho de 2026 coloca «Mouth movements match phoneme timing» como critério de aprovação, uma medição que a documentação não traz (issue).

Como escrever a fala no prompt

Primeiro o personagem, depois a fala entre aspas duplas e por fim o movimento da boca e do rosto. Nosso prompt descrevia o personagem e a boca, mas esqueceu as aspas: a fala foi escolhida pelo modelo.

A receita que usamos tem cinco passos.

  1. O personagem em uma frase: stop-motion de massinha, óculos redondos grandes, cachecol de tricô, sentado à mesa da cozinha.
  2. O que ele faz: diz uma fala curta olhando para a câmera.
  3. A fala, exatamente como está, entre aspas duplas. É a recomendação da BytePlus.
  4. A boca e o rosto: lábios abrem e fecham com as palavras, sobrancelhas acompanham a frase, a cabeça inclina na sílaba tônica.
  5. Câmera e luz fixas, para que só a atuação se mova.

Este é o prompt enviado, sem alteração, nos quatro clipes:

A stop-motion clay character with big round glasses and a knitted scarf sits at a kitchen table, looks straight into the camera, and speaks one short line to the viewer. The mouth opens and closes in time with the words, the eyebrows move with the sentence, and the head tilts slightly on the stressed word. Fixed camera, warm lamp light, a mug of tea in front of them, gentle 24 fps stop-motion feel.

Falta a fala. O prompt só dizia «uma fala curta», então as palavras vieram do modelo. Com o áudio ligado ele diz «You look like you could use a warm hug.», uma frase que não estava em lugar nenhum do pedido. Para controlar o diálogo, o passo 3 precisa entrar antes do envio.

Olhamos a boca num quadro a cada 0,5 segundo. O clipe com áudio começa com a boca fechada, fica entreaberta do quadro 2 ao 7, abre de vez no 8 e volta a fechar. O clipe mudo mostra fechada, entreaberta, bem aberta, entreaberta, bem aberta, e os dois últimos quadros entreaberta.

Dez closes de um personagem de massinha com óculos redondos e cachecol, um a cada meio segundo: boca fechada no primeiro e no último, aberta no meio e mais aberta no oitavo.
Com áudio, um quadro a cada meio segundo: boca fechada no 1, entreaberta do 2 ao 7, bem aberta no 8 e fechada de novo no 10. Seedance 2.0 via OmniaKey, texto para vídeo, 5 segundos, 720P, gerado em 3 de novembro de 2026.
Dez closes de um personagem de massinha laranja com cachecol verde-escuro, um a cada meio segundo, abrindo e fechando a boca, tirados de um vídeo sem faixa de áudio.
Com o áudio desligado e o mesmo prompt, a boca continua abrindo e fechando, mais aberta nos quadros 5, 6 e 8, e o arquivo não tem faixa de áudio. 5 segundos, 720P, gerado em 3 de novembro de 2026.

O mesmo texto também escolhe outro personagem: o clipe mudo voltou com corpo laranja, repartição castanho-acinzentada e cachecol verde-escuro. A frase do personagem funciona melhor como sugestão. Nos dois clipes a câmera não se mexeu, o que vem do «Fixed camera».

Dá para enviar o próprio áudio?

Dá, com uma imagem ou um vídeo de referência no mesmo pedido. Nosso mp3 de 1,8 segundo foi como áudio de referência, e as palavras voltaram na faixa de saída.

Usamos reference_to_video com três peças: o still de massinha como imagem de referência, a gravação como áudio de referência e o prompt acima. Os parâmetros foram 480P, 5 segundos e áudio ligado. A OmniaKey respondeu 202, a tarefa task_3Ay0Ktf2mbYXh9GNZpZ5j9kGyOIzz8Pv terminou bem e, 120,2 segundos depois, chegou um MP4 de 864×496 com faixa aac de 5.06 segundos.

A transcrição dessa faixa é uma frase só: «Why tow it? I told you the keys were in the drawer.». A segunda metade é exatamente o que gravamos, palavra por palavra. As três primeiras palavras não estavam no nosso arquivo; a transcrição não distingue se é nossa respiração ou algo que o modelo acrescentou, então deixamos o que se ouve.

Dez quadros de um personagem de massinha marrom com chapéu e cachecol laranja atrás de uma mesa de madeira, a boca fecha e abre e o vapor da caneca se move.
Com a nossa gravação como referência: a boca se mexe, o vapor da caneca sobe e a faixa de saída leva a frase enviada. 5 segundos, 480P, gerado em 3 de novembro de 2026.

Dez quadros, um a cada 0,5 segundo, mostram só que a boca se mexe. Para ver o encaixe por fonema seriam necessários quadros mais densos e uma medição própria, e isso não foi feito, então não dá para dizer que os lábios acompanham cada som.

Os limites vêm da API de criação de tarefa da BytePlus (conferida em 3 de novembro de 2026). O áudio aceita 3 clipes, de 2 a 15 segundos cada, 15 segundos no total, em wav ou mp3, 15 MB por arquivo. O clipe pode chegar por URL pública, string Base64 ou id de ativo. Só áudio não passa: «Audio-only input is not supported; include at least one reference image or video.»

Nada de rostos reais. A série 2.0 recusa imagens e vídeos de referência com pessoas reais, então para uma cena falada use um personagem de massinha, desenho ou CG.

Imagem para vídeo troca de plano sozinho

Nosso clipe de imagem para vídeo saiu de um plano inteiro em pé para um plano médio sentado na cozinha no quadro 4, e o prompt não pedia corte nem movimento de câmera.

O primeiro quadro é um still gerado para este teste: o personagem em pé diante de uma parede branca quente, braços caídos, corpo inteiro, 1254×1254 pixels. O prompt é o de cima, que o coloca sentado à mesa da cozinha. Os quadros 1 a 3 ficam em pé, o 4 pula para o plano médio sentado e continua ali. A boca fica fechada até o quadro 7, entreaberta no 8 e bem aberta nos quadros 9 e 10. No áudio soa «Well, what do you think?» e ruído de tecido.

Dez quadros de um vídeo quadrado: no começo o personagem de massinha está em pé e depois aparece sentado à mesa da cozinha com a boca aberta.
Imagem para vídeo: o plano em pé dura um instante e então muda para o assento de cozinha que o prompt pedia, uma composição que não estava na imagem. 5 segundos, 720P, gerado em 3 de novembro de 2026.

O que importa aqui é a composição, não a boca. Nesse modelo o prompt decide onde o personagem está e como a câmera se move, e o primeiro quadro decide a aparência. O plano que importa vai escrito no prompt.

O arquivo chegou em 960×960, não em 1280×720. A causa: usamos uma imagem quadrada como primeiro quadro e não enviamos proporção, e a API assume a da imagem. Para escolher o formato, escreva ratio em vez de deduzir pelo nome da resolução.

O pedido em Python

Criar a tarefa, consultar o id e baixar o MP4: três pedidos e só a biblioteca padrão. O mesmo auxiliar atende as três etapas.

python
import base64
import json
import os
import time
import urllib.error
import urllib.request
import uuid

API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "dreamina-seedance-2-0-260128"

PROMPT = (
    "A stop-motion clay character with big round glasses and a knitted scarf sits at a kitchen table, "
    "looks straight into the camera, and speaks one short line to the viewer. The mouth opens and closes "
    "in time with the words, the eyebrows move with the sentence, and the head tilts slightly on the "
    "stressed word. Fixed camera, warm lamp light, a mug of tea in front of them, gentle 24 fps "
    "stop-motion feel."
)

MIME = {".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg",
        ".webp": "image/webp", ".mp3": "audio/mpeg", ".wav": "audio/wav"}


def call(method, url, body=None, idempotency_key=None):
    headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
    data = None
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode()
    if idempotency_key:
        headers["Idempotency-Key"] = idempotency_key
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    with urllib.request.urlopen(req, timeout=120) as resp:
        return json.load(resp)


def data_url(path, limit_mb):
    raw = open(path, "rb").read()
    if len(raw) > limit_mb * 1024 * 1024:  # 30 MB para imagem, 15 MB para áudio
        raise ValueError(f"{path} is over {limit_mb} MB, the limit for this input type")
    mime = MIME[os.path.splitext(path)[1].lower()]
    return f"data:{mime};base64," + base64.b64encode(raw).decode()


def wait(task_id, timeout=900, step=5):
    deadline = time.time() + timeout
    while time.time() < deadline:
        state = call("GET", f"{API}/{task_id}")
        if state["status"] not in ("queued", "processing"):
            return state
        time.sleep(step)
    raise TimeoutError(f"{task_id} is still running: poll it again, do not resubmit")


def run(body, out_path):
    task_id = call("POST", API, body, str(uuid.uuid4()))["id"]
    print("task", task_id, flush=True)
    state = wait(task_id)
    if state["status"] != "succeeded":
        raise RuntimeError(state.get("error") or state["status"])
    signed = state["assets"][0]["url"]  # expira, então baixe na hora
    req = urllib.request.Request(signed, headers={"User-Agent": "omniakey-example/1"})
    with urllib.request.urlopen(req, timeout=300) as resp, open(out_path, "wb") as f:
        f.write(resp.read())
    return task_id


def reference_to_video(prompt, image_path, audio_path, out_path):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "reference_to_video",
        "input": {
            "prompt": prompt,
            "media": [
                {"type": "reference_image", "url": data_url(image_path, 30)},
                {"type": "reference_audio", "url": data_url(audio_path, 15)},
            ],
        },
        "parameters": {"duration": 5, "resolution": "480P", "ratio": "16:9",
                       "generate_audio": True, "watermark": False},
    }
    return run(body, out_path)


if __name__ == "__main__":
    print("done", reference_to_video(PROMPT, "character.png", "line.mp3", "line-clip.mp4"))

Três detalhes valem ficar. O Idempotency-Key é um UUID novo por corpo, então um reenvio devolve a tarefa original em vez de cobrar duas vezes. A espera para depois de 15 minutos com uma exceção, porque estourar o tempo significa que o clipe ainda está renderizando e reenviar compra outro. O download acontece no primeiro succeeded, porque assets[0].url é um link assinado que expira.

As outras duas operações trocam só o corpo e mantêm os auxiliares:

python
def text_to_video(prompt, out_path):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "text_to_video",
        "input": {"prompt": prompt},
        "parameters": {"duration": 5, "resolution": "720P", "ratio": "16:9",
                       "generate_audio": True, "watermark": False},
    }
    return run(body, out_path)


def image_to_video(prompt, image_path, out_path):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "image_to_video",
        "input": {"prompt": prompt,
                  "media": [{"type": "first_frame", "url": data_url(image_path, 30)}]},
        "parameters": {"duration": 5, "resolution": "720P", "ratio": "adaptive",
                       "generate_audio": True, "watermark": False},
    }
    return run(body, out_path)

A lista de campos é curta: model, type, operation, input.prompt, input.media[] com type em first_frame, reference_image, reference_video ou reference_audio, e parameters.duration, resolution, ratio, generate_audio, watermark. A mesma forma está na documentação da API de vídeo da OmniaKey, e o ciclo de criar, consultar e baixar aparece na visão geral da API de mídia. Este modelo dá para testar na página do modelo Seedance 2.0.

Quanto custa

A BytePlus cobra por segundo. O preço de tabela para 5 segundos em 16:9 sem vídeo de entrada é este (página de preços do ModelArk, conferida em 3 de novembro de 2026):

SaídaPor segundoClipe de 5 s
480p$0.07$0.35
720p$0.15$0.76
1080p$0.37$1.87
4K$0.78$3.89

Fazendo a conta pela coluna por segundo dá o mesmo, com um centavo de arredondamento na página: 5 segundos × $0.15 = $0.75, contra $0.76 na linha de 720p. Nossos dois clipes de texto para vídeo foram em 720P por 5 segundos, então cada um fica nesses $0.75.

Um pedido com vídeo de entrada é cobrado de outro jeito, e mais caro, então uma tarefa com vídeo de referência não entra nessa tabela (página de preços do ModelArk, conferida em 3 de novembro de 2026). A OmniaKey cobra por segundo gerado e devolve a cobrança quando a tarefa termina em failed ou canceled (visão geral da API de mídia, conferida em 3 de novembro de 2026); o preço atual está na página do modelo.

O que dá errado

  • Áudio sozinho é recusado. Inclua pelo menos uma imagem ou um vídeo de referência junto da faixa.
  • Rosto real não passa. Imagem ou vídeo de referência com pessoa real é bloqueado, então use um personagem de massinha, desenho ou CG.
  • generate_audio vem ligado. Para um arquivo mudo é preciso desligar; para uma fala, deixe no padrão e o prompt diz que alguém fala.
  • O tamanho entregue segue ratio. 720P deu 1280×720 a partir de texto, 960×960 a partir de um still quadrado sem proporção e 864×496 em 480P com 16:9.
  • A velocidade varia. Quatro tarefas de 5 segundos levaram 259,0, 202,0, 155,3 e 120,2 segundos, então conte de dois a cinco minutos e consulte o estado.
  • A duração vai de 4 a 15 segundos na saída, e os clipes de referência de 2 a 15 segundos cada, 15 no total. Os quatro arquivos voltaram a 24 fps.

Perguntas frequentes

Se eu enviar um WAV, a boca acompanha minha gravação?

Sim, junto com uma imagem de referência, e o modelo usa o áudio: nossa gravação voltou na faixa de saída. Se os lábios acertam cada som do arquivo, nossos quadros não mostram; um quadro a cada meio segundo mostra a boca se mexendo, não uma correspondência medida.

Por que meu pedido só com áudio foi recusado?

A série 2.0 não aceita áudio como única entrada. Junte uma imagem ou um vídeo de referência no mesmo pedido e a faixa vai junto.

Áudio ligado ou desligado para uma fala?

Deixe ligado, que é o padrão. Com false o arquivo não tem faixa de áudio, e o personagem abre a boca mesmo assim se o prompt disser que ele fala, como no nosso clipe mudo.

Qual o tamanho máximo do áudio de referência?

Cada clipe vai de 2 a 15 segundos, até 3 clipes, 15 segundos no total, em wav ou mp3 e 15 MB por arquivo (API de criação de tarefa da BytePlus, conferida em 3 de novembro de 2026). O nosso tinha 1,8 segundo, menos que esse mínimo, e mesmo assim passou como URL de dados Base64.

Fontes conferidas

Histórico de alterações

  • 3 de novembro de 2026: primeira versão, com quatro clipes gerados no mesmo dia.

Modelos deste artigo

Seedance 2.0lip syncvídeo com IAáudio de referênciaAPI de vídeoPython

Artigos relacionados

Artigos recentes

Guias populares