GPT-6 Sol et Claude Opus 5.5 disponiblesGPT-6 Sol à moitié prix par rapport à 5.6 Sol

API Wan 3.0 : text-to-video et image-to-video en Python

Un seul script, deux clips : le code, les durées réelles et le prix à la seconde d'Alibaba.

Kiki, OmniaKey COO8 minutes de lecture
Sur cette page

Wan 3.0 tourne sur Alibaba Cloud Model Studio sous wan3.0-video et sous wan3.0-video-prime, plus rapide. Chaque appel est asynchrone : créer une tâche, interroger l'ID, télécharger le MP4. Notre script Python a produit un clip de 5 secondes en 720P à partir d'un texte en 2 min 42 s, et un autre à partir d'une image fixe en 3 min 20 s, tous les deux avec du son.

  1. Mettez votre clé dans OMNIAKEY_API_KEY.
  2. Faites un POST sur https://api.omniakey.com/v1/media/tasks avec le modèle, l'opération, le prompt, les paramètres et un nouvel Idempotency-Key.
  3. Interrogez GET /v1/media/tasks/{id} jusqu'à ce que le statut indique succeeded, puis téléchargez assets[0].url tout de suite.

Existe-t-il une API Wan 3.0 officielle, et quel modèle choisir ?

Oui. Alibaba Cloud Model Studio est l'API officielle, avec wan3.0-video et wan3.0-video-prime (référence mise à jour le 15 octobre 2026). Son appel de création exige l'en-tête X-DashScope-Async: enable, et côté Python Alibaba passe par le SDK DashScope 2.0.1 ou plus récent.

Alibaba Model StudioOmniaKey
Les deux identifiantsOuiOui
En-tête asyncRequisNon
Lien vidéo valable24 heuresEnviron 1 heure, renouvelable
FacturationÀ la secondeÀ la seconde
PythonSDK DashScopeBibliothèque standard

Les deux identifiants acceptent le même corps de requête, et le modèle choisit le mode d'après les médias envoyés. Le script ci-dessous utilise wan3.0-video, et sa ligne MODEL suffit à changer. Nous n'avons pas exécuté Wan 3.0 Prime, que la doc OmniaKey décrit comme les mêmes capacités en environ la moitié du temps (vérifié le 31 octobre 2026).

Que faut-il avant le premier appel ?

Trois choses, et la première est la clé :

  1. Une clé API OmniaKey, exportée dans le shell :

    bash
    export OMNIAKEY_API_KEY="your-key"
    
  2. Python 3. Le script n'importe que la bibliothèque standard, python3 l'exécute tel quel.

  3. Pour l'image to video, une première image : un JPEG d'environ 1024 px de large, ou une URL HTTPS publique. Le script refuse un fichier de plus de 700 000 octets, parce que le Base64 ajoute un tiers et que le corps plafonne à 1 MiB (doc, vérifié le 31 octobre 2026).

Quels paramètres comptent ?

Sept champs font l'essentiel du travail, et chacun est une valeur dans parameters.

ParamètreRôleDéfaut
DuréeLongueur du clip, secondes5
RésolutionPalier de taille d'image1080P
RatioForme de l'imageadaptive
AudioPiste sonoreon
SeedIndice de reproductibilité-1
Extension du promptRéécrit votre prompton
FiligraneAjoute une marque d'angleoff

Le script règle la durée, la résolution et le ratio. Il demande du 720P alors que le défaut d'Alibaba est 1080P, ce qui coûte deux fois plus cher à la seconde aux tarifs catalogue.

À quoi ressemble le code Python ?

Le script ci-dessous a tourné sans modification le 31 octobre 2026 : bibliothèque standard uniquement, les deux modes, une ligne MODEL à changer.

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",
    ))

