Tutoriale
Come usare l'API reference-to-video di vidu-q4-preview (curl + Python)
Cosa costruirai
Avvia una chiamata reference-to-video sull'API asincrona /v1/tasks di hiapi, fondendo più fotogrammi di riferimento statici — e facoltativamente brevi clip audio — in un'unica scena da 3 a 16 secondi fino a 4K. Invierai una sola POST, poi eseguirai il polling (o riceverai un callback) finché l'attività non è completata, quindi scaricherai l'MP4.
Inizia ottenendo una chiave dalla console hiapi; ogni richiesta qui sotto usa Authorization: Bearer sk-<your-key>.
Reference-to-video vs image-to-video. Questo endpoint fonde da 1 a 15 fotogrammi statici — passa una foto di una persona, una di un ambiente e una di un oggetto, e le unirà in un'unica inquadratura. Se hai solo un singolo primo fotogramma da animare, usa invece vidu-q4-preview/image-to-video; accetta un singolo
image_urle rifiutareference_image_urls.
Richiesta minima funzionante (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": "参考图 1 中的人物走过参考图 2 中的咖啡馆,温暖的晨光,缓慢推镜",
"reference_image_urls": [
"https://your-cdn.com/person.jpg",
"https://your-cdn.com/cafe.jpg"
],
"resolution": "1080p",
"duration": 5,
"aspect_ratio": "16:9"
}
}'
La POST restituisce un id attività, non il video:
{ "code": 200, "data": { "taskId": "task_abc123" } }
Esegui il polling di GET /v1/tasks/<taskId> finché data.status non diventa success, poi leggi l'MP4 da 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 di output è temporaneo — porta un expireAt (scade dopo qualche giorno) — quindi scarica subito i byte, non fare hotlinking.
Python: invio → polling → download
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": (
"参考图 1 中的人物走过参考图 2 中的咖啡馆,"
"温暖的晨光,缓慢推镜"
),
"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}") # 400 错误会落到这里
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 punto da interiorizzare: un rendering fallito viene comunque restituito con HTTP 200, con la causa in data.status: "fail" e data.error.code / data.error.message. Una generazione fallita non è un errore HTTP, quindi dirama in base al corpo della risposta, non al codice di stato.
Aggiungere un riferimento vocale
Il campo vocale è reference_audio_urls — un array di massimo 3 clip audio. L'audio imposta il timbro; il tuo prompt continua a trasportare il testo e a guidare il lip-sync.
{
"model": "vidu-q4-preview/reference-to-video",
"input": {
"prompt": "参考图 1 中的主播用参考音频 1 的声音说:'欢迎回到频道。'",
"reference_image_urls": ["https://your-cdn.com/presenter.jpg"],
"reference_audio_urls": ["https://your-cdn.com/voice.mp3"],
"resolution": "1080p",
"duration": 8
}
}
Trappola sul nome del campo: l'intuitivo voice_reference_urls viene rifiutato (il validatore consente solo reference_audio_urls). Vedi la tabella di verifica qui sotto.
Produzione: callback e idempotenza
Per i flussi di lavoro server-side, di solito non vuoi mantenere attivo un ciclo di polling. Allega un callback di primo livello (allo stesso livello di input, non al suo interno) e hiapi invierà via POST l'attività completata al tuo URL:
{
"model": "vidu-q4-preview/reference-to-video",
"input": { "prompt": "...", "reference_image_urls": ["..."] },
"callback": { "url": "https://your-app.com/hooks/vidu", "when": "final" }
}
whensupporta solo"final"— riceverai una sola notifica allo stato terminale (successo o fallimento), mai notifiche di avanzamento intermedie.- Il corpo del callback è lo stesso payload restituito da
GET /v1/tasks/<id>. - La consegna viene ritentata più volte e può duplicarsi, quindi deduplica per
taskIde rendi il tuo handler idempotente. - Mantieni il polling come fallback per coprire le finestre in cui il tuo endpoint è temporaneamente irraggiungibile.
Salva il taskId nel momento in cui lo ottieni. Se il tuo poller incontra un errore di rete temporaneo, esegui nuovamente il polling usando l'id salvato — non reinviare mai, altrimenti pagherai per un secondo rendering.
Cosa ho verificato (contratto dello schema)
Ho sondato l'endpoint live con valori deliberatamente non validi (gratuito — le richieste rifiutate non vengono addebitate e i valori non validi non creano mai attività). Il validatore è severo e restituisce un oggetto piatto { "code": 400, "error_code": "INVALID_REQUEST", "message": ... }:
| Cosa invii | Cosa ricevi |
|---|---|
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 |
quattro reference_audio_urls |
reference_audio_urls: maxItems: got 4, want 3 |
reference_image_urls omesso |
missing required field "reference_image_urls" |
Quindi la struttura di input confermata è:
| Campo | Obbligatorio | Valori |
|---|---|---|
prompt |
Sì | Testo |
reference_image_urls |
Sì | Da 1 a 15 URL di immagini |
reference_audio_urls |
No | Massimo 3 URL audio (campo vocale) |
resolution |
No | 540p / 720p / 1080p / 2k / 4k |
duration |
No | Intero da 3 a 16 (secondi) |
aspect_ratio |
No | 16:9 / 9:16 / 1:1 / 4:3 / 3:4 |
duration è un intero (5), non una stringa — a differenza di alcuni altri modelli video su hiapi che si aspettano "6". Inviare chiavi extra è un errore bloccante (additional properties ... not allowed), quindi non copiare campi dallo schema image-to-video.
Note lato output prima di collegare il download
- Ogni clip porta una traccia audio AAC, anche se non hai inviato
reference_audio_urls. Il vocabolario sonoro nel prompt guida la traccia ambientale, quindi non dare per scontato che "nessun riferimento vocale = file muto". - L'output 4K di Vidu Q4 Preview viene consegnato in HEVC/H.265. È riproducibile nella maggior parte dei player nativi, ma molti browser non riescono a riprodurre inline un MP4 H.265 all'interno di un tag
<video>— se devi incorporarlo in una pagina web, ricodificalo in H.264. Le fasce inferiori restituiscono H.264 standard.
Modello di anteprima — tratta le enumerazioni come snapshot
vidu-q4-preview/reference-to-video è un modello in anteprima: è chiamabile oggi, ma non è elencato in /v1/models e lo schema di anteprima può cambiare. Prima di elaborazioni su larga scala, riesegui una volta la verifica con valori non validi (come la tabella sopra) per confermare che le enumerazioni siano ancora valide. La specifica autorevole è costituita dalle regole effettivamente applicate dal validatore più la pagina del modello.
Correlati
- Pagina del modello vidu-q4-preview/reference-to-video — specifica live e costo per richiesta.
- Ricette di prompt per il reference-to-video di Vidu Q4 Preview — cinque prompt pronti da copiare e le clip che hanno effettivamente generato, per darti idee su cosa mettere nel
prompt(questa guida copre la chiamata; quella pagina copre il prompt). - vidu-q4-preview/image-to-video — endpoint per l'animazione di un singolo fotogramma; usalo quando hai un solo fotogramma statico invece di un set di immagini da fondere.
- Prezzi hiapi — il reference-to-video è fatturato al secondo e aumenta con la risoluzione.
Domande frequenti
Reference-to-video è uguale a image-to-video?
No. Il reference-to-video fonde da 1 a 15 fotogrammi statici (facoltativamente più fino a 3 clip audio) in un'unica inquadratura composita; l'image-to-video anima un singolo primo fotogramma. Sono endpoint separati con input diversi — il reference-to-video rifiuta persino il campo image_url dell'image-to-video, e viceversa.
Come aggiungo la voce?
Allega reference_audio_urls (massimo 3 clip) e indicalo nel prompt ("...con la voce del riferimento audio 1"). Il nome del campo deve essere esattamente reference_audio_urls; voice_reference_urls e altri nomi vengono rifiutati.
Qual è la clip più lunga che posso richiedere?
16 secondi. duration è un intero da 3 a 16.
Devo per forza fare polling?
No — allega callback: { "url": ..., "when": "final" } e riceverai una notifica allo stato terminale. Deduplica per taskId e mantieni il polling come fallback.
Quanto costa una clip 4K?
La fatturazione è al secondo e la tariffa cresce con la risoluzione, con il 4K come fascia massima — vedi prezzi hiapi. Il flusso di lavoro pratico è iterare prima a 720p e ri-renderizzare a 4k solo le versioni finali che mantieni.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato