HiAPI
ブログ

使用ガイド

製品の静止画からショート動画を生成:hiapi API の grok-imagine/image-to-video

Jul 9, 2026
製品の静止画からショート動画を生成:hiapi API の grok-imagine/image-to-video

ショート動画の製品コンテンツには供給の問題がある。かつて、すぐに配信できる短編動画1本は1回の撮影を意味していた。スタジオ撮影の時間、モーションデザイン、編集者。しかし、すでにECの商品カタログを運営しているなら、手元には既製の素材がある——何千枚もの製品静止画だ。grok-imagine/image-to-video(xAI の Grok Imagine 画像→動画エンドポイント)は、1回の非同期 API 呼び出しで、これらの静止画を6〜30秒の映画のような短編動画に変える。その参照画像による条件付けにより、製品は依然としてあなたの製品のように見える。

本ガイドは hiapi API 上のエンドツーエンドのワークフローである。単一のカタログ静止画を動かし、複数の参照画像で被写体の一貫性を固定し、フィードの経済性に合わせて再生時間と解像度のティアを選び、カタログ全体を縦型ショート動画のキューにバッチ処理する。以下に埋め込まれた各短編動画は、ライブ API からの実際の、未編集の初回出力である——本記事のために私たちの素材ライブラリの静止画から生成し、隣に正確なプロンプトと設定を添えている。

モデル、制限、価格

grok-imagine/image-to-video は hiapi の非同期タスクインターフェース(POST /v1/tasks)上で動作する。本記事のために私たちが実測で検証した入力スキーマ:

  • image_urls(配列、必須)—— 1つ以上の公開アクセス可能な参照画像 URL。プライベートまたは取得不可能な URL は、スキーマエラーではなく正規化段階で失敗する。そのため、参照画像はまず公開の場所にホストしておくこと。
  • prompt(文字列、任意)—— 動き、カメラ、雰囲気の指示。プロンプトを指定しない場合はモデルが自由に解釈する。製品コンテンツを作る際は常に指定すべきだ。
  • duration(整数、6〜30秒)
  • resolution(480p または 720p)
  • aspect_ratio(1:1、2:3、3:2、16:9、9:16)

motion_mode、seed、ネガティブプロンプトのフィールドは存在しない——未知のフィールドは400で拒否される。すべての動きの制御はプロンプトの文言で行う。

本記事の短編動画を生成する際に遭遇した挙動:aspect_ratio が参照画像自体のアスペクト比と一致しない場合、参照画像が勝つことが多い。 以下の3回の実行ではいずれも 9:16 を要求したが、2枚の正方形のソース静止画は正方形の短編動画(960×960 と 544×544)を返し、最初の参照画像が横長だった実行では本物の 720×1280 の縦型が出力された。フィードで 9:16 を保証する必要があるなら、このパラメータに頼るのではなく、送信前に参照静止画を 9:16 にクロップすること。

価格は出力秒数に基づいて課金され、執筆時点の hiapi の料金ページによる:

ティア 1秒あたりの価格 6秒の動画 15秒の動画 30秒の動画
480p $0.0114 $0.068 $0.171 $0.342
720p $0.0214 $0.128 $0.321 $0.642

この価格がワークフロー全体を形作る。6秒の720pのメインビジュアル動画は約13セント、480pのドラフトは約半分だ。反復作業のコストは十分に許容できる。

送信 → ポーリング → ダウンロード

タスクのライフサイクルは、送信、ポーリング、ダウンロードである。curl で送信する:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine/image-to-video",
    "input": {
      "prompt": "Slow cinematic orbit around the bag, studio lighting glinting off the brass zippers, background stays clean, product unchanged.",
      "image_urls": ["https://your-cdn.example.com/products/weekender.jpg"],
      "duration": 6,
      "resolution": "720p",
      "aspect_ratio": "9:16"
    }
  }'

すぐにタスク ID が返る:

{"code": 200, "data": {"taskId": "tk-hiapi-01KX2H8WMWQG99A2F97BREDPS6"}, "message": "success"}

