HiAPI
Blogue

Tutorial

Escrevendo prompts de vídeo a partir de imagem com múltiplos ângulos usando minimax-h3-max via API hiapi

Não há parâmetros de ângulo de câmera — este padrão de prompt transforma uma foto em um clipe com múltiplos planos.

Sep 12, 2026
Escrevendo prompts de vídeo a partir de imagem com múltiplos ângulos usando minimax-h3-max via API hiapi

minimax-h3-max transforma uma foto em um vídeo de 5–15 segundos, mas seu endpoint não possui parâmetros de "ângulo de câmera", "múltiplas perspectivas" ou "número de planos" — os campos de entrada suportados listados na referência de parâmetros são prompt, first_frame_image, last_frame_image, duration, resolution e aspect_ratio. Escreva as instruções de câmera no prompt, que aceita até 7.000 caracteres.

Portanto, um clipe de "múltiplos ângulos" — passando de um plano de estabelecimento amplo para um close-up e depois para um plano de acompanhamento — não é um parâmetro que você define, mas um prompt que você escreve. Este tutorial cobre a estrutura da requisição, o padrão de prompt para exigir múltiplos ângulos de câmera dentro de um único clipe gerado e o fluxo de nível de produção ao seu redor.

Gerar com este prompt → Selecione 10 segundos e 768P. Para vídeo a partir de imagem, adicione sua imagem de quadro e omita aspect_ratio.

Pré-requisitos

Obtenha uma chave de API no seu console hiapi. Cada chamada abaixo autentica no endpoint assíncrono de tarefas compartilhado POST https://api.hiapi.ai/v1/tasks usando Authorization: Bearer YOUR_API_KEY.

Exemplo mínimo: uma foto, três ângulos de câmera

O first_frame_image ancora o sujeito e a cena, dando ao modelo conteúdo concreto de onde se afastar e para onde retornar. O prompt descreve cada plano como um corte numerado explícito. Este prompt da motocicleta é um exemplo de código, sem uma amostra renderizada anexada.

Uma motocicleta vintage vermelha estacionada em uma rua urbana molhada ao crepúsculo, letreiros de neon refletindo no asfalto. Plano 1 - ângulo amplo baixo: a câmera mantém um plano amplo estático da motocicleta inteira, chuva caindo levemente. Corte para o Plano 2 - close-up: a câmera avança apertado no farol cromado e na roda dianteira, acompanhando lentamente para a direita. Corte para o Plano 3 - vista aérea de cima: a câmera olha diretamente para baixo, para a motocicleta, de cima, girando lentamente. Sem texto ou legendas.

Gerar com este prompt → Adicione sua própria imagem de motocicleta publicamente acessível, selecione 10 segundos e 768P, e omita aspect_ratio.

import os
import requests
import time

API_KEY = os.environ["HIAPI_API_KEY"]
BASE = "https://api.hiapi.ai/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

payload = {
    "model": "minimax-h3-max",
    "input": {
        "prompt": (
            "A red vintage motorcycle parked on a wet city street at dusk, neon signs reflecting on the pavement. "
            "Shot 1 - low wide angle: the camera holds a static wide shot of the full motorcycle, rain lightly falling. "
            "Cut to Shot 2 - close-up: the camera pushes in tight on the chrome headlight and front wheel, tracking slowly right. "
            "Cut to Shot 3 - overhead top-down: the camera looks straight down at the motorcycle from above, slowly rotating. "
            "No text or subtitles."
        ),
        "first_frame_image": "https://your-cdn.example.com/motorcycle-source.jpg",
        "duration": 10,
        "resolution": "768P",
    },
}

# Frame images and aspect_ratio are mutually exclusive.
def response_data(response):
    response.raise_for_status()
    body = response.json()
    if not isinstance(body, dict) or body.get("code") != 200:
        raise ValueError("Expected a JSON object with code=200")
    data = body.get("data")
    if not isinstance(data, dict):
        raise ValueError("Expected data to be an object")
    return data

# Submit once. An uncertain POST response is not a reason to submit again.
try:
    resp = requests.post(
        f"{BASE}/tasks", headers=HEADERS, json=payload, timeout=(10, 60)
    )
    created = response_data(resp)
    task_id = created.get("taskId")
    if not isinstance(task_id, str) or not task_id.strip():
        raise ValueError("Missing data.taskId")
except (requests.RequestException, ValueError) as exc:
    raise RuntimeError(
        "Could not confirm task creation. Check task records before resubmitting."
    ) from exc

print("taskId:", task_id, flush=True)
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
    try:
        resp = requests.get(
            f"{BASE}/tasks/{task_id}", headers=HEADERS, timeout=(10, 60)
        )
        task = response_data(resp)
    except (requests.RequestException, ValueError) as exc:
        raise RuntimeError(
            f"Query failed; retain taskId={task_id} and resume GET for this ID."
        ) from exc

    state = task.get("status")
    if state == "fail":
        raise RuntimeError(f"Task {task_id} failed: {task.get('error')}")
    if state == "success":
        outputs = task.get("output")
        if not isinstance(outputs, list):
            raise RuntimeError(f"Task {task_id}: missing output array")
        video = next(
            (item for item in outputs
             if isinstance(item, dict) and item.get("type") == "video"
             and isinstance(item.get("url"), str) and item["url"]),
            None,
        )
        if video is None:
            raise RuntimeError(f"Task {task_id}: no video URL in output")
        print(video["url"])
        print("expireAt (Unix seconds):", video.get("expireAt"))
        break
    if state not in {"queued", "handling", "archiving"}:
        raise RuntimeError(f"Task {task_id}: unexpected status {state!r}")
    time.sleep(min(3, max(0, deadline - time.monotonic())))
