Seedance 2.5 est maintenant en ligne — En avant-première sur Atlas Cloud

Votre MiniMax H3 Poll Loop ne se termine jamais. Voici le tutoriel qui se termine réellement.

Un tutoriel MiniMax H3 avec la boucle asynchrone complète : l'appel de création, une boucle de sondage qui gère les cinq statuts réels, le défi de rappel de 3 secondes, et les deux choses qui expirent silencieusement.

Votre première requête POST est revenue en dix secondes avec un task_id. Ça semblait gagné.

Puis rien ne s'est passé pendant six minutes. Vous aviez copié while status != "Success" d'un tutoriel, et la boucle tournait en rond, car cet endpoint ne renvoie plus le mot Success. Vous êtes donc passé à un webhook. Pas une seule notification n'est arrivée, et rien nulle part ne vous a dit pourquoi. Le lendemain matin, vous êtes retourné chercher le rendu de la veille et le lien répondait 404.

Ces quatre choses semblent indépendantes. Aucune n'est la faute du modèle. Les quatre relèvent du contrat asynchrone, que presque personne ne formalise. Voici ce contrat en entier, plus un vrai court métrage en deux plans qui en est sorti.

Points clés

  • Trois endpoints, une boucle : create renvoie un task_id et se déconnecte, vous interrogez, vous téléchargez. Tout ce qui est dur se passe après l'appel create.
  • Les cinq vrais statuts sont queued, running, succeeded, failed, cancelled. Il n'y a pas de statut expired, quoi qu'un article de blog ait pu vous dire.
  • Deux choses expirent, et ce ne sont pas des statuts : l'URL de téléchargement est limitée dans le temps, et l'enregistrement de la tâche n'est consultable que pendant 7 jours.
  • Si vous utilisez un callback, MiniMax envoie d'abord une requête de vérification avec un champ challenge et vous devez le renvoyer inchangé en moins de 3 secondes. Si vous échouez, vous n'obtenez aucune erreur, juste un silence définitif.
  • Pour la génération textuelle uniquement, ratio est obligatoire et ne peut pas être adaptive. Pour l'image vers vidéo, la première image décide du cadre, et tout ratio que vous passez est ignoré.

Le résultat final d'abord

Toute la récompense de ce tutoriel : deux plans MiniMax H3 en 2K, concaténés, 14,6 secondes. Le plan A est une image vers vidéo à partir d'une première image générée, le plan B est un texte vers vidéo. Activez le son. L'audio n'est pas une bande-son rajoutée par-dessus, H3 a rendu les engrenages, la pluie et la ligne murmurée dans le cadre de la même génération.

Trois appels API ont permis cela. Un modèle d'image pour la première image, deux endpoints H3 pour les plans, une ligne ffmpeg pour les assembler. Le code ci-dessous est le code qui l'a produit.

Pourquoi la plupart des tutoriels MiniMax H3 se cassent à la deuxième requête

Presque tous les guides pour ce modèle s'arrêtent à l'appel create. C'est la moitié facile. L'appel create valide votre payload, vous donne un task_id et se déconnecte, et ensuite vous êtes seul avec un travail qui prend des minutes et un ensemble de règles que personne n'a imprimées.

Les échecs sont ennuyeusement répétables. J'ai rencontré cinq de ces six en un après-midi.

SymptômeCe que vous voyezCause réelleCorrectif
La boucle de poll ne sort jamaisLe terminal imprime à l'infini, le travail est fini depuis longtempsVotre condition de sortie compare avec des mots v1 comme Success / Fail. L'endpoint de requête v2 renvoie succeeded / failed en minusculesFaire correspondre à l'énumération v2, et lever une exception pour tout statut non reconnu
400 immédiat sur texte vers vidéoRequête rejetée avant tout renduratio manquant, ou défini sur adaptive, que le mode textuel refusePasser un ratio explicite, par exemple 16:9
Votre ratio est ignoré silencieusementL'image de sortie n'est pas celle demandéeL'image vers vidéo dérive le cadre de la première image, donc ratio est sans effet làRogner ou générer la première image au format souhaité
Webhook ne se déclenche jamais, pas d'erreurAucune notification, logs propres, aucune plainte de l'APILa poignée de main de vérification a échoué. MiniMax a envoyé un challenge et votre endpoint ne l'a pas renvoyé inchangé en moins de 3 secondesRépondre au challenge de manière synchrone, avant tout middleware d'auth ou de file d'attente
L'URL d'hier répond 404Lien de téléchargement mort, le rendu semble disparuL'URL de téléchargement est limitée dans le temps. Le rendu est intactInterroger à nouveau le même task_id pour obtenir une nouvelle URL, dans la fenêtre de 7 jours
429 aléatoires sous chargeCertains soumissions rejetées, pas de file d'attenteLa concurrence est plafonnée, et c'est un plafond dur, pas une file d'attenteLimiter votre propre nombre de tâches en cours et réessayer la soumission, pas le rendu

La première ligne est celle qui mange des soirées entières, et il vaut la peine d'être précis. L'ancienne API vidéo de MiniMax rapportait la progression avec des mots capitalisés dans la famille Preparing / Queueing / Processing / Success / Fail. L'endpoint de requête v2 utilisé par H3 renvoie queued, running, succeeded, failed, cancelled (Référence API MiniMax, août 2026). De nombreux documents de revendeurs tiers impriment encore l'ancien ensemble, ou mélangent les deux sur une seule page. Si vous avez hérité d'une boucle de l'un d'eux, elle ne peut pas se terminer, car la chaîne qu'elle attend n'est jamais envoyée.

Workflow du tutoriel MiniMax H3 : trois endpoints, cinq statuts, une boucle

H3 est sorti le 31 juillet 2026 en tant que modèle vidéo omni-modal : texte, image, vidéo et audio vivent tous dans la même fenêtre de contexte, avec une sortie jusqu'à 15 secondes en 2K avec audio stéréo natif (MarkTechPost, août 2026). Pour l'API, cela signifie un endpoint create avec un tableau content, et ce que vous mettez dans le tableau décide dans quel mode vous êtes.

ModeCe qui va dans contentrole sur l'élément imageCe que fait ratioUtilisez-le pour
Text-to-video (texte vers vidéo)un élément texteaucuneObligatoire, et adaptive est rejetéPlans sans image source, contrôle total du cadre
Image-to-video (image vers vidéo)élément texte + élément imagefirst_frame (éventuellement aussi last_frame)Ignoré, la première image décideAnimer une image fixe que vous avez déjà dirigée artistiquement
Reference-to-video (référence vers vidéo)élément texte + élément de référencereference_image (également reference_video, reference_audio)Obligatoire, comme pour le texte seulGarder un personnage ou une voix cohérents entre les plans

Et la partie que votre code doit réellement gérer. Cinq statuts, cinq branches différentes.

StatutCe que cela signifieCe que votre code fait
queuedAccepté, en attente d'un créneauContinuer à interroger, temporiser
runningRendu en coursContinuer à interroger, temporiser
succeededTerminé, content.url est renseignéTélécharger immédiatement, dans cette itération
failedÉchec du renduLire le corps de l'erreur, le journaliser, ne pas réessayer aveuglément le même payload
cancelledTravail annuléSortir de la boucle, traiter comme terminal
autre chosePas dans l'énumérationLever une exception. Un nouveau statut que vous traitez silencieusement comme "continuer d'attendre" est le bogue du tableau ci-dessus

Il n'y a pas de statut expired. Ce mot est souvent attaché à cette API et appartient à deux autres choses : l'URL de téléchargement, qui est limitée dans le temps et actualisable, et l'enregistrement de la tâche, qui n'est consultable que pour les 7 derniers jours. Les deux sont couverts à l'étape 4.

Encore un chiffre avant le code. La concurrence pour la génération vidéo sur H3 est plafonnée par le nombre de connexions, et non par le nombre de requêtes par minute : 2 tâches simultanées sur le niveau gratuit, 15 une fois que vous êtes payant (Limites de débit MiniMax, août 2026). Au-delà du plafond, vous obtenez immédiatement un 429. Rien ne se met en file d'attente pour vous. J'ai aussi poussé 20 tâches H3 simultanées via une passerelle de routage et les 20 ont abouti, et j'ai eu un 429 sur la même configuration un autre jour, donc considérez tout nombre supérieur au plafond documenté comme météo, pas une constante.

Direct ou via une passerelle

Les trois étapes sont les mêmes dans les deux cas, mais les chaînes diffèrent, et cela compte lorsque vous déboguez à 1h du matin.