次に GET /v1/tasks/{taskId} を status が success になるまでポーリングし、output[0].url をダウンロードする。以下は完全な Python ヘルパースクリプトである——本記事の各短編動画を生成するのに使った正確なパターンだ:

import json, subprocess, time, os

API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]

def submit(input_fields: dict) -> str:
    payload = {"model": "grok-imagine/image-to-video", "input": input_fields}
    out = subprocess.run(
        ["curl", "-s", "-X", "POST", API,
         "-H", f"Authorization: Bearer {TOKEN}",
         "-H", "Content-Type: application/json",
         "-d", json.dumps(payload)],
        capture_output=True, text=True, timeout=70).stdout
    data = json.loads(out)
    if not (data.get("data") or {}).get("taskId"):
        raise RuntimeError(f"submit failed: {out[:300]}")
    return data["data"]["taskId"]

def wait(task_id: str, timeout_s: int = 1200) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        out = subprocess.run(
            ["curl", "-s", f"{API}/{task_id}",
             "-H", f"Authorization: Bearer {TOKEN}"],
            capture_output=True, text=True, timeout=40).stdout
        task = json.loads(out)["data"]
        if task["status"] == "success":
            return task
        if task["status"] == "fail":
            raise RuntimeError(f"task failed: {task.get('error')}")
        time.sleep(10)
    raise TimeoutError(task_id)

task_id = submit({
    "prompt": "...",
    "image_urls": ["https://your-cdn.example.com/products/weekender.jpg"],
    "duration": 6,
    "resolution": "720p",
    "aspect_ratio": "9:16",
})
task = wait(task_id)
video_url = task["output"][0]["url"]
subprocess.run(["curl", "-s", "-o", "clip.mp4", video_url], timeout=180)

本番環境で注意すべき2つの運用上のポイント:

  1. output[0].url は有効期限付きの署名リンク(期限切れ時刻を持つ)である。タスクが成功したらすぐにバイトをダウンロードして自分のストレージへ移すこと——元のタスク URL を永続的に保存してはならない。
  2. 課金はタスクが受け付けられた時点で発生するため、大量送信の前に検証を行うこと。便利なテクニック:範囲外の値、例えば "duration": 99 を送ると、課金対象のタスクを作成せずに完全なスキーマ検証エラーが返る。

1枚の静止画 → 1本のメインビジュアル動画

最も一般的な操作:カタログの製品画像を1枚取り、連続したカメラの動きを与える。製品写真は本質的に静的であるため、プロンプトの役割は信憑性のある動きを1つだけ加え、それ以外のすべてを明示的に固定することだ:

Slow cinematic orbit around the burnt-orange canvas weekender bag, camera
circling smoothly from front to three-quarter view, studio lighting glinting
off the brass zippers, seamless white background stays clean and shadowless,
product perfectly sharp and unchanged, subtle premium e-commerce energy.

実際の出力——grok-imagine/image-to-video、6秒 @ 720p、参照画像1枚。初回生成、未編集。実際の納品は 960×960:正方形のソース静止画が私たちの 9:16 リクエストを上書きした(上記のアスペクト比の説明を参照)。ソース静止画は以下の通り。

製品動画をリアルに保つプロンプトのパターン:

  • カメラの動詞は1つ(「オービット」「プッシュイン」「パン」)。1つのプロンプトに2つの動きを入れると船酔いのような映像になる。
  • 「製品は不変 / 完全にシャープ」と明示する。画像→動画モデルはドリフトする。被写体は変更不可だと伝えることで、ロゴ、ステッチ、金具の変形を大幅に減らせる。
  • 素材の見せ場を挙げる(「真鍮のジッパーに光がきらめく」)——金属や革の上を光の反射が動くことこそ、静止画が歪みではなく撮影のように感じられる理由だ。
  • 背景を固定する(「クリーンで影なしのまま」)。さもないとモデルが勝手にセットを発明してしまう。

