GEMINI LABEN
API — Event-driven WebhooksでBatch APIや長時間処理の完了を通知受信。ポーリングが不要になりますSEARCH — File Searchがgemini-embedding-2に対応し、画像もネイティブに埋め込み・検索できますSECURITY — 6/19以降、未制限APIキーからのリクエストが遮断されました。キー制限の点検をMODEL — Gemini 3.5 Flashが一般提供。gemini-flash-latestの本体になりましたAGENT — Managed AgentsがGemini APIで公開プレビュー。隔離サンドボックスで自律エージェントを実行できますDEPRECATED — 画像プレビュー2モデルが6/25で停止。preview依存の処理は確認しておきましょうAPI — Event-driven WebhooksでBatch APIや長時間処理の完了を通知受信。ポーリングが不要になりますSEARCH — File Searchがgemini-embedding-2に対応し、画像もネイティブに埋め込み・検索できますSECURITY — 6/19以降、未制限APIキーからのリクエストが遮断されました。キー制限の点検をMODEL — Gemini 3.5 Flashが一般提供。gemini-flash-latestの本体になりましたAGENT — Managed AgentsがGemini APIで公開プレビュー。隔離サンドボックスで自律エージェントを実行できますDEPRECATED — 画像プレビュー2モデルが6/25で停止。preview依存の処理は確認しておきましょう
記事一覧/API / SDK
API / SDK/2026-06-28上級

Gemini API で動画を「時刻つき」で読む — 該当シーンだけを引き出す

画面録画やアプリのデモ動画から「あの操作はどこ?」を探すのは骨が折れます。Gemini API の動画理解を使い、タイムスタンプ付きで該当箇所だけを引き出す方法と、FPS・解像度でトークンを抑える設計をまとめます。

Gemini API152動画理解Files API3マルチモーダル22個人開発70

数分のアプリ操作を画面録画して、後から「設定を変えた瞬間って何分何秒だっけ」と探す。私自身、個人開発で不具合の再現動画を撮るたびに、このシーク作業に時間を溶かしてきました。動画は情報が濃いぶん、目で追って探すのが一番遅い媒体です。

Gemini API の動画理解は、ここを「時刻を答えてくれる検索」に変えてくれます。動画をまるごと渡し、「この操作が起きる箇所を分秒で挙げて」と頼めば、該当シーンのタイムスタンプを返してきます。ただし素朴に長尺動画を投げると、トークンが膨らんで応答も遅く、費用も読めません。以下では、タイムスタンプ付きで必要なシーンだけを引き出す実装と、FPS・解像度で消費を抑える設計を、動く形で組み立てます。

まず動画を Files API に預ける

20MB を超える動画はインラインで送れないため、Files API にアップロードしてから参照します。アップロード直後はサーバ側で処理中(PROCESSING)なので、ACTIVE になるまで待ってから使います。ここを待たずに投げると failed precondition 系のエラーになります。

import time
from google import genai
 
client = genai.Client()  # GEMINI_API_KEY を環境変数から読む
 
def upload_and_wait(path: str, timeout: float = 300.0):
    f = client.files.upload(file=path)
    start = time.time()
    while f.state.name == "PROCESSING":
        if time.time() - start > timeout:
            raise TimeoutError(f"processing timed out: {f.name}")
        time.sleep(3)
        f = client.files.get(name=f.name)
    if f.state.name != "ACTIVE":
        raise RuntimeError(f"upload not active: {f.state.name}")
    return f
 
video = upload_and_wait("app_demo.mp4")
print("ready:", video.name, video.state.name)

client.files.get で状態を取り直すのを忘れると、最初に取った PROCESSING のままループが回り続けます。アップロードしたファイルは既定で数日後に自動削除されるため、使い終わったら client.files.delete(name=...) で明示的に消しておくと、保存容量と取り違えの両方を防げます。

タイムスタンプで答えさせる

本題です。プロンプトで「MM:SS 形式の時刻つきで答えて」と明示し、出力をそのまま処理に使えるよう構造化を指示します。Gemini は動画の時間軸を理解しているので、「○○が画面に出る最初の瞬間」のような時刻依存の問いに答えられます。

from google.genai import types
 
prompt = """この画面録画から、次のイベントが最初に起きた時刻を MM:SS で挙げてください。
- 設定画面を開いた瞬間
- 保存ボタンを押した瞬間
- エラーダイアログが表示された瞬間
各イベントについて time(MM:SS) と what(40字以内の説明) を返してください。
該当が無いイベントは time を null にしてください。"""
 
schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "event": {"type": "string"},
            "time":  {"type": "string", "nullable": True},
            "what":  {"type": "string"},
        },
        "required": ["event", "what"],
    },
}
 
