HiAPI
Блог

Руководство

Создание многокадровых видеоподсказок для мини-Max H3 через API hiapi

Нет параметра угла камеры — этот подход к подсказке превращает одну фотографию в многокадровый фрагмент.

Sep 12, 2026
Создание многокадровых видеоподсказок для мини-Max H3 через API hiapi

minimax-h3-max превращает одну фотографию в видео длительностью 5–15 секунд, но в его конечной точке вообще нет параметров «угол камеры», «множественные ракурсы» или «количество кадров» — справочник параметров перечисляет поддерживаемые поля ввода: prompt, first_frame_image, last_frame_image, duration, resolution и aspect_ratio. Инструкции по камере нужно писать в prompt: это поле вмещает до 7 000 символов.

Итак, «многокадровый» фрагмент — переход от широкого установочного кадра к крупному плану, затем к следящему кадру — это не параметр, который вы задаёте, а подсказка, которую вы пишете. В этом руководстве описаны структура запроса, шаблоны подсказок для запроса нескольких углов камеры в одном сгенерированном фрагменте и производственный процесс вокруг этого.

Сгенерировать по этой подсказке → Выберите 10 секунд и 768P. Для преобразования изображения в видео добавьте своё изображение-кадр и пропустите aspect_ratio.

Предварительные требования

Получите ключ API в консоли hiapi. Каждый вызов ниже использует Authorization: Bearer YOUR_API_KEY для аутентификации на общем асинхронном эндпоинте задачи POST https://api.hiapi.ai/v1/tasks.

Минимальный пример: одна фотография, три угла камеры

first_frame_image закрепляет субъект и сцену, давая модели конкретный материал, от которого можно переключаться и возвращаться. Подсказка описывает каждый кадр как явный пронумерованный переход. Эта подсказка с мотоциклом является примером кода без приложенного образца рендеринга.

Красный винтажный мотоцикл, припаркованный на мокрой городской улице в сумерках, неоновые вывески отражаются на асфальте. Кадр 1 — низкий широкий угол: камера держит статичный широкий кадр всего мотоцикла, моросит дождь. Переход к кадру 2 — крупный план: камера плотно приближается к хромированной фаре и переднему колесу, медленно следя вправо. Переход к кадру 3 — верхний вид сверху: камера смотрит строго вниз на мотоцикл сверху, медленно вращаясь. Без текста и субтитров.

Сгенерировать по этой подсказке → Добавьте своё общедоступное изображение мотоцикла, выберите 10 секунд и 768P и пропустите 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}")

Замените first_frame_image на реальный общедоступный HTTPS URL изображения или полностью удалите его, чтобы сгенерировать ту же многокадровую последовательность только по тексту — minimax-h3-max обрабатывает как текст-в-видео, так и изображение-в-видео через одно и то же поле prompt.

Написание подсказки: шаблон пронумерованных кадров

Три решения делают целевую последовательность кадров однозначной:

  1. Одно предложение, задающее сцену, затем пронумерованные кадры. Опишите субъект и сцену один раз, затем перечислите каждый угол камеры как отдельный помеченный такт: Кадр 1 - [композиция]: [действие]. Переход к кадру 2 - [композиция]: [действие]. «Переход к кадру N» явно требует смены угла камеры.
  2. Используйте стандартную кинематографическую лексику. низкий широкий кадр, кадр сверху, крупный план, медленный наезд, боковой следящий кадр, ручная камера — эти слова указывают нужную композицию и движение. Расплывчатые формулировки вроде «ещё один крутой ракурс» дают нестабильные результаты.
  3. Планируйте количество кадров по длительности. duration — целое число от 5 до 15 секунд. Два-три кадра реалистичны; пять разных углов в 5-секундном фрагменте — это менее секунды на кадр, что часто выглядит как артефакт, а не как склейка.

