Tutorial
So rufen Sie hailuo-2.3-fast/image-to-video über die HiAPI API auf: curl und Python in der Praxis
Die erste lauffähige Anfrage für die schnelle, kostengünstige Bild-zu-Video-Stufe – von der Modell-ID bis zum heruntergeladenen MP4
Was hailuo-2.3-fast/image-to-video für Sie tun kann
hailuo-2.3-fast/image-to-video ist die auf Geschwindigkeit optimierte Stufe in der Bild-zu-Video-Produktlinie von HiAPI. Sie geben ihm ein statisches Bild und einen Text-Prompt, der die gewünschte Bewegung beschreibt, und es liefert einen kurzen Videoclip zurück, der sich von diesem Bild aus vorwärts bewegt. Das „fast“ in der Modell-ID ist der Punkt: Diese Stufe tauscht einen Teil der Detailtreue schwererer Videomodelle gegen geringere Latenz und niedrigere Kosten pro Rendering ein, was sie ideal für Iterationen und die Serienproduktion macht.
Wählen Sie dieses Modell, wenn Sie eine brauchbare erste lauffähige Version eines Clips brauchen und nicht ein „Hauptvisual“ als Endprodukt: Storyboard-Vorschauen, sozial-taugliche Loop-Videos, Hintergrundbewegungsmaterial oder die Entwurfsphase in einer Pipeline, in der ein schwereres Modell das finale Rendering übernimmt. Wenn Ihre Ausgabe lange Einstellungen, komplexe Kameraführung oder strikte Identitätskonsistenz über viele Frames hinweg erfordert, überlassen Sie diese Aufgaben einer schwereren Stufe – und behalten Sie dabei dieselbe Anfragestruktur bei, sodass ein Wechsel nur eine Konfigurationsänderung ist.
Alles im Folgenden dreht sich um eine Anfrage, die Sie wirklich ausführen können. Das Ziel ist, dass eine MP4-Datei auf der Festplatte landet, nicht ein Screenshot einer erfolgreichen Antwort.
Die Anfrage auf einen Blick
Ein Video-Rendering dauert Sekunden bis Minuten, daher ist die API asynchron: Sie übermitteln eine Aufgabe, erhalten eine Aufgabenkennung und fragen diese Aufgabe dann ab, bis sie den Abschluss meldet und die Ausgabe liefert. Das bedeutet, jede Integration hat zwei Phasen – Übermittlung und Abfrage – und nur die Übermittlungsphase unterscheidet sich je nach Modell.
Die Übermittlungsanfrage enthält vier von Ihnen kontrollierte Elemente:
- Endpunkt und Methode – ein
POST-Request an den Video-Generierungs-Endpunkt von HiAPI. - Authentifizierungsheader – Ihr Schlüssel in der Form
Authorization: Bearer $HIAPI_API_KEY. Legen Sie den Schlüssel in einer Umgebungsvariablen ab und fügen Sie ihn niemals inline in den übermittelten Code ein. - Modell-ID – der Literal-String
hailuo-2.3-fast/image-to-video. Er wählt die Stufe aus. - Eingabe – ein
prompt, der die Bewegung beschreibt, sowie ein Startbild. Das Bild wird als öffentlich erreichbare URL oder als Data-URI bereitgestellt, je nachdem, welche Form Ihr Konto an diesem Endpunkt akzeptiert; mit einer URL zu beginnen ist am einfachsten. Der JSON-Request-Body wird mitContent-Type: application/jsongesendet.
Legen Sie diese vier Felder an einer Stelle in Ihrer Codebasis ab – ein Dictionary, eine Konfigurationsdatei, ein durch Umgebungsvariablen gesteuerter Builder –, sodass ein späterer Wechsel zu einem anderen HiAPI-Videomodell nur eine Zeile ändert statt einer Neufassung bedarf. Die Antwort ist ein kleines JSON-Envelope, in dem die Aufgabenkennung das einzige Feld ist, das Sie persistieren müssen; der Rest sind Status-Metadaten.
Die funktionierende curl-Anfrage
Das ist der vollständige Übermittlungsschritt. Ersetzen Sie die Bild-URL durch eine Adresse, auf die Ihr Konto zugreifen kann, und exportieren Sie zuerst Ihren Schlüssel.
export HIAPI_API_KEY="your-key-here"
curl -sS -X POST "https://api.hiapi.ai/v1/video/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "hailuo-2.3-fast/image-to-video",
"prompt": "slow push in, gentle breeze moving the fabric, film grain",
"image": "https://example.com/first-frame.jpg"
}'
Die erfolgreiche Antwort ist JSON mit der Aufgabenkennung, üblicherweise in der Form {"id": "task_...", "status": "queued"}. Die genaue Form der Envelope-Felder kann sich ändern, daher defensiv parsen: Lesen Sie die Aufgaben-ID über den Schlüssel, nicht über die Position, und behandeln Sie unbekannte Felder als informative Inhalte.
Wenn Sie debuggen, fügen Sie -i hinzu, um die HTTP-Statuszeile zu sehen. 401 bedeutet fast immer, dass der Authentifizierungsheader fehlt oder die Variable zu einem leeren String expandiert wurde – führen Sie echo $HIAPI_API_KEY aus, bevor Sie den Request-Body verdächtigen. 400 deutet meist auf den Body hin: nicht erreichbare Bild-URL, fehlendes model oder Feldnamen, die nicht zum Endpunkt passen.
Kopieren Sie die zurückgegebene Aufgaben-ID in eine Shell-Variable, sodass spätere Schritte sie nicht erneut eingeben müssen:
TASK_ID=$(curl -sS -X POST "https://api.hiapi.ai/v1/video/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"hailuo-2.3-fast/image-to-video","prompt":"slow push in","image":"https://example.com/first-frame.jpg"}' \
| python -c 'import sys,json; print(json.load(sys.stdin)["id"])')
echo "$TASK_ID"
Dieselbe Anfrage in Python
Die Python-Version hält den Request-Body bytegenau identisch zu curl, sodass curl- und Python-Ergebnisse direkt verglichen werden können, wenn Sie einen Bug verfolgen.
import os
import requests
API_BASE = "https://api.hiapi.ai/v1"
MODEL = "hailuo-2.3-fast/image-to-video"
def submit_video(prompt: str, image_url: str) -> str:
resp = requests.post(
f"{API_BASE}/video/generations",
headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
json={
"model": MODEL,
"prompt": prompt,
"image": image_url,
},
timeout=60,
)
resp.raise_for_status()
return resp.json()["id"]
Drei wichtige Gewohnheiten hier. os.environ[...] (statt .get) schlägt laut fehl, wenn eine Variable fehlt – und genau so möchten Sie scheitern. Ein expliziter timeout verhindert, dass ein hängender Socket einen Worker-Prozess unbegrenzt belegt. Und raise_for_status() verwandelt einen 4xx-Response-Body in eine protokollierbare Exception statt in einen stillen KeyError, den die nächste Zeile wegen der fehlenden ID wirft.
Diese Funktion gibt bewusst nur die Aufgaben-ID zurück. Übermittlung und Warten sind getrennte Anliegen; mischt man sie, wird die Polling-Schleife schwer testbar. Beachten Sie, dass die Modell-ID nur einmal auf Modulebene vorkommt – das ist die einzige Stelle, die Sie ändern müssen, wenn Sie zu einem anderen HiAPI-Videomodell wechseln.
Die Aufgabe abfragen, bis das Video bereit ist
Die Statusprüfung ist ein GET-Request an die Aufgabenressource. Aufgaben in der Warteschlange oder in Ausführung liefern einen nicht-terminalen Status; abgeschlossene Aufgaben liefern einen terminalen Status samt Ausgabe.
import time
def wait_for_video(task_id: str, timeout: float = 600.0) -> dict:
deadline = time.monotonic() + timeout
delay = 2.0
url = f"{API_BASE}/video/generations/{task_id}"
while True:
r = requests.get(
url,
headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
task = r.json()
if task.get("status") == "succeeded":
return task
if task.get("status") in {"failed", "cancelled"}:
raise RuntimeError(f"task {task_id} ended: {task}")
if time.monotonic() >= deadline:
raise TimeoutError(f"task {task_id} still {task.get('status')} after {timeout}s")
time.sleep(delay)
delay = min(delay * 1.5, 15.0)
Dies ist eine Retry-Schleife, kein festes Sleep. Das Backoff beginnt bei zwei Sekunden und wächst bis zu einer Obergrenze von fünfzehn Sekunden, sodass kurze Renderings schnell fertig werden und lange Renderings den Endpunkt nicht bombardieren. Die Frist wird vor dem Schlafen geprüft, sodass die Gesamt-Wall-Clock-Zeit im Rahmen bleibt statt um ein Intervall zu überschreiten. Verwenden Sie time.monotonic() statt time.time(), damit Uhrzeitanpassungen die Schleife nicht verlängern.
Behandeln Sie failed und cancelled anders als „weiter warten“: Sie sind terminal, aber nicht erfolgreich. Wenn das passiert, protokollieren Sie das gesamte Aufgabenobjekt – das ist die einzige Diagnose, die Sie bekommen, und einen Fehler allein anhand einer ID zu reproduzieren ist sehr mühsam. Behandeln Sie unbekannte Status-Strings als nicht-terminal und führen Sie die Abfrage fort, damit neue Zwischenzustände Ihren Worker nicht zum Absturz bringen.
Die Ausgabe herunterladen und verarbeiten
Eine abgeschlossene Aufgabe trägt eine oder mehrere Ausgabe-URLs. Holen Sie die Bytes und schreiben Sie sie dorthin, wo Sie die Kontrolle haben.
def download_video(task: dict, dest: str) -> str:
url = task["output"][0]["url"] if isinstance(task.get("output"), list) else task["output"]["url"]
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(dest, "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 20):
f.write(chunk)
return dest
Streamen Sie den Download, anstatt .content aufzurufen; ein Video kann so groß sein, dass das vollständige Zwischenspeichern im Speicher für einen Worker, der mehrere Aufgaben verarbeitet, verschwenderisch ist. Die genaue Form der Ausgabe-URL kann je nach Modellstufe leicht variieren, prüfen Sie daher vor dem Indexieren, ob eine Liste vorliegt – die obige Verzweigung deckt beide Fälle ab.
Wichtige Regel: Behandeln Sie die zurückgegebene URL als kurzlebigen Handle, nicht als Speicher. Sobald eine Aufgabe erfolgreich ist, kopieren Sie die Datei in Ihren eigenen Bucket oder lokalen Pfad und bedienen Sie von dort. Die URL in einer Datenbank zu persistieren und Tage später abzurufen, ist der Grund, warum Sie 403 und ein leeres Dashboard bekommen. Für Objektspeicher kann dieselbe Streaming-Byte-Schleife direkt Ihre Upload-Methode des Clients speisen – wenn Ihr SDK dateiähnliche Objekte akzeptiert, brauchen Sie keine temporäre Zwischendatei.
Praktische Tipps und häufige Fallstricke
- Authentifizierungsheader statt Query-Parameter verwenden. Der Schlüssel gehört in
Authorization: Bearer .... Ein Schlüssel, der in die URL geklebt wird, ist ein Schlüssel in den Zugriffslogs. - Erreichbarkeit des Bildes ist wichtiger als Korrektheit des Bildes. Ein
400bei der Übermittlung liegt weit häufiger an einer URL, die die API nicht abrufen kann – localhost, private Buckets, Hotlink-Schutz-Hosts, ablaufende Links – als an einem problematischen Prompt. Testen Sie die URL in einer frischen Browser-Session, bevor Sie irgendetwas anderes debuggen. - Content-Type des Request-Bodys. Senden Sie JSON mit
Content-Type: application/json. Vergisst man bei curl das-H, parst der Server Ihren Body möglicherweise gar nicht. - Zu enges Polling. Ein
while Trueohne Schlaf führt zu Rate-Limiting und lässt das Rendering nicht schneller fertig werden. Backoff plus Frist ist der ganze Trick. - Nirgends Timeouts. Setzen Sie Timeouts bei Submit-, Polling- und Download-Aufrufen. Fehlende Timeouts verwandeln einen langsamen Anbieter in eine hängende Warteschlange in Ihrem eigenen System.
- Prompts beschreiben Bewegung, nicht das Bild. Beschreiben Sie, was sich von Frame zu Frame ändert – Kamerabewegung, Aktionen des Motivs, Umgebungselemente – und halten Sie es kurz. Das statische Bild erneut zu beschreiben bringt keinen Gewinn.
- Eine Konfiguration, mehrere Modelle. Halten Sie Modell-ID, Prompt und Bild-Eingabe in demselben Payload-Builder. Der Wechsel von dieser schnellen Stufe zu einer schwereren erfordert dann nur die Änderung eines Strings.
Der schnellste Weg, Ihr Setup Ende-zu-Ende zu validieren: Führen Sie die curl-Übermittlung aus, fügen Sie die Aufgaben-ID in die Polling-Schleife ein und bestätigen Sie, dass eine MP4-Datei auf der Festplatte landet – sobald das funktioniert, ist der Rest Verpackungsarbeit.
Ähnliche Artikel
Alle Artikel ansehen →-
Tutorial
So rufen Sie hailuo-2.3/text-to-video über die HiAPI API auf: curl, Python und lauffähige Anfragebeispiele
-
Tutorial
Kandinsky 6.0 Pro Text-zu-Video auf HiAPI: curl- und Python-Tutorial
Eine anfrageorientierte praktische Demonstration: Aufbau des Aufrufs vom Prompt zum Videoclip, Absenden der Anfrage, Abfragen des Fertigstellungsstatus und Herunterladen des Ergebnisses
-
Tutorial
So nutzt du kling-4.0/text-to-video über die HiAPI-API: curl, Python und ein lauffähiges Anforderungsbeispiel
Ein praxisnaher Leitfaden für Entwickler: filmische Prompts, synchrones Audio, asynchrones Polling und Download der Ausgabe