Tutoriel
Rédiger des prompts image-vers-vidéo multi-angles avec minimax-h3-max via l'API hiapi
Aucun paramètre d'angle de caméra — la méthode de rédaction de prompts ci-dessous transforme une photo en séquence multi-plans.
minimax-h3-max peut transformer une photo en vidéo de 5 à 15 secondes, mais son point de terminaison n'expose aucun paramètre « angle de caméra », « multi-vues » ou « nombre de plans » — la référence des paramètres liste comme champs d'entrée pris en charge prompt, first_frame_image, last_frame_image, duration, resolution et aspect_ratio. Écrivez les instructions de caméra dans prompt, champ qui accepte jusqu'à 7 000 caractères.
Ainsi, un clip « multi-angles » — passant d'un plan d'ensemble d'ouverture à un gros plan, puis à un plan en suivi — n'est pas un paramètre que vous définissez, mais un prompt que vous écrivez. Ce tutoriel couvre la structure de la requête, les schémas de prompt demandant plusieurs angles de caméra au sein d'un même clip généré, ainsi que le flux de production qui l'entoure.
Générer avec ce prompt → Choisissez 10 secondes et 768P. Pour l'image-vers-vidéo, ajoutez votre image de trame et omettez aspect_ratio.
Prérequis
Obtenez une clé API depuis votre console hiapi. Chaque appel ci-dessous s'authentifie sur le point de terminaison partagé de tâches asynchrones POST https://api.hiapi.ai/v1/tasks avec Authorization: Bearer YOUR_API_KEY.
Exemple minimal : une photo, trois angles de caméra
first_frame_image ancre le sujet et la scène, donnant au modèle un contenu concret vers lequel couper et revenir. Le prompt décrit chaque plan comme une coupe numérotée explicite. Ce prompt de moto est un exemple de code, sans rendu d'exemple joint.
Une moto vintage rouge garée sur une rue urbaine mouillée au crépuscule, des enseignes au néon se reflétant sur le trottoir. Plan 1 - grand angle en contre-plongée : la caméra maintient un plan large statique de la moto entière, une pluie fine tombe. Coupe vers le plan 2 - gros plan : la caméra avance serré sur le phare chromé et la roue avant, en suivant lentement vers la droite. Coupe vers le plan 3 - plongée verticale : la caméra regarde droit vers le bas la moto depuis au-dessus, en tournant lentement. Aucun texte ni sous-titre.
Générer avec ce prompt → Ajoutez votre propre image de moto accessible publiquement, choisissez 10 secondes et 768P, et omettez 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}")
Remplacez first_frame_image par une URL d'image HTTPS réelle et accessible publiquement, ou supprimez-la entièrement pour générer la même séquence multi-angles à partir du seul texte — minimax-h3-max gère à la fois le texte-vers-vidéo et l'image-vers-vidéo via le même champ prompt.
Rédiger le prompt : le schéma des plans numérotés
Trois choix rendent votre séquence de plans cible claire et explicite :
- Une phrase d'établissement de scène, puis des plans numérotés. Décrivez le sujet et la scène une seule fois, puis listez chaque angle de caméra comme un temps annoté distinct :
Plan 1 - [cadrage] : [action]. Coupe vers le plan 2 - [cadrage] : [action].« Coupe vers le plan N » demande explicitement un changement d'angle de caméra. - Employez le vocabulaire cinématographique standard.
grand angle en contre-plongée,plan en plongée verticale,gros plan,travelling avant lent,plan en suivi latéral,caméra à l'épaule— ces termes indiquent le cadrage et le mouvement voulus. Des formulations vagues comme « un autre angle sympa » produisent des résultats incohérents. - Planifiez le nombre de plans selon la durée.
durationest un entier de 5 à 15 secondes. Deux à trois plans sont réalistes ; caser cinq angles différents dans un clip de 5 secondes donne moins d'une seconde par plan, ce qui ressemble souvent à un bug plutôt qu'à une coupe.
first_frame_image et last_frame_image sont tous deux facultatifs et indépendants l'un de l'autre — vous pouvez en définir un, les deux, ou aucun. Si vous en fournissez un, omettez aspect_ratio : ces champs sont mutuellement exclusifs et l'image de trame détermine le rapport d'aspect de la sortie. Notez aussi que l'exactitude tridimensionnelle ou géométrique n'est pas garantie d'un angle à l'autre — c'est un modèle de vidéo génératif, pas une chaîne de photogrammétrie ; attendez-vous donc, même avec une première trame ancrée, à une légère dérive des détails du sujet entre les coupes.
Le rendre prêt pour la production
- Au-delà de l'échelle du script, privilégiez le callback au polling. Ajoutez
"callback": {"url": "https://your-domain.com/hiapi/callback", "when": "final"}dans le corps de la requête ; hiapi enverra un POST de notification lorsque la tâche atteint un état final, au lieu que vous interrogiezGET /v1/tasks/{taskId}en boucle. - Dédupliquez par
taskId. Les réponses de polling et les callbacks sont tous deux indexés par le mêmetaskId— traitez les notifications d'état final répétées pour un même ID comme idempotentes, et non comme plusieurs tâches distinctes. - Téléchargez immédiatement les sorties. Une tâche réussie renvoie
data.output[].urlpour un stockage temporaire. Choisissez l'élément de sortie dont letypevautvideoet vérifiez son horodatage UnixexpireAt(en secondes). Dans le même gestionnaire qui traite l'état final, réhébergez-le sur votre propre stockage. - Gérez les deux formes d'échec. Un corps de requête incorrect (champ non pris en charge,
durationhors plage, URL d'image malformée) échoue rapidement à la soumission avec400 INVALID_REQUEST. Un problème d'authentification renvoie401avecerror.code: "permission_denied". Une tâche qui échoue pendant la génération signale"status": "fail"dans la réponse de polling/callback — vérifiezstatusavant de faire confiance àoutput.
Pour aller plus loin
- Page du modèle minimax-h3-max — tarification en direct, paramètres, et aire de test pour essayer des prompts dans le navigateur avant de les intégrer au code.
- Documentation API de minimax-h3-max — référence complète des paramètres et détails des callbacks.
- Tarification H3 et H3 Max — taux par résolution et budget pour les vidéos courtes.
- Tarification hiapi — tarif actuel par seconde pour chaque modèle.
FAQ
minimax-h3-max dispose-t-il d'un paramètre dédié multi-angles ou multi-caméras ?
Non. Les champs d'entrée documentés sont prompt, first_frame_image, last_frame_image, duration, resolution et aspect_ratio. Décrivez plusieurs plans dans prompt plutôt que d'ajouter un champ d'angle de caméra.
Peut-on définir aspect_ratio avec first_frame_image ou last_frame_image ?
Non. aspect_ratio est mutuellement exclusif avec tout champ d'image de trame. L'image fournie détermine le rapport de sortie. Dès que vous passez une image de trame, omettez aspect_ratio.
Quelle peut être la durée d'un clip multi-angles ?
duration accepte un entier de 5 à 15 secondes. Deux à trois angles de caméra différents tiennent confortablement dans cette fenêtre ; au-delà, chaque plan se retrouve souvent compressé à une fraction de seconde.
Le sujet reste-t-il parfaitement cohérent d'un angle à l'autre ?
Ce n'est pas garanti. minimax-h3-max est un modèle de vidéo génératif, donc même si first_frame_image ancre la trame d'ouverture, les détails (textures précises, proportions subtiles) peuvent dériver entre les coupes. Considérez cela comme une forte cohérence créative, et non comme une reconstruction multi-vues exacte au pixel près.
Peut-on générer un clip multi-angles à partir du seul texte, sans image source ?
Oui — omettez first_frame_image et last_frame_image et décrivez la scène et les plans dans le prompt. La génération purement textuelle utilise le canevas horizontal par défaut. Pour un cadrage vertical, fournissez une image de trame verticale sans définir aspect_ratio, ou recadrez/complétez la vidéo enregistrée dans l'éditeur.
À quoi ressemble un échec d'authentification ?
HTTP 401, avec un corps de réponse semblable à {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}. Vérifiez soigneusement l'en-tête Authorization: Bearer et si la clé a été révoquée depuis la console.
Copiez la séquence de plans de la moto et générez avec ce prompt → Choisissez 10 secondes et 768P ; ajoutez votre image de trame pour guider la composition d'ouverture.
Articles similaires
Voir tous les articles →-
Tutoriel
Comment appeler hailuo-2.3-fast/image-to-video via l'API HiAPI : curl et Python en pratique
La première requête exploitable du palier image-vers-vidéo rapide et économique — de l'ID du modèle au téléchargement du MP4
-
Tutoriel
Comment appeler hailuo-2.3/text-to-video via l'API HiAPI : curl, Python et exemples de requêtes exécutables
-
Tutoriel
Utiliser Kandinsky 6.0 Pro texte-vers-vidéo sur HiAPI : tutoriel curl et Python
Démonstration pratique axée sur la requête : construire l'appel du prompt au clip vidéo, soumettre la requête, interroger l'état d'achèvement et télécharger le résultat