HiAPI
Blog

Tutorial

So rufen Sie veo-3.1-fast/image-to-video über die HiAPI-API auf (curl + Python)

Eine lauffähige Request-Demo: Eingabe des ersten Frames, natives Audio, asynchrones Polling und Download der Ausgabe

Nov 3, 2026
深靛蓝底色上三层嵌套的扁平折线箭头依次向右推进,前缘为杏橙色,像信号流程图,是教程文章的封面图。

Was dieses Tutorial baut und was Sie vorher vorbereiten müssen

Dieses Tutorial zeigt eine vollständig lauffähige HiAPI-Integration mit veo-3.1-fast/image-to-video: Sie senden ein Bild als ersten Frame und einen Prompt, erhalten einen asynchronen Job, poll'en ihn bis zum Abschluss und laden anschließend das erzeugte Video samt nativem Audio herunter.

Am Ende des Tutorials verfügen Sie über zwei äquivalente Implementierungen – einen curl-Befehl, der im Terminal läuft, und einen Python-Client, den Sie in ein Skript oder einen Dienst einbetten können – beide rufen denselben HiAPI-Endpunkt auf.

Voraussetzungen

Bevor Sie beginnen, halten Sie Folgendes bereit:

  • Einen HiAPI-API-Schlüssel. Legen Sie ihn nicht in der Versionsverwaltung ab. In den folgenden Beispielen wird er aus einer Umgebungsvariable gelesen, statt direkt eingefügt zu werden.
  • Eine HiAPI-Basis-URL. Verwenden Sie die Adresse, die in Ihrem HiAPI-Dashboard oder der API-Referenz angezeigt wird; speichern Sie sie als Variable, damit sie nur einmal konfiguriert werden muss.
  • Ein Bild für den ersten Frame. Eine öffentlich erreichbare URL ist die einfachste Eingabe. Verwenden Sie ein echtes Bild, das Sie verwenden dürfen, in einem gängigen Format wie JPEG oder PNG.
  • Einen HTTP-Client. Für diese Demo genügt curl. Für die Python-Version benötigen Sie nur requests – kein Anbieter-SDK.
  • Ein lokales Verzeichnis zum Speichern des heruntergeladenen Videos.

Umgebung einrichten

Exportieren Sie Schlüssel und Basis-URL, damit sowohl das Shell- als auch das Python-Beispiel sie wiederverwenden können:

export HIAPI_API_KEY="your-api-key"
export HIAPI_BASE_URL="https://api.hiapi.ai"
export FIRST_FRAME_URL="https://example.com/your-first-frame.jpg"

Der genaue Endpunktpfad und die Parameternamen von veo-3.1-fast/image-to-video sind in der HiAPI-API-Referenz neben dem Modelleintrag dokumentiert – sehen Sie dort in der Liste der verbindlichen Felder nach, statt sich auf anderswo kopierte Ausschnitte zu verlassen. Dieses Tutorial konzentriert sich auf die Request-Struktur und den Workflow; diese bleiben gleich, auch wenn die Felddetails gegen die Dokumentation bestätigt werden müssen.

Merken Sie sich schon jetzt einen Punkt: Dies ist ein aufgabenbasiertes Modell, kein synchrones Modell. Sie erhalten das Video nicht direkt in der Submit-Antwort. Sie erhalten eine Aufgabenkennung, und das Video trifft später ein.

Aufbau einer Image-to-Video-Anfrage

Bevor Sie Code schreiben, hilft es zu verstehen, was Sie tatsächlich senden und was zurückkommt. Die Bild-zu-Video-Generierung ist rechenintensiver als Textgenerierung, daher modelliert die API sie als Hintergrundaufgabe.

Eingabe: Prompt und erster Frame

Eine Anfrage an veo-3.1-fast/image-to-video hat konzeptionell zwei Teile:

  • Einen Text-Prompt, der Bewegung, Kameravehalten und Szenenabsicht beschreibt – also was nach dem ersten Frame geschehen soll.
  • Ein Referenzbild, das den ersten Frame der Ausgabe verankert. Genau das unterscheidet Image-to-Video von Text-to-Video: Das Modell setzt Ihr Bild fort, statt einen Eröffnungsframe aus dem Nichts zu erzeugen.

Der Modellname selbst verrät den Kompromiss: Die fast-Variante ist auf schnellere Durchlaufzeiten für Image-to-Video-Aufgaben optimiert, was sie ideal für Iterationen und Pipelines macht, bei denen Latenz wichtiger ist als höchste Wiedergabetreue.