MiniMax directPasserelle unifiée (Atlas Cloud)
SoumettrePOST /v2/video_generationPOST /api/v1/model/generateVideo
Interroger (poll)GET /v2/query/video_generation/{task_id}GET /api/v1/model/prediction/{id}
Mots de statutqueued / running / succeeded / failed / cancelledcompleted en cas de succès, failed en cas d'échec
Notifications pushURL de callback avec la poignée de main du challenge en 3 secondesInterroger l'ID de prédiction
Concurrence2 gratuit, 15 payant, 429 durNon publié comme plafond par modèle, mesuré plus large en pratique
Modèle d'image pour première image sur la même cléNon, compte séparéOui, GPT Image 2 et H3 se trouvent derrière une seule clé
Prix H3Publié par niveau de résolutionPar seconde de sortie, par niveau de résolution, cité sur le bouton Run avant soumission

La raison pour laquelle j'ai exécuté la chaîne de ce tutoriel sur une passerelle est purement l'avant-dernière ligne : la première image provient d'un modèle d'image OpenAI et les deux plans proviennent de MiniMax, et je ne voulais pas deux fournisseurs, deux clés et deux pages de facturation pour un seul film de 14 secondes. Si vous êtes déjà sur la plateforme MiniMax, restez-y, la boucle ci-dessous fonctionne inchangée à part les chemins et les mots de statut.

Hailuo AI Video Generator : comment l'utiliser avant d'écrire du code

Si vous êtes arrivé ici en cherchant comment utiliser le générateur vidéo Hailuo AI, vous êtes au bon endroit et vous n'avez encore besoin d'aucun code. Hailuo est l'application grand public de MiniMax et H3 est le nom du modèle utilisé par l'API. Même moteur, porte différente.

Trois minutes, pas de terminal :

  1. Ouvrez une page de modèle, par exemple MiniMax H3 image-to-video. Le playground est le panneau de droite de la page.
  2. Déposez une première image, ou passez à la page texte-vers-vidéo et écrivez simplement un prompt. Définissez la résolution et la durée. Dites à voix haute ce que vous voulez entendre, pas seulement ce que vous voulez voir : H3 génère l'audio dans le même passage, donc "pluie qui tambourine sur le verre, petits clics de servo" est une vraie instruction, pas une décoration.
  3. Appuyez sur Run. Le bouton indique le montant exact facturé pour les réglages que vous avez choisis avant de vous engager. Attendez, téléchargez.

C'est tout le chemin sans code, et pour des clips uniques, c'est vraiment l'option la plus rapide. Dès que vous voulez dix variantes, ou une première image générée par un autre modèle et injectée directement, revenez au code. C'est ce que fait le reste de cet article.

Le tutoriel MiniMax H3 : Créer, interroger, télécharger, répéter

Un exemple parcourt les sept étapes : un horloger répare un petit oiseau mécanique en laiton, lui murmure une phrase, et l'oiseau s'envole de l'atelier. Deux plans. Le plan A est une image vers vidéo pour que l'intérieur soit dirigé artistiquement. Le plan B est un texte vers vidéo car il n'y a pas d'image source pour le ciel.

Étape 1 : Générer la première image avec GPT Image 2

L'image vers vidéo ignore ratio, donc la première image est l'endroit où vous décidez du cadre du plan A. Générez-la en 16:9 et au niveau de qualité le plus élevé, car H3 héritera de tous ses défauts et y ajoutera du flou de mouvement.

Modèle : openai/gpt-image-2/text-to-image. Réglages : qualité high, 2048x1152, 16:9, PNG.

text
1Un atelier d'horloger encombré au crépuscule, lampe tungstène chaude au-dessus d'un établi en chêne marqué.
2Un vieux réparateur en tablier de cuir se penche sur un petit oiseau mécanique en laiton reposant dans ses mains en coupe,
3ses plaques d'ailes entrouvertes, de minuscules engrenages visibles.
4La pluie strie la fenêtre à meneaux derrière lui ; un poêle à charbon brille ambre à gauche du cadre.
5Faible profondeur de champ, 35 mm, poussière volumétrique dans le faisceau de la lampe, palette ambre profond et sarcelle, photoréaliste, pas de texte.
6

Interface du générateur d'images AI affichant un prompt textuel et la sortie générée

Playground GPT Image 2 sur Atlas Cloud avec le prompt de première image de ce tutoriel et l'atelier d'horloger rendu dans le panneau de sortie

GPT Image 2 sur Atlas Cloud, qualité high à 2048x1152. Le bouton Run indique le montant exact facturé pour les réglages choisis, 0,1745 $ pour celui-ci, avant de vous engager.

Conservez l'URL renvoyée. L'étape 2 l'envoie directement à H3, sans aller-retour de téléchargement.

Étape 2 : Créer la tâche MiniMax H3 et conserver le task_id

L'appel create fait deux choses puis ne se soucie plus de vous : il valide le payload et renvoie un task_id. Un 400 ici est dû à votre payload, pas à un échec transitoire, donc ne le mettez pas derrière une boucle de réessai. Toute autre classe de problème apparaît plus tard, lors de l'interrogation.

La seule habitude qui fait économiser de l'argent : persistez le task_id avant de faire quoi que ce soit d'autre. Les tâches ne sont consultables que pendant 7 jours, et si votre processus meurt avec l'id en mémoire, vous avez payé pour un rendu que vous ne pouvez plus atteindre.

python
1import os, json, time, requests
2
3BASE = "https://api.minimax.io"
4HEADERS = {
5    "Authorization": f"Bearer {os.environ['MINIMAX_API_KEY']}",
6    "Content-Type": "application/json",
7}
8
9def create_task(payload: dict) -> str:
10    r = requests.post(f"{BASE}/v2/video_generation",
11                      headers=HEADERS, json=payload, timeout=60)
12    if r.status_code == 400:
13        # votre payload est erroné. le réessayer serait juste le refaire de travers.
14        raise ValueError(f"rejeté : {r.text}")
15    r.raise_for_status()
16    task_id = r.json()["task_id"]
17    with open("tasks.jsonl", "a") as f:                 # persister AVANT toute autre chose
18        f.write(json.dumps({"task_id": task_id, "at": int(time.time()),
19                            "payload": payload}) + "\n")
20    return task_id
21
22SHOT_A_PROMPT = (
23    "Les mains du vieux réparateur stabilisent l'oiseau en laiton. Ses yeux de verre vacillent, "
24    "les plaques d'ailes s'ouvrent une par une en cliquant. Il se penche et murmure, près du micro, "
25    ""Voyons si tu te souviens encore du ciel." Lent push-in 50 mm, lumière de lampe balayant "
26    "le laiton, pluie tambourinant sur la fenêtre, crépitement du poêle à charbon, petits clics de servo "
27    "sous sa voix. Ambre chaud, remplissage de fenêtre sarcelle. Pas de texte à l'écran."
28)
29
30shot_a = create_task({
31    "model": "MiniMax-H3",
32    "resolution": "2K",
33    "duration": 8,
34    # pas de "ratio" ici volontairement : l'image vers vidéo prend le cadre de la première image
35    "content": [
36        {"type": "text", "text": SHOT_A_PROMPT},
37        {"type": "image_url", "role": "first_frame",
38         "image_url": {"url": FIRST_FRAME_URL}},
39    ],
40})
41print("tâche shot A :", shot_a)
42

Voici ce même prompt et cette première image exécutés en tant que travail, pour que vous puissiez voir à quoi ressemble une soumission saine de l'autre côté :

Capture d'écran d'une interface de générateur vidéo AI avec entrée et sortie

Playground MiniMax H3 image-to-video sur Atlas Cloud avec la première image de l'atelier chargée et le clip rendu dans le panneau de sortie

MiniMax H3 image-to-video : première image chargée à gauche, clip 2K terminé dans OUTPUT à droite. Notez le champ Aspect Ratio verrouillé sur adaptive, et le devis de 1,12 $ pour 2K à 8 secondes.

Étape 3 : Interroger (poll) et gérer les cinq statuts MiniMax H3

C'est la boucle que tout le monde a faux, donc il vaut la peine de l'écrire en entier. Quatre règles : temporiser au lieu de marteler, plafonner l'attente totale, traiter succeeded comme "télécharger maintenant", et lever une exception pour tout statut non présent dans l'énumération.

python
1TERMINAL_OK   = {"succeeded"}
2TERMINAL_BAD  = {"failed", "cancelled"}
3IN_FLIGHT     = {"queued", "running"}
4
5def poll(task_id: str, timeout_s: int = 900) -> dict:
6    delay, deadline = 3.0, time.time() + timeout_s
7    while time.time() < deadline:
8        r = requests.get(f"{BASE}/v2/query/video_generation/{task_id}",
9                         headers=HEADERS, timeout=30)
10        r.raise_for_status()
11        task = r.json()["task"]
12        status = task["status"]
13
14        if status in TERMINAL_OK:
15            return task                                  # content.url est valide MAINTENANT
16        if status in TERMINAL_BAD:
17            raise RuntimeError(f"{status} : {json.dumps(r.json())[:400]}")
18        if status not in IN_FLIGHT:
19            # un statut que l'énumération n'a pas. NE PAS passer à "continuer d'attendre".
20            raise RuntimeError(f"statut inconnu {status!r} -- lisez le journal des modifications")
21
22        print(f"  {status} ... prochaine vérification dans {delay:.0f}s")
23        time.sleep(delay)
24        delay = min(delay * 1.5, 15.0)                    # 3s -> plafond 15s
25    raise TimeoutError(f"{task_id} toujours pas terminal après {timeout_s}s")
26

Trois choses dans ce code sont délibérées :

status not in IN_FLIGHT lève une exception au lieu de continuer. Si MiniMax ajoute un sixième statut le trimestre prochain, vous voulez un crash sonore, pas une boucle qui attend un mot qui ne viendra jamais. Cette seule ligne fait la différence entre le tutoriel cassé et celui-ci.

failed ne réessaie pas. Un rendu échoué signifie généralement que le prompt a déclenché un filtre ou que le payload avait une mauvaise combinaison, et renvoyer le même payload vous achète le même échec au prix fort. Journalisez le corps, regardez-le, puis décidez.

La temporisation commence à 3 secondes et monte à 15. H3 en 2K prend des minutes, pas des secondes. Interroger une fois par seconde épuise juste votre limite de débit sur l'endpoint de requête.

Étape 4 : Télécharger avant l'expiration de l'URL

Dès que succeeded arrive, téléchargez le fichier en flux sur le disque. L'URL dans content.url est explicitement un lien limité dans le temps : "Téléchargez-le ou stockez-le rapidement ; interrogez à nouveau pour obtenir une nouvelle URL après son expiration" (Référence API MiniMax, août 2026). Ce n'est pas un chemin CDN que vous pouvez mettre dans votre base de données et oublier.

La deuxième moitié est la bonne nouvelle, et c'est la réponse au 404 que vous avez eu le lendemain matin. Le rendu n'est pas perdu. Interrogez à nouveau le même task_id et vous obtenez une nouvelle URL, jusqu'à 7 jours après la création.

python
1def download(url: str, path: str) -> str:
2    with requests.get(url, stream=True, timeout=300) as r:
3        r.raise_for_status()
4        with open(path, "wb") as f:
5            for chunk in r.iter_content(1 << 20):
6                f.write(chunk)
7    return path
8
9def refresh_url(task_id: str) -> str:
10    """Lien mort ? Le rendu est intact. Redemandez, dans la fenêtre de 7 jours."""
11    r = requests.get(f"{BASE}/v2/query/video_generation/{task_id}",
12                     headers=HEADERS, timeout=30)
13    r.raise_for_status()
14    return r.json()["task"]["content"]["url"]
15
16task = poll(shot_a)
17download(task["content"]["url"], "shot-a.mp4")
18

Ce qui revient pour le plan A, à côté de l'image fixe dont il est parti :

Comparaison côte à côte d'un artisan examinant un oiseau mécanique

Côte à côte : la première image générée à gauche, une image du clip MiniMax H3 terminé à droite, montrant les plaques d'ailes de l'oiseau ouvertes et les yeux allumés

À gauche : l'image fixe GPT Image 2 de l'étape 1, telle que soumise. À droite : une image extraite du clip 2K renvoyé par H3. Même décor, même lumière, les plaques d'ailes et les yeux sont ce qui a bougé.

Étape 5 : Plan B avec MiniMax H3 texte vers vidéo, où ratio est obligatoire

Pas d'image source pour le ciel, donc le plan B est uniquement textuel. Cela inverse la règle de ratio de "ignoré" à "obligatoire" : pour un prompt textuel uniquement, ratio est obligatoire et ne peut pas être adaptive (Référence API MiniMax, août 2026). L'omettre ou envoyer adaptive vous donne un 400 immédiat, avant même que le rendu ne commence.

Modèle : minimax/h3/text-to-video. Réglages : 2K, durée 6, ratio 16:9.

text
1L'oiseau en laiton jaillit à travers un puits de lumière entrouvert de l'atelier dans un ciel de soirée lavé par la pluie,
2les ailes battant dans un vrombissement d'engrenages, des gouttelettes jaillissant des plumes de métal
3alors qu'il monte au-dessus des toits d'ardoise mouillés vers une percée de nuage doré.
4La caméra s'élève derrière lui, 24 mm, contre-jour depuis le soleil bas. Son : servos d'ailes vrombissant,
5vent qui se lève, cloche d'église lointaine, pluie qui s'estompe. Pas de texte.
6
python
1shot_b = create_task({
2    "model": "MiniMax-H3",
3    "resolution": "2K",
4    "duration": 6,
5    "ratio": "16:9",          # obligatoire ici. l'omettre ou passer "adaptive" -> 400
6    "content": [{"type": "text", "text": SHOT_B_PROMPT}],
7})
8download(poll(shot_b)["content"]["url"], "shot-b.mp4")
9

Capture d'écran d'une interface de générateur vidéo AI montrant l'entrée et la sortie

Playground MiniMax H3 texte-vers-vidéo sur Atlas Cloud avec le prompt de l'oiseau qui s'envole et le clip terminé dans le panneau de sortie

MiniMax H3 texte-vers-vidéo avec le prompt du plan B et le rapport d'aspect fixé explicitement à 16:9. Cette exécution a utilisé les 8 secondes par défaut de la page plutôt que les 6 du payload ci-dessus.

Étape 6 : Ignorer l'interrogation avec un callback, et renvoyer le challenge en 3 secondes

Si vous préférez être informé plutôt que de demander, passez callback_url sur l'appel create. Il y a exactement un piège, documenté dans une seule parenthèse dans la référence API, et c'est la façon la plus courante dont les callbacks auto-hébergés échouent.

Avant que MiniMax ne vous pousse quoi que ce soit, il envoie une requête de vérification contenant un champ challenge, et "vous devez retourner le challenge inchangé dans les 3 secondes pour terminer la vérification" (Référence API MiniMax, août 2026). Si vous le manquez, il n'y a aucune erreur nulle part. Vos appels create continuent de réussir, vos rendus continuent de se terminer, et vous ne recevez tout simplement jamais de notification. Rien dans aucun log ne dit pourquoi.

Douze lignes de FastAPI, et l'ordre à l'intérieur est tout le point :

python
1from fastapi import FastAPI, Request
2
3app = FastAPI()
4
5@app.post("/minimax/callback")
6async def callback(req: Request):
7    body = await req.json()
8    if "challenge" in body:                 # poignée de main de vérification, y répondre EN PREMIER
9        return {"challenge": body["challenge"]}   # inchangé, synchrone, sans porte d'auth
10    task_id = body.get("task_id")
11    status  = body.get("status")
12    enqueue(task_id, status)                # notification réelle : déléguer, retourner vite
13    return {"ok": True}
14

Les erreurs qui le tuent, par ordre de fréquence observée :

  • La requête de challenge traverse votre middleware d'auth et reçoit un 401 ou une redirection. La vérification n'est pas authentifiée par définition. Mettez le chemin en liste blanche.
  • Le gestionnaire pousse le challenge vers une file d'attente et répond de manière asynchrone. Trop tard. Cette réponse doit être dans le corps de la réponse de cette requête.
  • La valeur est resérialisée, tronquée ou emballée. Renvoyez-la octet pour octet.
  • Vous testez via un tunnel contre un serveur de développement serverless, et le démarrage à froid à lui seul dépasse 3 secondes. Préchauffez-le d'abord, ou vérifiez contre un processus déjà en cours.

L'interrogation (polling) est tout à fait acceptable, d'ailleurs. Si vous avez quelques tâches par heure, la boucle de l'étape 3 est moins de code et moins à casser. Le callback devient rentable lorsque vous avez beaucoup de tâches et que vous ne voulez pas un poller par tâche.

Étape 7 : Concaténer les deux plans en un seul film