resp = client.models.generate_content(
    model="gemini-flash-latest",
    contents=[video, prompt],
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema=schema,
    ),
)
for row in resp.parsed:
    print(f'{row.get("time") or "--:--"}  {row["event"]}: {row["what"]}')

ポイントは、時刻の表現をプロンプトで MM:SS に固定し、さらに response_schema で配列の形まで縛っていることです。こうしておくと、返ってきた time をそのまま ffmpeg -ss のシーク開始点に渡したり、該当フレームのサムネイルを切り出したりと、後段の自動処理につなげられます。モデルは速くて安い gemini-flash-latest(3.5 Flash 系の本体)で十分実用になります。動画理解のような前処理こそ、速度と費用の効く Flash 系に回すのが、Dolice Labs の自動運用での私の定番です。

FPS と解像度でトークンを抑える

長尺になるほど効いてくるのが、サンプリング設定です。Gemini は動画を既定で毎秒1フレーム前後で取り込みますが、video_metadatafps を下げれば取り込むフレーム数が減り、消費トークンと処理時間がまとめて下がります。スライド主体の録画や、ゆっくりした操作の動画なら、FPS を落としても精度はほとんど落ちません。

from google.genai import types
 
# 低FPS + 低解像度で、長尺のざっくり把握を安く済ませる
part = types.Part(
    file_data=types.FileData(file_uri=video.uri, mime_type="video/mp4"),
    video_metadata=types.VideoMetadata(
        fps=0.5,                 # 2秒に1フレーム。動きの少ない録画に有効
        start_offset="30s",      # 冒頭30秒を飛ばして本編から
        end_offset="5m0s",       # 5分まで。範囲を切ると更に軽くなる
    ),
)
 
resp = client.models.generate_content(
    model="gemini-flash-latest",
    contents=[part, "この区間の主要な操作を時系列で5点、MM:SS つきで。"],
    config=types.GenerateContentConfig(
        media_resolution=types.MediaResolution.MEDIA_RESOLUTION_LOW,
    ),
)
print(resp.text)
print("tokens:", resp.usage_metadata.total_token_count)

私の使い分けは単純です。長い動画から「だいたいどこに何があるか」を地図化したい一次パスは、fps=0.5MEDIA_RESOLUTION_LOW で安く広く。そこで当たりをつけた区間だけ、start_offset/end_offset で 30 秒ほどに切り、FPS と解像度を上げて精読する二次パス。こうすると、最初から全編を高解像度で見るより、トークンを数分の一に抑えつつ、肝心な箇所の精度は確保できます。usage_metadata.total_token_count を毎回ログに残しておくと、どの設定がどれだけ効いたかを実測で比べられます。

注意点として、fps を上げるほど短い瞬間の検出力は上がりますが、トークンは線形に増えます。1フレームで消える通知バナーのような対象を確実に捉えたいときだけ、その区間に限って高 FPS にするのが費用対効果の良い進め方です。

二段で読む発想に切り替える

動画理解で遠回りに見えて速いのは、最初から精読しないことでした。低 FPS・低解像度で全体の地図を作り、当たりのついた短い区間だけを高解像度で読み直す。タイムスタンプを構造化して返させておけば、その地図はそのまま後段の自動処理の入力になります。

次の一歩として、手元の画面録画を1本、まず fps=0.5 で「主要イベントを MM:SS つきで」と読ませてみてください。返ってきた時刻を ffmpeg -ss に渡せば、該当フレームだけを瞬時に取り出せます。シークに溶かしていた時間が、そのまま開発に戻ってくるはずです。同じように動画から情報を拾う作業に追われている方の、最初の足がかりになれば嬉しいです。

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API / SDK2026-06-12
壁紙アセットの画像探しを File Search のマルチモーダル検索に任せてみた記録
数千枚の壁紙アセットから目当ての一枚を探す作業を、File Search のマルチモーダル検索(gemini-embedding-2)に置き換えられるか300枚で検証しました。カテゴリタグ運用との比較、つまずいた点、使い分けの結論を実装コードとともに残します。
API / SDK2026-06-03
Gemini Files API の孤児ファイルを棚卸しする — 多アプリ運用の照合と自動クリーンアップ設計
Files API にアップロードしたファイルは48時間で静かに消えます。多アプリ運用で発生する孤児ファイルとクォータ消費を、自前DBとの照合と定期クリーンアップで統制する本番設計を、壁紙アプリ運営の実装メモとしてまとめました。
API / SDK2026-05-19
Gemini Files API と Cloudflare R2 を組み合わせた画像処理パイプライン設計 — 壁紙アプリ運営の実装メモ
Gemini Files API と Cloudflare R2 を組み合わせ、壁紙アプリの画像処理パイプラインを再設計した30日の記録です。48時間制限・冪等性・コスト監視の落とし穴と対処を、実装コードと数値で整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →