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

API Wan 3.0: texto para vídeo e imagem para vídeo em Python

Um script, dois clipes: o código, os tempos reais e o preço por segundo da Alibaba.

Kiki, OmniaKey COO8 min de leitura
Nesta página

Wan 3.0 roda no Alibaba Cloud Model Studio como wan3.0-video e como o mais rápido wan3.0-video-prime. Cada chamada é assíncrona: criar a tarefa, consultar o ID, baixar o MP4. Nosso script em Python gerou um clipe de 5 segundos em 720P a partir de texto em 2 min 42 s e outro a partir de uma imagem fixa em 3 min 20 s, os dois com som.

  1. Coloque a chave em OMNIAKEY_API_KEY.
  2. Faça POST em https://api.omniakey.com/v1/media/tasks com o modelo, a operação, o prompt, os parâmetros e uma nova Idempotency-Key.
  3. Consulte GET /v1/media/tasks/{id} até o status dizer succeeded e baixe assets[0].url na hora.

Existe uma API oficial do Wan 3.0, e qual modelo eu uso?

Sim. O Alibaba Cloud Model Studio é a API oficial, com wan3.0-video e wan3.0-video-prime (referência atualizada em 15 de outubro de 2026). A chamada de criação precisa do cabeçalho X-DashScope-Async: enable, e o caminho Python da Alibaba é o SDK DashScope 2.0.1 ou mais novo.

Alibaba Model StudioOmniaKey
Os dois IDsSimSim
Cabeçalho asyncPrecisaNão
Link do vídeo vale24 horasCerca de 1 hora, renovável
CobrançaPor segundoPor segundo
PythonSDK DashScopeBiblioteca padrão

Os dois IDs aceitam o mesmo corpo, e o modelo escolhe o modo pelos arquivos de mídia que você envia. O script abaixo usa wan3.0-video, e a linha MODEL troca. Não rodamos o Wan 3.0 Prime, que a doc da OmniaKey descreve como as mesmas capacidades em cerca de metade do tempo (verificado em 31 de outubro de 2026).

O que você precisa antes da primeira chamada?

Três coisas, e a primeira é a chave:

  1. Uma chave de API da OmniaKey, exportada no shell:

    bash
    export OMNIAKEY_API_KEY="your-key"
    
  2. Python 3. O script importa só a biblioteca padrão, então o python3 roda direto.

  3. Para imagem para vídeo, um primeiro quadro: um JPEG com cerca de 1024 px de largura, ou uma URL HTTPS pública. O script recusa arquivo acima de 700.000 bytes, porque o Base64 acrescenta um terço e o corpo para em 1 MiB (doc, verificada em 31 de outubro de 2026).

Quais parâmetros importam?

Sete campos fazem a maior parte do trabalho, e cada um é um valor dentro de parameters.

ParâmetroO que fazPadrão
DuraçãoTamanho do clipe, segundos5
ResoluçãoFaixa de tamanho da imagem1080P
ProporçãoFormato do quadroadaptive
ÁudioFaixa de somon
SeedDica de repetibilidade-1
Ampliar promptReescreve seu prompton
Marca d'águaPõe marca no cantooff

O script define duração, resolução e proporção. Ele pede 720P enquanto o padrão da Alibaba é 1080P, que custa o dobro por segundo na tabela de preços.

Como é o código em Python?

O script abaixo rodou sem mudança em 31 de outubro de 2026: só biblioteca padrão, os dois modos, uma linha MODEL para trocar.

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 = "wan3.0-video"

def request(method, url, body=None, extra_headers=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()
    headers.update(extra_headers or {})
    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 poll(url, attempts=5):
    for attempt in range(attempts):
        try:
            return request("GET", url)
        except urllib.error.HTTPError as err:
            if err.code < 500 or attempt == attempts - 1:
                raise
        except urllib.error.URLError:
            if attempt == attempts - 1:
                raise
        time.sleep(5 * (attempt + 1))

def run_task(body, out_path):
    task = request("POST", API, body, {"Idempotency-Key": str(uuid.uuid4())})["id"]
    print("task", task, flush=True)
    for _ in range(180):  # 5-second polls, up to 15 minutes
        time.sleep(5)
        state = poll(f"{API}/{task}")
        if state["status"] not in ("queued", "processing"):
            break
    else:
        raise TimeoutError(f"{task} is still {state['status']}: poll it again later, do not resubmit")
    if state["status"] != "succeeded":
        raise RuntimeError(state.get("error") or state["status"])
    asset_url = state["assets"][0]["url"]  # signed link: short-lived, so download now
    req = urllib.request.Request(asset_url, 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

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

def image_to_video(prompt, image_path, out_path, duration=5, resolution="720P"):
    with open(image_path, "rb") as f:
        raw = f.read()
    if len(raw) > 700_000:  # base64 adds a third, and the whole body must stay under 1 MiB
        raise ValueError("first frame too large: save it as a JPEG about 1024 px wide")
    frame = "data:image/jpeg;base64," + base64.b64encode(raw).decode()
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "image_to_video",
        "input": {"prompt": prompt, "media": [{"type": "first_frame", "url": frame}]},
        "parameters": {"duration": duration, "resolution": resolution, "ratio": "adaptive"},
    }
    return run_task(body, out_path)

if __name__ == "__main__":
    print("done", text_to_video(
        "A blacksmith hammers a glowing horseshoe on an anvil in a dark forge. Sparks fly at each "
        "strike and light his leather apron. The camera slowly pushes in. Sound of the hammer ringing "
        "on steel and the fire crackling. No dialogue, no music, no text.",
        "forge.mp4",
    ))
    print("done", image_to_video(
        "Image 1 is the first frame. The paper boat drifts slowly to the right across the puddle. "
        "Light rain makes small ripples and the cafe lights shimmer in the water. The camera stays "
        "low and still. Sound of light rain. No dialogue, no music, no text.",
        "boat.jpg",
        "boat-drifts.mp4",
    ))

O que cada parte faz:

  • run_task gera uma nova Idempotency-Key para cada tarefa. Reenviar a mesma chave com o mesmo corpo devolve a tarefa original e nunca cobra duas vezes (doc, verificada em 31 de outubro de 2026).
  • Ele consulta a cada 5 segundos por até 15 minutos e depois levanta TimeoutError.
  • Um timeout quer dizer: consultar o mesmo ID mais tarde; reenviar gera outra chave, cria uma segunda tarefa e cobra por ela.
  • Ele baixa a primeira URL de asset na hora, porque o link assinado dura pouco.
  • image_to_video recusa um quadro acima de 700.000 bytes: o Base64 acrescenta um terço, e o corpo para em 1 MiB.
  • A chamada de imagem define a proporção como adaptive, então o clipe segue o formato da imagem fixa.

O que ele imprimiu:

text
task task_<id>
done task_<id>
task task_<id>
done task_<id>

O que as duas chamadas produziram?

Os dois arquivos voltaram como MP4 de 5,04 segundos, 150 quadros a 30 fps, H.264, com faixa AAC estéreo a 44,1 kHz.

Texto para vídeo: a forja

Quatro quadros do clipe da forja do Wan 3.0
Texto para vídeo, 5 s em 720P: quadros em 0,3, 2,2, 3,5 e 4,7 segundos.

O clipe segue o prompt: um ferreiro de camisa escura e avental de couro martela uma ferradura laranja incandescente, faíscas saltam em 2,2 segundos, e a câmera avança um pouco. O defeito é um selo de fabricante estampado em letras embaralhadas na bigorna, embora o prompt pedisse nenhum texto. Do início ao arquivo levou 2 min 42 s; o MP4 tem 1280×720 e 6,6 MB.

Imagem para vídeo: o barco de papel

A imagem fixa do primeiro quadro e três quadros do clipe do barco de papel do Wan 3.0
Imagem para vídeo: a imagem enviada (canto superior esquerdo), depois o clipe em 1,6, 3,5 e 4,7 segundos.

O primeiro quadro foi uma imagem fixa feita com o Nano Banana 2.1, um barco de papel vermelho numa poça de chuva, redimensionada para um JPEG de 1024×571 com 158 KB e enviada embutida como data URL. O clipe mantém aquela luz de crepúsculo e o calçamento molhado, faz o barco ir da esquerda para a direita como pedido, cria ondulações em 1,6 segundo e mantém a câmera baixa e parada. Voltou em 1284×716 porque o adaptive seguiu o formato da imagem fixa, em 3 min 20 s com 7,4 MB.

O som vem ligado, e o "no music" funciona?

O som vem ligado por padrão. O Gemini 3.8 Flash descreveu a faixa da forja como tilintar metálico sem fala e sem música, e a do barco de papel como uma melodia de piano melancólica e calma, embora esse prompt terminasse com "no music". O guia de prompt da Alibaba (atualizado em 16 de outubro de 2026) sugere escrever "No BGM" ou "No background music", e nosso prompt não usou nenhum dos dois.

Com "audio": false o arquivo traz só faixa de vídeo: nossa tarefa de 2 segundos em 480P com a lanterna não tinha faixa de som, e a Alibaba cobra o mesmo nos dois casos.

ClipeTempoTamanhoSom
Forja (texto)2 min 42 s1280×720Tilintar, sem música
Barco (imagem)3 min 20 s1284×716Piano apesar de "no music"
Lanterna, áudio off4 min 36 s854×480Sem faixa de som

O tempo na fila varia: a tarefa de 2 segundos com áudio desligado levou 4 min 36 s, mais que qualquer um dos clipes de 5 segundos em 720P. Para escrever prompts, o guia de prompt do Wan 3.0 traz a estrutura e exemplos.

Consulte GET /v1/media/tasks/{id} até o status dizer succeeded, failed ou canceled; enquanto a tarefa roda ele diz queued ou processing. Uma tarefa concluída devolve uma URL de asset assinada que vale cerca de uma hora (doc da OmniaKey, verificada em 31 de outubro de 2026). Baixe na hora e consulte a tarefa de novo para pegar um link novo quando o antigo expirar, porque o registro dura 24 horas.

O arquivo é um MP4 com vídeo H.264 a 30 fps, e a URL de vídeo da própria Alibaba dura 24 horas. Cancelar uma tarefa do Wan 3.0 não para a renderização, e uma tarefa que termina com sucesso depois do cancelamento ainda é cobrada, então confira duração e resolução antes de enviar.

Quais erros você vai ver?

A maioria volta antes de existir uma tarefa, e cada um tem uma correção na requisição ou na chave.

  • 400 model_price_error — duração fora de 2 a 30 segundos. Nosso teste com "duration": 1 falhou em 0,9 s com "media duration must be between 2 and 30 seconds"; nenhuma tarefa foi criada e nada foi cobrado.
  • 400 missing_idempotency_key — falta o cabeçalho Idempotency-Key. Adicione um, de até 255 caracteres.
  • 409 idempotency_key_reused — mesma chave, corpo diferente. Gere uma chave nova para cada prompt.
  • 403 model_not_allowed — a chave não pode chamar esse modelo. Confira o valor de model e depois as configurações da chave.
  • 403 com mensagem de saldo ou limite de gasto — saldo baixo ou limite por chave. Recarregue ou aumente o limite.
  • 404 task_not_found — ID errado, ou tarefa com mais de 24 horas. Consulte o ID que a chamada de criação devolveu.
  • 409 task_state_conflict — a tarefa já terminou, como quando um cancelamento chega depois do sucesso. Leia o status primeiro.
  • 429 — requisições demais. A OmniaKey não publica limites fixos, então espere com atraso exponencial e jitter.
  • 503 no_available_channel — nenhum canal para essa operação, como vídeo para vídeo. Use texto para vídeo ou imagem para vídeo.
  • TimeoutError — ainda rodando depois de 15 minutos. Consulte o mesmo ID mais tarde; reenviar cria uma segunda tarefa e cobra por ela.

Quanto custa um clipe do Wan 3.0?

A Alibaba cobra por segundo de vídeo, e uma requisição que falha não é cobrada (página de preços atualizada em 29 de outubro de 2026). A tabela traz os preços de tabela da Alibaba por segundo em Singapura, verificados em 31 de outubro de 2026, na página de preços do Model Studio da Alibaba.

Modelo480P720P1080P
Wan 3.0$0.05$0.1$0.2
Wan 3.0 Prime$0.068$0.14$0.28

Um clipe de 5 segundos em 720P custa na Alibaba $0.50 no Wan 3.0 (5 × $0.1) e $0.70 no Prime (5 × $0.14). Os três preços do Wan 3.0 trazem a marca "Limited-time 30% off", e a página não diz se os números já a incluem. Som ligado ou desligado custa o mesmo.

A cota grátis da Alibaba é de 30 segundos de vídeo, entrada mais saída, no wan3.0-video em Singapura; o Prime não tem. Na Alibaba na China (Pequim), o modelo padrão tem preços em dólar mais baixos: $0.041256, $0.082513 e $0.165025 por segundo em 480P, 720P e 1080P.

A OmniaKey também cobra por segundo, com os preços atuais nas páginas dos modelos Wan 3.0 e Wan 3.0 Prime.

Perguntas frequentes

Quanto tempo leva uma chamada?

A Alibaba diz que uma tarefa costuma levar de 1 a 5 minutos e sugere consultar a cada 15 segundos (referência, verificada em 31 de outubro de 2026). Nossas três tarefas levaram 2 min 42 s, 3 min 20 s e 4 min 36 s.

Como desligo o som?

Coloque "audio": false dentro de parameters, e o MP4 chega só com faixa de vídeo, como na nossa tarefa da lanterna. O preço continua o mesmo.

wan3.0-video ou wan3.0-video-prime?

Escolha o wan3.0-video pelo preço mais baixo da Alibaba e pela cota grátis de 30 segundos em Singapura, e o Prime quando o tempo pesa mais. A OmniaKey descreve o Prime como as mesmas capacidades em cerca de metade do tempo.

Cerca de uma hora na OmniaKey, e consultar a tarefa de novo devolve um link novo enquanto o registro durar 24 horas. A URL de vídeo da própria Alibaba dura 24 horas.

Fontes verificadas

Modelos deste artigo

Wan 3.0video APIPythontext-to-videoimage-to-video

Artigos relacionados

Artigos recentes