else:
    raise TimeoutError(f"Polling timed out; continue GET with taskId={task_id}")

Substitua first_frame_image por uma URL HTTPS de imagem real e publicamente acessível, ou remova-a completamente para gerar a mesma sequência de múltiplos ângulos apenas a partir de texto — minimax-h3-max processa tanto vídeo a partir de texto quanto vídeo a partir de imagem pelo mesmo campo prompt.

Escrevendo o prompt: o padrão de planos numerados

Três escolhas tornam sua sequência de planos desejada explícita:

  1. Uma frase de estabelecimento da cena, depois os planos numerados. Descreva o sujeito e a cena uma vez, depois liste cada ângulo de câmera como um movimento rotulado próprio: Plano 1 - [enquadramento]: [ação]. Corte para o Plano 2 - [enquadramento]: [ação]. "Corte para o Plano N" exige explicitamente uma mudança de ângulo de câmera.
  2. Use vocabulário padrão de cinematografia. plano amplo de ângulo baixo, plano aéreo de cima, close-up, dolly-in lento, plano de acompanhamento lateral, câmera na mão — essas palavras especificam o enquadramento e o movimento que você deseja. Formulações vagas como "outro ângulo legal" produzem resultados inconsistentes.
  3. Planeje o número de planos de acordo com a duração. duration é um inteiro de 5 a 15 segundos. Dois ou três planos são realistas; espremer cinco ângulos distintos em um clipe de 5 segundos dá a cada plano menos de um segundo, e geralmente parece uma falha em vez de um corte.

first_frame_image e last_frame_image são ambos opcionais e independentes entre si — você pode definir um, ambos ou nenhum. Ao fornecer qualquer um deles, pule aspect_ratio: esses campos são mutuamente exclusivos, e a imagem de quadro determina a proporção da saída. Observe também que a consistência 3D ou geométrica estrita entre ângulos não é garantida — este é um modelo de vídeo generativo, não um pipeline de fotogrametria, então mesmo com a ancoragem do primeiro quadro, espere leve deriva nos detalhes do sujeito entre os cortes.

Deixando pronto para produção

  • Prefira callbacks a polling quando passar do tamanho de script. Inclua "callback": {"url": "https://your-domain.com/hiapi/callback", "when": "final"} no corpo da requisição, e a hiapi fará um POST de notificação quando a tarefa atingir o estado terminal, em vez de você fazer polling de GET /v1/tasks/{taskId} em loop.
  • Deduplique por taskId. Respostas de polling e callbacks têm como chave o mesmo taskId — trate notificações de estado terminal repetidas para o mesmo ID como idempotentes, não como múltiplas tarefas independentes.
  • Baixe a saída imediatamente. Uma tarefa bem-sucedida retorna data.output[].url para armazenamento temporário. Selecione o item de saída cujo type é video e verifique seu timestamp Unix expireAt (em segundos). Reenvie-o para seu próprio armazenamento no mesmo handler que processa o estado terminal.
  • Trate as duas formas de falha. Corpos de requisição inválidos (campos não suportados, duration fora do intervalo, URL de imagem malformada) falham rapidamente no envio com 400 INVALID_REQUEST. Problemas de autenticação retornam 401 com error.code: "permission_denied". Tarefas que falham durante a geração relatam "status": "fail" na resposta de polling/callback — verifique status antes de confiar em output.

Leitura relacionada

Perguntas frequentes

O minimax-h3-max tem um parâmetro dedicado de múltiplos ângulos ou múltiplas câmeras? Não. Os campos de entrada documentados são prompt, first_frame_image, last_frame_image, duration, resolution e aspect_ratio. Descreva múltiplos planos dentro de prompt, em vez de adicionar um campo de ângulo de câmera.

Posso definir aspect_ratio junto com first_frame_image ou last_frame_image? Não. aspect_ratio é mutuamente exclusivo com qualquer campo de imagem de quadro. A imagem fornecida determina a proporção da saída. Sempre que passar qualquer imagem de quadro, omita aspect_ratio.

Quão longo pode ser um clipe de múltiplos ângulos? duration aceita inteiros de 5 a 15 segundos. Dois ou três ângulos de câmera distintos cabem confortavelmente nessa janela; mais do que isso tende a comprimir cada plano em uma fração de segundo.

O sujeito permanecerá perfeitamente consistente entre os ângulos? Não há garantia. O minimax-h3-max é um modelo de vídeo generativo, então mesmo que first_frame_image ancore o quadro inicial, detalhes (texturas exatas, proporções sutis) podem variar entre os cortes. Trate-o como forte consistência criativa, não como reconstrução multi-perspectiva pixel a pixel.

Posso gerar um clipe de múltiplos ângulos apenas a partir de texto, sem imagem de origem? Sim — omita first_frame_image e last_frame_image e descreva a cena e os planos no prompt. A geração apenas por texto usa a tela horizontal padrão. Para composição vertical, forneça uma imagem de quadro vertical sem definir aspect_ratio, ou corte/preencha o vídeo salvo no editor.

Como é uma falha de autenticação? HTTP 401, com um corpo de resposta semelhante a {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}. Verifique cuidadosamente o cabeçalho Authorization: Bearer e se a chave foi revogada no console.

Copie a sequência de planos da motocicleta e gere com este prompt → selecionando 10 segundos e 768P; adicione sua imagem de quadro para orientar o enquadramento inicial.

Artigos relacionados

Ver todos os artigos →

Comece a criar com artefactos de IA persistentes

Obtenha a sua chave de API e chame modelos de imagem, vídeo e áudio através de uma única API baseada em tasks.

Ler a documentação da API