Tutoriel
Comment utiliser l'API vidu-q4-preview reference-to-video (curl + Python)
Ce que vous allez construire
Lancez un appel reference-to-video sur l'API asynchrone /v1/tasks de hiapi, en fusionnant plusieurs images fixes de référence — et éventuellement des extraits audio — en une séquence de 3 à 16 secondes, jusqu'à 4K. Vous soumettez un seul POST, puis vous interrogez (ou recevez un callback) jusqu'à ce que la tâche soit terminée, puis vous téléchargez le MP4.
Commencez par obtenir une clé depuis la console hiapi ; chaque requête ci-dessous utilise Authorization: Bearer sk-<your-key>.
Reference-to-video vs image-to-video. Ce endpoint fusionne 1 à 15 images fixes — passez une image fixe de personnage, une image fixe de décor, une image fixe d'objet, et il les compose en un seul plan. Si vous n'avez qu'une seule première image à animer, utilisez plutôt vidu-q4-preview/image-to-video ; il accepte un seul
image_urlet rejettereference_image_urls.
Requête minimale exécutable (curl)
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "vidu-q4-preview/reference-to-video",
"input": {
"prompt": "le personnage de l'image de référence 1 traverse le café de l'image de référence 2, lumière chaude du matin, travelling avant lent",
"reference_image_urls": [
"https://your-cdn.com/person.jpg",
"https://your-cdn.com/cafe.jpg"
],
"resolution": "1080p",
"duration": 5,
"aspect_ratio": "16:9"
}
}'
Ce POST renvoie un id de tâche, pas la vidéo :
{ "code": 200, "data": { "taskId": "task_abc123" } }
Interrogez GET /v1/tasks/<taskId> jusqu'à ce que data.status vaille success, puis récupérez le MP4 depuis data.output[0].url :
curl https://api.hiapi.ai/v1/tasks/task_abc123 \
-H "Authorization: Bearer sk-<your-key>"
{
"code": 200,
"data": {
"status": "success",
"output": [
{ "url": "https://temp.hiapi.ai/....mp4", "expireAt": 1760000000 }
]
}
}
L'URL de sortie est temporaire — elle porte un expireAt (expiration après quelques jours) — donc téléchargez immédiatement les octets, ne faites pas de hotlink.
Python : soumettre → interroger → télécharger
import time
import requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {
"Authorization": "Bearer sk-<your-key>",
"Content-Type": "application/json",
}
def submit() -> str:
payload = {
"model": "vidu-q4-preview/reference-to-video",
"input": {
"prompt": (
"le personnage de l'image de référence 1 traverse le café de l'image de référence 2, "
"lumière chaude du matin, travelling avant lent"
),
"reference_image_urls": [
"https://your-cdn.com/person.jpg",
"https://your-cdn.com/cafe.jpg",
],
"resolution": "1080p",
"duration": 5,
"aspect_ratio": "16:9",
},
}
r = requests.post(BASE, json=payload, headers=HEADERS, timeout=60)
r.raise_for_status()
body = r.json()
task_id = (body.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError(f"submit rejected: {body}") # les erreurs 400 arrivent ici
return task_id
def wait(task_id: str, timeout_s: int = 600, interval: int = 5) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=40)
task = r.json().get("data") or {}
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"task failed: {task.get('error')}")
time.sleep(interval)
raise TimeoutError(task_id)
def download(url: str, path: str) -> None:
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1 << 16):
f.write(chunk)
task_id = submit()
url = wait(task_id)
download(url, "out.mp4")
Un point à bien intégrer : un rendu échoué renvoie tout de même un HTTP 200, la raison se trouvant dans data.status: "fail" et data.error.code / data.error.message. Un échec de génération n'est pas une erreur HTTP : branchez donc sur le corps de la réponse, pas sur le code de statut.
Ajouter une référence vocale
Le champ vocal est reference_audio_urls — un tableau de 3 extraits audio maximum. L'audio définit le timbre ; votre prompt porte toujours le texte et pilote la synchronisation labiale.
{
"model": "vidu-q4-preview/reference-to-video",
"input": {
"prompt": "le présentateur de l'image de référence 1 dit avec la voix de l'audio de référence 1 : « Bienvenue sur la chaîne. »",
"reference_image_urls": ["https://your-cdn.com/presenter.jpg"],
"reference_audio_urls": ["https://your-cdn.com/voice.mp3"],
"resolution": "1080p",
"duration": 8
}
}
Piège de nommage : le champ intuitif voice_reference_urls est rejeté (le validateur n'autorise que reference_audio_urls). Voir le tableau de sondage ci-dessous.
Production : callbacks et idempotence
Pour les workflows serveur, vous ne voulez généralement pas maintenir une boucle de polling. Ajoutez un callback au niveau supérieur (au même niveau que input, pas à l'intérieur), et hiapi enverra en POST la tâche terminée à votre URL :
{
"model": "vidu-q4-preview/reference-to-video",
"input": { "prompt": "...", "reference_image_urls": ["..."] },
"callback": { "url": "https://your-app.com/hooks/vidu", "when": "final" }
}
whenn'accepte que"final"— vous ne recevez qu'une seule notification à l'état terminal (succès ou échec), jamais de notification de progression intermédiaire.- Le corps du callback est identique au payload renvoyé par
GET /v1/tasks/<id>. - La livraison est retentée plusieurs fois et peut être dupliquée : dédupliquez donc par
taskIdet rendez votre gestionnaire idempotent. - Conservez le polling comme filet de sécurité pour couvrir les fenêtres où votre endpoint est brièvement injoignable.
Enregistrez le taskId dès que vous l'obtenez. Si votre poller rencontre une erreur réseau transitoire, réinterrogez l'id déjà enregistré — ne soumettez jamais à nouveau, sinon vous paierez un second rendu.
Ce que j'ai vérifié (contrat de schéma)
J'ai sondé le endpoint en direct avec des valeurs volontairement invalides (gratuit — les requêtes rejetées ne sont pas facturées, et une valeur invalide ne crée jamais de tâche). Le validateur est strict, renvoyant un objet plat { "code": 400, "error_code": "INVALID_REQUEST", "message": ... } :
| Ce que vous envoyez | Ce qui est renvoyé |
|---|---|
resolution: "9999p" |
resolution: value must be one of '540p', '720p', '1080p', '2k', '4k' |
duration: 999 |
duration: maximum: got 999, want 16 |
aspect_ratio: "banana" |
aspect_ratio: value must be one of '16:9', '9:16', '1:1', '4:3', '3:4' |
voice_reference_urls: [...] |
additional properties 'voice_reference_urls' not allowed |
quatre reference_audio_urls |
reference_audio_urls: maxItems: got 4, want 3 |
omission de reference_image_urls |
missing required field "reference_image_urls" |
La structure d'entrée confirmée est donc :
| Champ | Obligatoire | Valeurs |
|---|---|---|
prompt |
oui | texte |
reference_image_urls |
oui | 1 à 15 URL d'images |
reference_audio_urls |
non | 3 URL audio maximum (champ vocal) |
resolution |
non | 540p / 720p / 1080p / 2k / 4k |
duration |
non | entier 3–16 (secondes) |
aspect_ratio |
non | 16:9 / 9:16 / 1:1 / 4:3 / 3:4 |
duration est un entier (5), pas une chaîne — contrairement à certains autres modèles vidéo de hiapi qui attendent "6". Passer une clé supplémentaire est une erreur bloquante (additional properties ... not allowed), donc ne copiez pas les champs du schéma image-to-video.
Points d'attention côté sortie avant de brancher le téléchargement
- Chaque séquence porte une piste audio AAC, même si vous n'avez pas envoyé de
reference_audio_urls. Le vocabulaire sonore du prompt pilote la piste d'ambiance, donc ne supposez pas « pas de référence vocale = fichier muet ». - La sortie 4K de Vidu Q4 Preview est livrée en HEVC/H.265. Elle est lisible dans la plupart des lecteurs natifs, mais de nombreux navigateurs ne peuvent pas lire un MP4 H.265 en ligne dans une balise
<video>— si vous l'intégrez dans une page web, réencodez en H.264. Les niveaux inférieurs renvoient du H.264 standard.
Modèle de prévisualisation — traitez les énumérations comme un instantané
vidu-q4-preview/reference-to-video est un modèle de prévisualisation : il est appelable aujourd'hui, mais n'est pas listé dans /v1/models, et son schéma de prévisualisation peut évoluer. Avant de traiter en gros volume, relancez une fois le sondage avec valeurs invalides (comme dans le tableau ci-dessus) pour confirmer que les énumérations sont toujours valides. La spécification de référence, ce sont les règles réellement appliquées par le validateur, complétées par la page du modèle.
Voir aussi
- Page du modèle vidu-q4-preview/reference-to-video — spécification en direct et coût par requête.
- Recettes de prompt pour Vidu Q4 Preview reference-to-video — cinq prompts prêts à copier et les séquences qu'ils génèrent réellement, pour vous donner des idées sur ce qu'il faut mettre dans
prompt(ce guide couvre l'appel ; cette page couvre le prompt). - vidu-q4-preview/image-to-video — endpoint d'animation d'une seule image ; utilisez-le lorsque vous n'avez qu'une seule image fixe au lieu d'un ensemble à fusionner.
- Tarification hiapi — le reference-to-video est facturé à la seconde et augmente avec la résolution.
Questions fréquentes
Le reference-to-video est-il identique à l'image-to-video ?
Non. Le reference-to-video fusionne 1 à 15 images fixes (avec éventuellement jusqu'à 3 extraits audio) en un seul plan composite ; l'image-to-video anime une seule première image. Ce sont des endpoints distincts avec des entrées différentes — le reference-to-video rejette même le champ image_url de l'image-to-video, et inversement.
Comment ajouter une voix ?
Ajoutez reference_audio_urls (3 extraits maximum) et précisez-le dans le prompt (« ... avec la voix de l'audio de référence 1 »). Le nom du champ doit être exactement reference_audio_urls ; voice_reference_urls et les autres noms sont rejetés.
Quelle est la séquence la plus longue que je peux demander ?
16 secondes. duration est un entier de 3 à 16.
Dois-je forcément faire du polling ?
Non — ajoutez callback: { "url": ..., "when": "final" } pour recevoir une notification unique à l'état terminal. Dédupliquez par taskId et conservez le polling comme filet de sécurité.
Combien coûte une séquence 4K ?
La facturation est à la seconde, le tarif augmente avec la résolution, et le 4K est le niveau le plus élevé — voir la tarification hiapi. Le workflow pratique consiste à itérer d'abord en 720p, puis à ne refaire le rendu en 4k que pour les versions finales retenues.
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