Ce que fait chaque partie :

  • run_task génère un nouvel Idempotency-Key pour chaque tâche. Renvoyer la même clé avec le même corps renvoie la tâche d'origine et ne facture jamais deux fois (doc, vérifié le 31 octobre 2026).
  • Il interroge toutes les 5 secondes pendant 15 minutes au maximum, puis lève TimeoutError.
  • Un timeout veut dire : interroger le même ID plus tard ; un nouvel envoi génère une autre clé, crée une seconde tâche et la facture.
  • Il télécharge la première URL d'asset tout de suite, parce que le lien signé est de courte durée.
  • image_to_video refuse une image de plus de 700 000 octets : le Base64 ajoute un tiers, et le corps plafonne à 1 MiB.
  • L'appel image règle le ratio sur adaptive, pour que le clip suive la forme de l'image fixe.

Ce qu'il a affiché :

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

Qu'ont produit les deux appels ?

Les deux fichiers sont revenus en MP4 de 5,04 secondes, 150 images à 30 fps, H.264, avec une piste AAC stéréo à 44,1 kHz.

Text to video : la forge

Quatre images du clip de la forge de Wan 3.0
Text to video, 5 s en 720P : images à 0,3, 2,2, 3,5 et 4,7 secondes.

Le clip suit le prompt : un forgeron en chemise sombre et tablier de cuir martèle un fer à cheval orange incandescent, des étincelles jaillissent à 2,2 secondes, et la caméra avance un peu. Le défaut est une marque de fabrique estampée en lettres brouillées sur l'enclume, alors que le prompt ne demandait aucun texte. Du lancement au fichier, il a fallu 2 min 42 s ; le MP4 fait 1280×720 pour 6,6 Mo.

Image to video : le bateau en papier

L'image fixe de départ et trois images du clip du bateau en papier de Wan 3.0
Image to video : l'image envoyée (en haut à gauche), puis le clip à 1,6, 3,5 et 4,7 secondes.

La première image était une image fixe produite avec Nano Banana 2.1, un bateau en papier rouge sur une flaque de pluie, redimensionnée en JPEG 1024×571 de 158 Ko et envoyée dans la requête comme URL de données. Le clip garde cette lumière de crépuscule et les pavés mouillés, fait dériver le bateau de gauche à droite comme demandé, crée des ondulations à 1,6 seconde et garde la caméra basse et fixe. Il est revenu en 1284×716 parce que adaptive a suivi la forme de l'image fixe, en 3 min 20 s pour 7,4 Mo.

Le son est-il activé, et « no music » fonctionne-t-il ?

Le son est activé par défaut. Gemini 3.8 Flash a décrit la piste de la forge comme un cliquetis métallique sans parole et sans musique, et celle du bateau en papier comme une mélodie de piano mélancolique et calme, alors que ce prompt finissait par « no music ». Le guide de prompt d'Alibaba (mis à jour le 16 octobre 2026) conseille d'écrire « No BGM » ou « No background music », et notre prompt n'utilisait ni l'un ni l'autre.

Avec "audio": false, le fichier ne contient qu'une piste vidéo : notre tâche lanterne de 2 secondes en 480P n'avait pas de piste sonore, et Alibaba facture pareil dans les deux cas.

ClipTempsTailleSon
Forge (texte)2 min 42 s1280×720Cliquetis, pas de musique
Bateau (image)3 min 20 s1284×716Piano malgré « no music »
Lanterne, audio off4 min 36 s854×480Aucune piste sonore

Le temps d'attente varie : la tâche de 2 secondes sans audio a pris 4 min 36 s, plus que les deux clips de 5 secondes en 720P. Pour la formulation des prompts, le guide de prompt Wan 3.0 donne la structure et des exemples.

Comment récupérer le fichier vidéo, et combien de temps les liens durent-ils ?

Interrogez GET /v1/media/tasks/{id} jusqu'à ce que le statut indique succeeded, failed ou canceled ; pendant l'exécution, il indique queued ou processing. Une tâche terminée renvoie une URL d'asset signée valable environ une heure (doc OmniaKey, vérifiée le 31 octobre 2026). Téléchargez-la tout de suite, puis interrogez de nouveau la tâche pour obtenir un lien frais quand l'ancien expire, car l'enregistrement dure 24 heures.

Le fichier est un MP4 en H.264 à 30 fps, et l'URL vidéo d'Alibaba elle-même dure 24 heures. Annuler une tâche Wan 3.0 n'arrête pas le rendu, et une tâche qui aboutit après une annulation est quand même facturée ; vérifiez donc la durée et la résolution avant d'envoyer.

Quelles erreurs allez-vous rencontrer ?

La plupart reviennent avant même qu'une tâche existe, et chacune a une solution dans la requête ou dans la clé.

  • 400 model_price_error — durée hors de 2 à 30 secondes. Notre test avec "duration": 1 a échoué en 0,9 s avec « media duration must be between 2 and 30 seconds » ; aucune tâche n'a été créée et rien n'a été facturé.
  • 400 missing_idempotency_key — pas d'en-tête Idempotency-Key. Ajoutez-en un, jusqu'à 255 caractères.
  • 409 idempotency_key_reused — même clé, corps différent. Générez une nouvelle clé pour chaque prompt.
  • 403 model_not_allowed — la clé n'a pas le droit d'appeler ce modèle. Vérifiez la valeur model, puis les réglages de la clé.
  • 403 avec un message de solde ou de plafond de dépense — solde bas ou plafond par clé. Rechargez ou relevez le plafond.
  • 404 task_not_found — ID faux, ou tâche de plus de 24 heures. Interrogez l'ID renvoyé par l'appel de création.
  • 409 task_state_conflict — la tâche est déjà finie, par exemple quand une annulation arrive après le succès. Lisez d'abord le statut.
  • 429 — trop de requêtes. OmniaKey ne publie pas de limites fixes, donc attendez avec un délai exponentiel et du jitter.
  • 503 no_available_channel — aucun canal pour cette opération, comme video to video. Passez par text to video ou image to video.
  • TimeoutError — toujours en cours après 15 minutes. Interrogez le même ID plus tard ; un nouvel envoi crée une seconde tâche et la facture.

Combien coûte un clip Wan 3.0 ?

Alibaba facture à la seconde de vidéo, et une requête échouée n'est pas facturée (page tarifs mise à jour le 29 octobre 2026). Le tableau donne les tarifs catalogue d'Alibaba à la seconde pour Singapour, vérifiés le 31 octobre 2026, d'après la page tarifs Model Studio d'Alibaba.

Modèle480P720P1080P
Wan 3.0$0.05$0.1$0.2
Wan 3.0 Prime$0.068$0.14$0.28

Un clip de 5 secondes en 720P coûte chez Alibaba $0.50 avec Wan 3.0 (5 × $0.1) et $0.70 avec Prime (5 × $0.14). Les trois tarifs Wan 3.0 portent la mention « Limited-time 30% off », et la page ne dit pas si les chiffres l'incluent. Le son activé ou non coûte pareil.

Le quota gratuit d'Alibaba est de 30 secondes de vidéo, entrée plus sortie, sur wan3.0-video à Singapour ; Prime n'en a pas. Chez Alibaba en Chine (Pékin), le modèle standard a des tarifs en dollars plus bas : $0.041256, $0.082513 et $0.165025 à la seconde en 480P, 720P et 1080P.

OmniaKey facture aussi à la seconde, avec les tarifs actuels sur les pages modèles Wan 3.0 et Wan 3.0 Prime.

Questions fréquentes

Combien de temps prend un appel ?

D'après Alibaba, une tâche prend en général 1 à 5 minutes, et la référence conseille d'interroger toutes les 15 secondes (vérifié le 31 octobre 2026). Nos trois tâches ont pris 2 min 42 s, 3 min 20 s et 4 min 36 s.

Comment couper le son ?

Mettez "audio": false dans parameters, et le MP4 arrive avec une piste vidéo seule, comme notre tâche lanterne. Le prix ne change pas.

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

Prenez wan3.0-video pour le tarif catalogue plus bas d'Alibaba et son quota gratuit de 30 secondes à Singapour, et Prime quand le délai compte davantage. OmniaKey décrit Prime comme les mêmes capacités en environ la moitié du temps.

Combien de temps le lien vidéo dure-t-il ?

Environ une heure sur OmniaKey, et une nouvelle interrogation de la tâche renvoie un lien frais tant que l'enregistrement dure 24 heures. L'URL vidéo d'Alibaba elle-même dure 24 heures.

Sources vérifiées

Modèles cités dans cet article

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

Articles similaires

Articles récents