Les deux plans sont revenus en 2560x1440 h264 à 24 ips avec audio stéréo AAC à 32 kHz. Même conteneur, même tout, donc c'est une copie de flux plutôt qu'un ré-encodage. Aucune perte de qualité, aucune attente.

Une petite surprise à laquelle s'attendre : demander 6 secondes m'a donné un fichier de 6,58 secondes. Les durées reviennent proches de ce que vous avez demandé, pas exactes à l'image près, donc les deux plans s'additionnent à 14,62 secondes plutôt qu'à un 14 net.

bash
1printf "file 'shot-a.mp4'\nfile 'shot-b.mp4'\n" > list.txt
2ffmpeg -f concat -safe 0 -i list.txt -c copy brass-bird-two-shot.mp4
3

Cette sortie est la vidéo en haut de cet article. Si -c copy se plaint, vos deux plans ont des résolutions ou des fréquences d'images différentes, ce qui sur H3 signifie que vous avez changé resolution entre les appels. Faites-les correspondre, ou abandonnez -c copy et acceptez un ré-encodage.

Variations de tutoriel MiniMax H3 qui valent la peine d'être volées

Cinq choses à essayer une fois que la boucle ci-dessus fonctionne, en ordre approximatif d'économies.

Brouillon en 768P, finition en 2K. Les deux niveaux sont le même modèle, et 768P coûte environ 29% de moins par seconde. Rendez vos candidats courts et bon marché, regardez-les, puis relancez uniquement le gagnant en 2K avec le même prompt. C'est là que se trouvent la plupart des économies dans une liste de plans. Le niveau dont vous avez réellement besoin pour la livraison est un autre débat, et je l'ai fait dans 768P vs 2K.

La durée est tout entier de 4 à 15. Pas un ensemble de préréglages. Si l'action se termine à 7 secondes, demandez 7 et arrêtez de payer pour 8.

Première image plus dernière image. Envoyez un deuxième élément image avec role: "last_frame" et H3 construira la transition entre elles. Utile pour les transitions entre des plans que vous avez déjà dirigés artistiquement.

Référence vers vidéo pour la continuité. role: "reference_image" maintient un personnage cohérent entre les plans au lieu de relancer son visage à chaque génération. Il existe un rôle reference_audio correspondant avec une fenêtre de 2 à 15 secondes pour le clip de référence, ce qui permet de garder une voix cohérente. Voir référence vers vidéo.

Tête parlante verticale. ratio: "9:16" avec une ligne de dialogue dans le prompt est le cas d'utilisation le plus volumineux de ce modèle actuellement, car l'audio sort du même passage et les lèvres correspondent sans étape de synchronisation labiale séparée.

L'art du prompt est une compétence distincte de la plomberie asynchrone, et si vos plans sont techniquement propres mais visuellement plats, le problème est en amont de cet article. Commencez par le guide de prompt H3.

Combien a coûté ce tutoriel MiniMax H3

Lignes réelles de l'exécution qui a produit le film en haut, citées par le bouton Run et vérifiées le 12 août 2026. H3 facture par seconde de sortie et le tarif est échelonné par résolution : les travaux en 2K ont été cités à 1,12 $ pour 8 secondes, soit 0,14 $ par seconde, et le tarif de départ du catalogue de 0,10 $ est le niveau 768P. Les trois endpoints H3 sont au prix fort actuellement, sans réduction appliquée.

ÉtapeModèleRéglagesFrais
Première imageGPT Image 2 texte vers imagequalité high, 2048x11520,1745 $
Plan AH3 image vers vidéo2K, 8s1,12 $
Plan BH3 texte vers vidéo2K, 16:9, 6s0,84 $
Film livré14,6s, deux plans, 2560x1440, audio stéréo2,13 $
Captures d'écran pour cet articleH3 i2v + t2v2K, 8s chacun2,24 $

Il est à noter que les mêmes deux plans brouillonnés en 768P auraient coûté 0,80 $ et 0,60 $ au lieu de 1,12 $ et 0,84 $, soit environ 29% de moins, pour des images sur lesquelles vous pouvez absolument juger une prise.

Deux détails de facturation qu'il est facile d'apprendre à ses dépens. Une requête rejetée à la soumission ne coûte rien, donc un 400 pour un ratio manquant est gratuit. Une requête qui rend quelque chose d'inutile n'est pas gratuite : si le travail atteint succeeded, vous êtes facturé, même si la sortie n'est pas ce que vous vouliez. C'est le véritable argument en faveur du brouillon en 768P.