first_frame_image и last_frame_image необязательны и независимы друг от друга — можно задать одно, оба или ни одного. При указании любого из них пропустите aspect_ratio: эти поля взаимоисключающие, изображение-кадр определяет соотношение сторон вывода. Также учтите, что между ракурсами не гарантируется строгая трёхмерная или геометрическая согласованность — это генеративная видеомодель, а не фотограмметрический конвейер, поэтому даже с привязкой к первому кадру ожидайте лёгкого дрейфа деталей субъекта между кадрами.

Подготовка к производству

  • Как только масштаб превышает скрипт, предпочитайте обратные вызовы опросу. Добавьте в тело запроса "callback": {"url": "https://your-domain.com/hiapi/callback", "when": "final"}, и hiapi отправит POST-уведомление при достижении задачей конечного состояния, вместо того чтобы вы опрашивали GET /v1/tasks/{taskId} в цикле.
  • Устраняйте дубликаты по taskId. Ответы опроса и обратные вызовы используют один и тот же taskId — рассматривайте повторные уведомления о конечном состоянии для одного ID как идемпотентные, а не как несколько независимых задач.
  • Немедленно скачивайте вывод. Успешные задачи возвращают data.output[].url для временного хранения. Выберите элемент вывода с type равным video и проверьте его временную метку Unix в секундах expireAt. Перезагрузите его в собственное хранилище в том же обработчике, который обрабатывает конечное состояние.
  • Обрабатывайте две формы ошибок. Неверное тело запроса (неподдерживаемые поля, duration вне диапазона, некорректный URL изображения) быстро завершается ошибкой при отправке с 400 INVALID_REQUEST. Проблемы аутентификации возвращают 401 с error.code: "permission_denied". Задачи, завершившиеся ошибкой во время генерации, сообщают "status": "fail" в ответе опроса/обратного вызова — проверяйте status перед тем, как доверять output.

Связанные материалы

  • Страница модели minimax-h3-max — актуальные цены, параметры и песочница, где можно протестировать подсказки в браузере перед интеграцией в код.
  • Документация API minimax-h3-max — полный справочник параметров и детали обратных вызовов.
  • Цены H3 и H3 Max — тарифы по разрешению и бюджеты коротких видео.
  • Цены hiapi — текущие ставки за секунду для каждой модели.

Часто задаваемые вопросы

Есть ли у minimax-h3-max специальный параметр множественных ракурсов или нескольких камер? Нет. Поля ввода в документации — это prompt, first_frame_image, last_frame_image, duration, resolution и aspect_ratio. Описывайте несколько кадров внутри prompt, а не добавляйте поле угла камеры.

Можно ли задать aspect_ratio вместе с first_frame_image или last_frame_image? Нет. aspect_ratio взаимоисключающе с любым полем изображения-кадра. Предоставленное изображение определяет соотношение сторон вывода. Если передаётся любое изображение-кадр, пропустите aspect_ratio.

Какой длины может быть многокадровый фрагмент? duration принимает целые секунды от 5 до 15. Два-три разных угла камеры довольно свободно помещаются в это окно; больше — и каждый кадр часто сжимается до доли секунды.

Будет ли субъект идеально согласован между разными углами? Не гарантируется. minimax-h3-max — генеративная видеомодель, поэтому даже если first_frame_image закрепляет начальный кадр, детали (точные текстуры, незначительные пропорции) могут дрейфовать между кадрами. Считайте это сильной творческой согласованностью, а не попиксельной многовидовой реконструкцией.

Могу ли я генерировать многокадровый фрагмент только по тексту, без исходного изображения? Да — опустите first_frame_image и last_frame_image и опишите сцену и кадры в prompt. Чисто текстовая генерация использует горизонтальный холст по умолчанию. Для портретной композиции предоставьте портретное изображение-кадр, не задавая aspect_ratio, или обрежьте/заполните сохранённое видео в редакторе.

Как выглядит ошибка аутентификации? HTTP 401 с телом ответа вида {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}. Внимательно проверьте заголовок Authorization: Bearer и не отозван ли ключ из консоли.

Скопируйте последовательность кадров с мотоциклом и сгенерируйте по этой подсказке → Выберите 10 секунд и 768P; добавьте своё изображение-кадр, чтобы задать начальную композицию.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API