Die erzeugte Ausgabe enthält natives Audio, sodass die endgültige Datei ein vollständiges Video mit Ton ist und kein stummer Clip, der separat vertont werden muss.

Lebenszyklus einer Aufgabe

Da die Generierung Zeit braucht, gliedert sich die Interaktion in drei Phasen:

  1. Einreichen. Sie POSTen Prompt und Bild an den Modellendpunkt. Die Antwort ist eine knappe Bestätigung mit einer Aufgabenkennung – kein Video.
  2. Polling. Mit dieser Kennung rufen Sie wiederholt per GET den Aufgabenstatus ab, bis er Abschluss (oder Fehlschlag) meldet.
  3. Abrufen. Nach Abschluss verweist die Aufgabenantwort auf das erzeugte Video, das Sie herunterladen und speichern.

Diese Phasen im Code getrennt zu halten, ist die wichtigste strukturelle Entscheidung. Mischt man sie, werden Wiederholungsversuche, Timeouts und Fehlerbehandlung unübersichtlich.

Wie eine korrekt formatierte Einreichung aussieht

Unabhängig von der genauen Serialisierung sollte eine Anfrage Folgendes enthalten:

  • Die Modellkennung veo-3.1-fast/image-to-video.
  • Ihren Prompt-Text.
  • Die Referenz auf das Bild des ersten Frames.
  • Authentifizierung über den API-Schlüssel im Request-Header.

Alles Weitere – optionale Parameter, Standardwerte, Ausgabeauflösungsoptionen – gehört in die HiAPI-API-Referenz zu diesem Modell. Lesen Sie sie einmal und legen Sie die bestätigten Feldnamen in Konstanten ab, statt sie über die Codebasis zu verstreuen.

Behandeln Sie die Submit-Antwort wie einen Beleg. Protokollieren Sie sie, speichern Sie die Aufgaben-ID und fahren Sie mit dem Polling fort.

Aufruf mit curl durchführen

Reichen wir eine Aufgabe ein. Der folgende Befehl sendet einen JSON-Body mit Prompt und Bild des ersten Frames an den Modellendpunkt auf HiAPI und authentifiziert sich mit dem Schlüssel aus der Umgebung.

curl -sS -X POST "$HIAPI_BASE_URL/v1/videos/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-fast/image-to-video",
    "prompt": "Slow dolly forward through a sunlit forest path, leaves drifting, soft birdsong ambience",
    "image": "'"$FIRST_FRAME_URL"'"
  }'

Einige Hinweise zu diesem Befehl:

  • Der Endpunktpfad und der Feldname image sollten gegen die HiAPI-API-Referenz für veo-3.1-fast/image-to-video geprüft werden; weichen sie ab, ersetzen Sie sie durch die verbindlichen Werte. Die Struktur hier – Modell, Prompt, Bild – ist entscheidend.
  • Der Prompt hat echten Einfluss. Beschreiben Sie Bewegung und Kamerafahrt ausdrücklich („langsames Vorwärts-Dolly“, „Blätter treiben“) und nennen Sie die gewünschte Audioatmosphäre, denn das Modell erzeugt Bild und natives Audio zugleich.
  • -sS hält die Ausgabe ruhig, zeigt aber weiterhin Fehler – genau das, was man in einer Terminal-Demo möchte.
  • Das Bild wird als URL-String übergeben. Wenn Sie lieber Bytes hochladen möchten, sehen Sie in der Referenz nach den unterstützten Eingabeformen, statt zu raten.

Submit-Antwort lesen

Eine erfolgreiche Einreichung liefert ein kompaktes JSON-Objekt mit Aufgabenkennung und Status – ungefähr so:

{
  "id": "job_abc123",
  "status": "queued"
}

Die Feldnamen sind nur Beispiele; bestätigen Sie sie anhand der tatsächlichen Antwort. Wichtig ist, dass Sie jetzt eine ID zum Pollen haben und einen Status, der nicht „fertiges Video“ bedeutet.

Fangen Sie die ID in der Shell ab, damit die nächsten Schritte einfacher werden:

JOB_ID="job_abc123"