複数の参照画像:被写体を固定する

image_urls は1枚以上の参照画像を受け付け、まさにここが grok-imagine が製品作業において単一フレームのアニメーターと異なる点である。シーンのベースにしたいライフスタイル画像を与え、さらにクリーンな製品画像をアイデンティティの保険として加えると、モデルは両者を調和させる——シーンは1枚目の画像から、製品の正確なトリム、ストラップ、ジッパーは2枚目の画像によって固定される:

The same burnt-orange weekender bag rests on a weathered wooden bench in a
sunlit loft; a gentle push-in as dust motes drift through warm window light,
soft shadows slide slowly across the bench, the bag and its dark leather trim
stay exactly consistent with the reference images, calm lifestyle-catalog mood.

実際の出力——grok-imagine/image-to-video、6秒 @ 720p、9:16、2枚の参照画像(ベンチのライフスタイル画像 + 白背景の製品画像)。初回生成、未編集。

プロンプト内の「参照画像と一致」という文言に注目してほしい——複数の参照画像を使う場合、それを明示することが、余分な画像を混ぜ込む2つ目のシーンではなくアイデンティティの制約としてモデルに扱わせる助けになる。これがブランドアカウントの毎日投稿のパターンだ:SKUごとに製品画像を1枚撮影(または生成)し、アニメーション化する各ライフスタイル動画で一貫性のアンカーとして再利用する。

再生時間とドラフトティアの経済性

再生時間は6〜30秒で、解像度が予算のレバーとなる:480p の1秒あたりの価格は 720p の約半分だ。フィードはどのみち積極的に圧縮するため、合理的なパイプラインは480p でドラフトし、勝者を 720p で作り直すことだ。より長い再生時間はモデルにゆっくりとした展開の余地も与える——以下は紅茶缶の静止画に連続した雰囲気の動きを与えた、12秒の 480p ドラフトティアの短編動画だ:

Moody slow dolly-in on the matte-black tea tin standing on slate, steam curls
up lazily behind it, a soft beam of morning light sweeps across the embossed
label, tiny tea leaves tumble gently onto the slate in the final seconds, dark
premium atmosphere, label text unchanged and legible.

実際の出力——grok-imagine/image-to-video、12秒 @ 480p、参照画像1枚。初回生成、未編集(正方形のソース静止画に合わせて正方形で納品)。コスト:$0.137。

480p のレンダリングコストは $0.0114/秒——12秒の動画全体でわずか13.7セントだった。各製品について3つのプロンプトバリエーションを試し、実際に公開する1本にだけ 720p の料率を支払う余裕がある。プロンプト内の「ラベルのテキストは不変で読みやすく」に注目してほしい:パッケージの文字は画像→動画で最も早くぼやけるものなので、明示することが最も安価な防御策だ。

カタログをバッチ処理する

タスクは非同期なので、上述のすべては線形にスケールする:バッチ全体を先に送信し、その後にポーリングする。製品リスト向けの最小限のバッチランナー:

products = [
    {"sku": "weekender-orange", "refs": ["https://cdn.example.com/weekender.jpg"],
     "prompt": "Slow cinematic orbit around the bag, studio light on the brass zippers, background clean, product unchanged."},
    {"sku": "tea-tin-black", "refs": ["https://cdn.example.com/tea-tin.jpg"],
     "prompt": "Moody slow dolly-in, steam drifting, light sweeping the embossed label, label text unchanged."},
    # ... カタログの残り
]

jobs = []
for p in products:
    tid = submit({
        "prompt": p["prompt"],
        "image_urls": p["refs"],
        "duration": 6,
        "resolution": "480p",     # ドラフトティア
        "aspect_ratio": "9:16",
    })
    jobs.append((p["sku"], tid))

for sku, tid in jobs:
    task = wait(tid)
    url = task["output"][0]["url"]
    subprocess.run(["curl", "-s", "-o", f"{sku}.mp4", url], timeout=180)
    print(f"{sku}: done")