Les tarifs par seconde, la comparaison 768P et 2K, et le comportement des frais en fonction de la durée sont détaillés correctement dans l'article compagnon sur la tarification de l'API MiniMax H3 de cet article. Celui-ci est le code, celui-là est la facture.

Attribution et territoire avant de déployer

Deux choses à vérifier avant que cela n'aille quelque part en public. Les conditions d'utilisation de l'API de MiniMax incluent une obligation de défense conditionnelle couvrant les réclamations de brevet et de droit d'auteur contre la sortie de l'API, et cette obligation ne s'étend pas aux marques de commerce ou à l'image, donc un logo reconnaissable ou une personne réelle dans votre prompt reste votre problème. Par ailleurs, la licence open-weights de H3 comporte une clause de territoires exclus, et cette clause régit les poids téléchargés et leurs sorties, pas l'API hébergée, dont les conditions nomment une région de service américaine que vous pouvez sélectionner. Lisez le contrat que vous avez réellement signé. Et étiquetez la sortie H3 comme sortie H3 dans votre interface utilisateur.

FAQ du tutoriel MiniMax H3

Quels sont les statuts de tâche MiniMax H3, et y en a-t-il un expired ?

Cinq : queued, running, succeeded, failed, cancelled. Il n'y a pas de statut expired. Deux autres choses expirent et sont confondues avec un : l'URL de téléchargement dans content.url est limitée dans le temps, et l'enregistrement de la tâche lui-même n'est consultable que pour les 7 derniers jours.

Dois-je utiliser un callback, ou l'interrogation (polling) est-elle suffisante pour MiniMax H3 ?

L'interrogation est suffisante et nécessite moins de code. Utilisez un callback lorsque vous avez suffisamment de tâches simultanées pour qu'un poller par tâche soit stupide. Si vous le faites, l'endpoint doit renvoyer le champ challenge inchangé en moins de 3 secondes, de manière synchrone, avant tout middleware d'authentification. Une poignée de main échouée ne produit aucun message d'erreur, juste un silence permanent.

Pourquoi ma requête MiniMax H3 texte vers vidéo renvoie-t-elle un 400 avec "ratio is required and cannot be adaptive" ?

Parce que vous êtes en mode textuel uniquement, où il n'y a pas de première image pour déduire le cadre. Passez une valeur explicite : 21:9, 16:9, 4:3, 1:1, 3:4 ou 9:16. La même règle explique pourquoi ratio semble ne rien faire en image vers vidéo, où la première image décide et tout ratio que vous envoyez est ignoré.

Combien de tâches MiniMax H3 puis-je exécuter en parallèle ?

Le plafond documenté est basé sur les connexions : 2 tâches simultanées gratuites, 15 payantes. Au-delà du plafond, vous obtenez un 429 immédiat plutôt qu'un créneau dans une file d'attente, donc limitez votre propre nombre de tâches en cours. Les passerelles de routage absorbent parfois plus, et j'ai eu 20 tâches simultanées toutes terminées, mais j'ai aussi été 429 sur la même configuration un autre jour. Ne construisez pas un planificateur qui suppose le nombre le plus élevé.

Mon URL vidéo MiniMax H3 renvoie 404 un jour plus tard. Le rendu est-il perdu ?

Non. L'URL a expiré, pas le rendu. Interrogez à nouveau le même task_id et la réponse contient une nouvelle URL, à tout moment dans la fenêtre de requête de 7 jours. Après 7 jours, l'enregistrement de la tâche lui-même n'est plus consultable, c'est pourquoi l'étape 2 persiste le task_id avant de faire quoi que ce soit d'autre.

J'ai cherché "hailuo ai video generator how to use" et je suis tombé sur un tutoriel MiniMax H3. Suis-je au bon endroit ?

Oui. Hailuo est l'application grand public et H3 est le nom du modèle utilisé par l'API. Même moteur. Si vous voulez un clip, utilisez le chemin du playground dans la section workflow ci-dessus, aucun code requis. Si vous voulez dix variantes ou une première image injectée depuis un autre modèle, les sept étapes sont pour vous.

Modèles récents

Une seule API pour toute l'IA multimédia.

Explorer tous les modèles