Wenn Sie einen Authentifizierungsfehler erhalten, fehlt Ihr Schlüssel oder ist falsch formatiert. Validierungsfehler bedeuten meist, dass der Request-Body nicht zum dokumentierten Schema passt – prüfen Sie zuerst Feldnamen und Typen. Eine Rate-Limit-Antwort bedeutet, dass Sie zu häufig senden; legen Sie eine Pause ein, statt in einer engen Schleife zu wiederholen.

Dieselbe Anfrage in Python

Folgend die äquivalente Einreichung in Python. Sie nutzt nur requests, liest die Konfiguration aus Umgebungsvariablen und trennt den Einreichungsschritt vom Polling, sodass Sie jeden Teil wiederverwenden können.

import os
import time
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"].rstrip("/")
FIRST_FRAME_URL = os.environ["FIRST_FRAME_URL"]

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

MODEL = "veo-3.1-fast/image-to-video"

def submit_job(prompt: str, image_url: str) -> str:
    payload = {
        "model": MODEL,
        "prompt": prompt,
        "image": image_url,
    }
    resp = requests.post(
        f"{BASE_URL}/v1/videos/generations",
        headers=HEADERS,
        json=payload,
        timeout=60,
    )
    resp.raise_for_status()
    data = resp.json()
    job_id = data["id"]
    print(f"submitted job: {job_id} (status={data.get('status')})")
    return job_id

if __name__ == "__main__":
    job_id = submit_job(
        prompt="Slow dolly forward through a sunlit forest path, "
               "leaves drifting, soft birdsong ambience",
        image_url=FIRST_FRAME_URL,
    )

Warum diese Struktur

  • Konfiguration in Konstanten. Basis-URL, Header, Endpunktpfad und Modellname werden nur einmal definiert. Wenn die API-Referenz Ihnen andere Feldnamen nennt, ändern Sie nur eine Zeile.
  • timeout ist explizit. Eine Einreichung, die ewig hängt, ist schlimmer als ein schneller Fehlschlag. Für einen kleinen JSON-Body sind sechzig Sekunden reichlich.
  • raise_for_status() legt Fehler früh offen. Bei 4xx und 5xx erhalten Sie eine Exception, statt stillschweigend einen Fehler-Body als Aufgabe zu parsen.
  • Die Funktion gibt nur die Aufgaben-ID zurück. Der Aufrufer muss nicht wissen, wie die Submit-Payload aussieht; er braucht nur etwas zum Pollen.

Wenn Ihre Anwendung ein Webdienst ist, rufen Sie submit_job im Request-Handler auf und übergeben Sie die zurückgegebene ID an einen Hintergrund-Worker. Blockieren Sie nicht die HTTP-Anfrage, während das Video gerendert wird.

Asynchrone Aufgabe pollen, bis das Video bereit ist

Jetzt existiert die Aufgabe und steht in der Warteschlange. Polling ist der Weg, zu erfahren, wann sie fertig ist.

Die grundlegende Polling-Schleife

def poll_job(job_id: str, timeout_s: int = 900, initial_delay: float = 5.0) -> dict:
    url = f"{BASE_URL}/v1/videos/generations/{job_id}"
    delay = initial_delay
    deadline = time.time() + timeout_s

    while time.time() < deadline:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        resp.raise_for_status()
        data = resp.json()
        status = data.get("status")
        print(f"status={status}")

        if status == "succeeded":
            return data
        if status in ("failed", "cancelled"):
            raise RuntimeError(f"job {job_id} ended with status={status}: {data}")

        time.sleep(delay)
        delay = min(delay * 1.5, 30.0)  # back off, cap at 30s

    raise TimeoutError(f"job {job_id} did not finish within {timeout_s}s")

Warum jeder Teil vorhanden ist

  • Polling statt Webhook. Die einfachste zuverlässige Integration fragt den Status nach Plan ab. Webhooks sind im großen Maßstab besser, erfordern aber einen öffentlichen Endpunkt; Polling funktioniert überall.
  • Exponentielles Backoff mit Obergrenze. Frühe Abfragen sind günstig und häufig; spätere Abfrageintervalle werden größer. Die Obergrenze verhindert, dass die Intervalle bei langen Aufgaben entgleisen. Starten Sie bei etwa fünf Sekunden und steigern Sie sich.
  • Explizite Endzustände. Erfolg ist ein Zustand; Fehlschlag und Abbruch sind andere. Behandeln Sie alles andere als „weiter warten“, aber warten Sie niemals unbegrenzt.
  • Echte Zeitgrenze. Videogenerierung ist im Vergleich zu Text langsam. Wählen Sie ein großzügiges Gesamt-Timeout, das zur Geduld Ihres Produkts passt, und scheitern Sie bei Überschreitung sauber, statt endlos zu schleifen.
  • Status-Logging. Drucken oder protokollieren Sie jeden Statuswechsel. Wenn etwas schiefgeht, ist das das Erste, was Sie sehen wollen.

Aus der Shell pollen

Für eine schnelle manuelle Prüfung beim Debuggen genügt ein curl-Aufruf:

curl -sS "$HIAPI_BASE_URL/v1/videos/generations/$JOB_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"

Führen Sie ihn alle paar Sekunden erneut aus oder verpacken Sie ihn in eine kleine while-Schleife, bis der Status in einen Endzustand umschlägt. Bestätigen Sie die genauen Feld- und Pfadnamen gegen die HiAPI-API-Referenz – der Lebenszyklus ist stabil, aber die Details auf der Leitung sind die maßgebliche Quelle.

Sobald poll_job zurückkehrt, sollte die Antwort einen Verweis auf das fertige Video enthalten. Das laden Sie als Nächstes herunter.

Ausgabe herunterladen und prüfen

Die Aufgabe ist abgeschlossen, die Antwort verweist auf die erzeugte Datei. Das Herunterladen ist ein gewöhnlicher HTTP-GET, aber mit zwei Dingen: Sie schreiben sie gestreamt auf die Festplatte und prüfen, was Sie erhalten haben.

Video abrufen

import os
from urllib.parse import urlparse

def download_video(job: dict, out_dir: str = "outputs") -> str:
    video_url = job["output"]["url"]  # confirm the field path in the API reference
    os.makedirs(out_dir, exist_ok=True)

    parsed = urlparse(video_url)
    ext = os.path.splitext(parsed.path)[1] or ".mp4"
    dest = os.path.join(out_dir, f"{job['id']}{ext}")

    with requests.get(video_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 << 16):
                f.write(chunk)

    size = os.path.getsize(dest)
    if size == 0:
        raise IOError(f"downloaded file is empty: {dest}")
    print(f"saved {dest} ({size} bytes)")
    return dest

Erläuterungen:

  • Gestreamtes Übertragen in Blöcken. Videodateien sind groß; sie mit r.content in den Speicher zu laden, ist verschwenderisch und kann auf ressourcenbeschränkten Hosts fehlschlagen.
  • Dateiendung beibehalten, damit Player und nachgelagerte Tools das Containerformat erkennen.
  • Benennung nach Aufgaben-ID. Sie ist eindeutig, nachverfolgbar und vermeidet Konflikte beim Ausführen von Batches.
  • Leere Dateien ablehnen. Ein Download mit null Bytes ist ein fehlgeschlagener Download, auch wenn der Statuscode 200 lautet.

Wenn die Video-URL signiert ist oder zeitlich begrenzt gilt, laden Sie sofort nach Abschluss der Aufgabe herunter, statt die URL für später zu speichern.

Prüfen, dass es ein echtes Video mit Audio ist

Dass eine Datei existiert, heißt nicht, dass sie brauchbar ist. Prüfen Sie sie:

  • Lokal abspielen mit einem Mediaplayer und Bild sowie Ton bestätigen. veo-3.1-fast/image-to-video erzeugt natives Audio, daher ist ein stummes Ergebnis ein Warnsignal, das es wert ist, vor der Auslieferung an Nutzer untersucht zu werden.
  • Container prüfen mit ffprobe, falls ffmpeg installiert ist:
ffprobe -hide_banner outputs/job_abc123.mp4

Achten Sie in der Ausgabe auf Video- und Audiostream sowie eine plausible Dauer. Das ist auch der schnellste Weg, abgeschnittene Dateien zu erkennen.

  • Grundprüfung gegen den ersten Frame. Er sollte Ihrem Eingabebild ähneln. Wenn nicht, verdächtigen Sie zunächst die Bild-URL oder das Feld, über das Sie sie übergeben haben, bevor Sie das Modell verdächtigen.

Sobald der Download geprüft ist, legen Sie die Datei in persistentem Speicher ab und protokollieren Sie zugleich die Aufgaben-ID. Diese Zuordnung ermöglicht späteres Debuggen, erneutes Ausführen und Abrechnungsabgleich.

Fallstricke und Prüfungen vor dem Skalieren

Die meisten Integrationsprobleme mit asynchronen Video-APIs sind keine Modellprobleme. Es sind Pipeline-Probleme. Folgendes sollten Sie zuerst prüfen.

Bildeingabe

  • Ist das Bild wirklich erreichbar? Eine URL, die in Ihrem Browser funktioniert, kann Authentifizierung verlangen, Hotlinking blockieren oder ablaufen. Bevorzugen Sie stabile, öffentlich lesbare URLs.
  • Ist es ein unterstütztes Format? Bleiben Sie bei gängigen Formaten wie JPEG und PNG, sofern die API-Referenz nichts anderes angibt.
  • Ist der Inhalt richtig? Der erste Frame verankert den gesamten Clip. Ein minderwertiges oder thematisch unpassendes Bild erzeugt ein enttäuschendes Video, das auch durch noch so viel Prompt-Feintuning nicht zu retten ist.

Request-Struktur

  • Feldnamen und Typen. Prüfen Sie sie gegen die HiAPI-API-Referenz für veo-3.1-fast/image-to-video. Von anderen Plattformen kopierte Ausschnitte schlagen fehl – der Endpunkt gehört HiAPI, und Feldnamen sind case-sensitiv.
  • Content-Type. Senden Sie Content-Type: application/json und einen echten JSON-Body, keine Formulardaten.
  • Modellkennung. Verwenden Sie den vollständigen String veo-3.1-fast/image-to-video; abgeschnittene Namen liefern scheinbar unzusammenhängende Fehler.

Timeouts und Wiederholungen

  • Eigene Timeouts pro Phase. Einreichung, Statusabfragen und Dateidownload verdienen jeweils eines. Ein einzelnes globales Timeout ist entweder zu knapp für den Download oder zu großzügig für Statusprüfungen.
  • Sicher wiederholen. Die Einreichung kann bei transienten Netzwerkfehlern und 5xx-Antworten wiederholt werden, aber nur, wenn Sie feststellen können, ob die Aufgabe tatsächlich angelegt wurde – sonst drohen doppelte Abrechnung und doppelte Generierung. Polling und Download sind idempotent und können frei wiederholt werden.
  • Bei Rate-Limits zurückweichen. Respektieren Sie die Antwort und werden Sie langsamer, statt den Endpunkt zu bombardieren.

Polling-Verhalten

  • Niemals in einer engen Schleife pollen. Das verschwendet Kontingent und wirkt wie Missbrauch.
  • Immer eine Abbruchbedingung haben. Eine Deadline, die eine Exception auslöst, ist besser als eine im Speicher hängende Aufgabe.
  • Jeden Statuswechsel mit Zeitstempel protokollieren. Sie brauchen das, um Latenzen abzuleiten.

Betriebliche Hygiene

  • API-Schlüssel serverseitig halten. Senden Sie sie niemals an den Browser und betten Sie sie nicht in mobile Apps ein.
  • Aufgaben-ID mit jedem Artefakt speichern. Sie ist Ihr Verbindungsschlüssel über Logs, Dateien und Nutzungsaufzeichnungen hinweg.
  • Downloads vor der Auslieferung prüfen. Prüfen Sie die Größe und idealerweise die Streams. Leere oder stumme Dateien, die Nutzer erreichen, sind deutlich teurer zu beheben als ein fehlgeschlagener Download, den Sie wiederholen.
  • Feldpfade nicht annehmen. Die Position von output in der Aufgabenantwort ist genau die Art Detail, die sich ändert – lesen Sie sie aus der API-Referenz, nicht aus einem Tutorial, auch nicht aus diesem.

Gehen Sie diese Liste der Reihe nach durch, bevor Sie ein Ticket gegen das Modell einreichen. Meistens liegt die Lösung in einer URL, einem Feldnamen oder fehlendem Backoff.

Das ist der vollständige Kreislauf: mit erstem Frame und Prompt einreichen, die Aufgabe bis zum Abschluss pollen, dann das Video mit nativem Audio herunterladen und prüfen. Beginnen Sie auf der Modellseite von veo-3.1-fast/image-to-video bei HiAPI, bestätigen Sie die aktuellen Request-Felder und heben Sie dann die beiden obigen Funktionen in Ihren eigenen Dienst.

Ähnliche Artikel

Alle Artikel ansehen →

Starte mit persistenten KI-Artefakten

Hol dir deinen API-Key und rufe Bild-, Video- und Audiomodelle über eine einzige task-basierte API auf.

API-Dokumentation lesen