GEMINI LABEN
TTS — gemini-3.1-flash-tts-previewが音声生成のストリーミングに対応し、streamGenerateContentから逐次再生できますTRANSLATE — Gemini 3.5 Live Translateが登場。70以上の言語を自動判定し、話者の抑揚を保ったまま音声から音声へ翻訳しますIMAGE — Nano Banana 2 Liteが提供開始となり、最も高速かつ低コストなGemini画像モデルになりましたOMNI — Gemini Omni Flashが公開プレビュー入りし、動画ワークフローを組めるネイティブマルチモーダルモデルとして使えますMODEL — Gemini 3.5 FlashがGA(正式版)となり、gemini-flash-latestの実体になりましたAGENT — Managed AgentsがGemini APIで公開プレビュー入り。分離されたGoogleホストのLinuxサンドボックスで自律エージェントを動かせますTTS — gemini-3.1-flash-tts-previewが音声生成のストリーミングに対応し、streamGenerateContentから逐次再生できますTRANSLATE — Gemini 3.5 Live Translateが登場。70以上の言語を自動判定し、話者の抑揚を保ったまま音声から音声へ翻訳しますIMAGE — Nano Banana 2 Liteが提供開始となり、最も高速かつ低コストなGemini画像モデルになりましたOMNI — Gemini Omni Flashが公開プレビュー入りし、動画ワークフローを組めるネイティブマルチモーダルモデルとして使えますMODEL — Gemini 3.5 FlashがGA(正式版)となり、gemini-flash-latestの実体になりましたAGENT — Managed AgentsがGemini APIで公開プレビュー入り。分離されたGoogleホストのLinuxサンドボックスで自律エージェントを動かせます
記事一覧/API / SDK
API / SDK/2026-07-05上級

Omni Flash で動画理解を1パスに畳む — フレーム抽出前提の構成をどこで手放すか

Omni Flash の公開プレビューで、ffmpeg のフレーム抽出と個別呼び出しに頼っていた動画理解を1回のネイティブ呼び出しへ畳む最小構成と、フレーム抽出を残すべき境界を実測ベースで整理します。

Gemini Omni Flash動画理解2マルチモーダル23Files API5コスト設計3

プレミアム記事

個人開発で短尺の紹介動画をいくつか扱うようになってから、動画を「理解させる」処理がいちばん重い工程になっていました。ffmpeg で毎秒フレームを切り出し、1枚ずつモデルに投げて説明を集め、最後にもう一度まとめる。動くには動くのですが、1本の動画を1回さばくのに7〜9回の API 呼び出しが走り、音声はまるごと捨てていました。

Omni Flash が公開プレビューに入り、動画をそのまま渡して理解させる経路が現実的になりました。以下では、私が実際にフレーム抽出前提の構成から1パスへ寄せたときの最小コード、相対的な計測、そして「ここから先はフレーム抽出を残したほうがよい」という境界を、判断できる形でまとめます。

フレーム抽出前提の3段パイプラインが抱えていた負債

これまで使っていた構成は、抽出・記述・要約の3段でした。コードにすると負債の場所がはっきりします。

import subprocess, os
from google import genai
 
client = genai.Client()
 
def extract_frames(video_path: str, fps: float = 1.0, out_dir: str = "frames") -> list[str]:
    os.makedirs(out_dir, exist_ok=True)
    subprocess.run([
        "ffmpeg", "-i", video_path,
        "-vf", f"fps={fps}", f"{out_dir}/f_%04d.jpg",
    ], check=True)
    return sorted(os.path.join(out_dir, f) for f in os.listdir(out_dir))
 
def describe_video(video_path: str) -> str:
    frames = extract_frames(video_path, fps=1.0)
    notes = []
    for i, path in enumerate(frames):           # フレーム枚数ぶん呼び出しが増える
        img = client.files.upload(file=path)
        r = client.models.generate_content(
            model="gemini-3.5-flash",
            contents=[img, f"{i}秒付近のフレームです。写っているものを一文で。"],
        )
        notes.append(f"[{i}s] {r.text.strip()}")
    summary = client.models.generate_content(    # さらに二次要約でもう1回
        model="gemini-3.5-flash",
        contents=["以下は毎秒のフレーム記述です。動画全体を3行で要約してください。\n" + "\n".join(notes)],
    )
    return summary.text