このパイプラインを実行するための実用的なバッチ処理のポイント:

  • 先に送信、後でポーリング。 各レンダリングには数分かかり、サーバー側で並列に実行される。「送信-待機-送信」を直列化すると、この並列性を無駄にする。
  • コンテンツタイプごとに1つのフラットなプロンプトテンプレートを保つ(製品画像はオービット、ライフスタイル画像はプッシュイン)。製品名だけを差し替える。フィード全体の一貫性は、各動画の巧妙さよりも重要だ。
  • 予算チェック: 50 SKU のカタログを6秒/480p でドラフトすると 50 × $0.068 ≈ $3.42。最良の10本を 720p に引き上げると10 × $0.128 ≈ $1.28 の追加。1か月分の毎日の製品動画が、1時間のスタジオ撮影時間より安く済む。

ショート動画公開の注意点

  • 縦型には縦型の参照画像が必要。 前述の通り、参照画像のアスペクト比が aspect_ratio を上書きすることが多い——動画をフィードに配信するなら、送信前に静止画を 9:16 にクロップすること。完成した正方形のレンダリングを縦型にクロップするとピクセルの大部分を失う。
  • 最初の1秒がフック——動きを即座に始めるプロンプト(「カメラオービット」「プッシュイン」)は、ゆっくりしたフェードインよりも完視聴率で優れる。
  • 動画にはモデル生成の環境音トラックが付属する。 私たちが生成した各出力には AAC ストリームが含まれていた——あるものは微妙なスタジオの雰囲気、あるものはほぼ無音だった。これを制御する入力フィールドは存在しないため、公開時は完成した楽曲として扱うのではなく、独自の音楽やナレーションに差し替える計画を立てること。
  • ループとの相性: オービットや光の掃引は、露わにして終わる動画よりもはるかにループ効果が高い。自動ループするフィード(Shorts、Reels)では、上記のオービットパターンはシームレスに再生し続けられる。

よくある質問

レンダリングにはどのくらいかかる? 本記事の6秒の動画は各数分でレンダリングされた。12秒の動画はもう少し長い。インタラクティブな呼び出しではなく非同期キューとして扱うこと——一括で送信してポーリングする。

生成した画像を参照画像として使える? 使える。参照 URL は公開で取得可能であるだけでよい。本記事の3枚のソース静止画自体が API で生成した製品画像(seedream-5.0-lite の実行によるもの)で、私たちの素材ライブラリからのものだ——完全に合成された静止画から動画へのパイプラインである。

1080p や30秒超はどう? このエンドポイントは 720p と30秒までに制限されている。ショート動画フィードには、まさにこれが最適な範囲だ。より高い解像度が必要なら、後処理でアップスケールするか、モデルカタログで現在の選択肢を確認してほしい。

grok-imagine-1.5/image-to-video との違いは? 1.5 プレビューエンドポイントは範囲を動きの品質と引き換えにする:1〜15秒の再生時間、動きはアップグレード、1秒あたりの価格は同じ。この 1.0 エンドポイントは6〜30秒を提供する。1.5 の基本については別の解説記事で扱っている。

テキスト→動画のバージョンはある? ある——grok-imagine/text-to-video、同じタスクインターフェースでプロンプト入力のみ。ブランド/製品の一貫性が重要な場合は画像→動画が正しい選択であり、ゼロから素材を生成する必要がある場合はテキスト→動画を使う。


製品の静止画と API キーがあれば、最初のフィード動画まであと1回の POST /v1/tasks だけだ:ダッシュボードでキーを取得し、grok-imagine/image-to-video のモデルページから始め、上記のオービットプロンプトで製品画像を1枚アニメーション化しよう——ドラフト1本13セントなら、このモデルを学ぶ最速の方法は実際に動かすことだ。

永続的なAIアーティファクトで開発を始める

APIキーを取得して、タスクベースの1つのAPIで画像・動画・音声モデルを呼び出せます。

APIドキュメントを読む