負債は3つあります。第一に、呼び出し回数が動画の長さに比例して増えます。第二に、音声トラックを一切見ていないため、ナレーションや効果音に依存する内容を取りこぼします。第三に、フレームを時系列インデックスで並べているだけなので、モデルは「動き」を推論できず、静止画の羅列として扱います。私の用途では、この3つ目が精度の頭打ちになっていました。

Omni Flash に動画をそのまま渡す最小構成

Omni Flash はネイティブに動画を扱うため、Files API でアップロードした動画を1回の generate_content に渡すだけで済みます。構造化出力と組み合わせると、後段のパースも消えます。

import time
from google import genai
from pydantic import BaseModel
 
client = genai.Client()
 
class VideoReport(BaseModel):
    summary: str
    spoken_language: str
    has_music: bool
    safe_for_all_ages: bool
    key_moments: list[str]
 
def understand_video(video_path: str) -> VideoReport:
    f = client.files.upload(file=video_path)
    # アップロード直後は PROCESSING。ACTIVE になるまで待たないと 400 になる
    while f.state.name == "PROCESSING":
        time.sleep(2)
        f = client.files.get(name=f.name)
    if f.state.name != "ACTIVE":
        raise RuntimeError(f"upload failed: {f.state.name}")
 
    r = client.models.generate_content(
        model="gemini-omni-flash-preview",   # 公開プレビュー。実IDは changelog の表記に合わせる
        contents=[f, "この動画を通しで理解し、指定スキーマで返してください。"],
        config={
            "response_mime_type": "application/json",
            "response_schema": VideoReport,
        },
    )
    return r.parsed

呼び出しは1回です。映像・音声・時間経過をひとつのコンテキストで見るため、has_musicspoken_language のように、フレーム抽出版では取れなかった軸が同時に返ります。私は最初、フレーム版の出力に寄せてテキスト要約だけを受け取っていましたが、response_schema を渡して必要な軸を明示したほうが、後続の分岐がそのまま書けて扱いやすかったです。

Before / After の差はコード量以上に「何を捨てているか」に出ます。Before は音声と動きを捨てて呼び出し回数を払い、After はその両方を1回で拾います。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
ffmpeg のフレーム抽出+個別呼び出し(1本あたり7〜9回)を Omni Flash の1回のネイティブ呼び出しに畳む最小構成
1パス処理が崩れる3つの境界(長尺・フレーム精密検出・低コストの真偽判定)とフレーム抽出を残す判断基準
粗い1パス判定→必要区間だけフレーム精査するハイブリッド構成と、アップロード状態・トークン予算で踏んだ落とし穴
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

API / SDK2026-06-28
Gemini API で動画を「時刻つき」で読む — 該当シーンだけを引き出す
画面録画やアプリのデモ動画から「あの操作はどこ?」を探すのは骨が折れます。Gemini API の動画理解を使い、タイムスタンプ付きで該当箇所だけを引き出す方法と、FPS・解像度でトークンを抑える設計をまとめます。
API / SDK2026-07-05
Nano Banana 2 Lite で大量画像生成のコストを設計する — 実測で使い分けを決める
最速・最安の画像モデル Nano Banana 2 Lite を、大量生成の現場でどう組み込むか。1枚あたりコストの測り方、品質モデルとの二層構成、失敗リトライまで含めた実測ベースの設計を書きます。
API / SDK2026-07-05
Nano Banana 2 Lite で大量画像生成のコストを二段に分ける — 一次生成と本番レンダを切り離した設計メモ
Nano Banana 2 Lite を一次生成、標準の Nano Banana 2 を採用後の本番レンダに回す二段構成のコスト設計を、最小のPythonルーターとともにまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →