動画理解

Gemini モデルは動画を処理できるため、これまでドメイン固有のモデルを必要としていた多くのフロンティア デベロッパーのユースケースを実現できます。Gemini のビジョン機能には、次のものがあります。

  • 最大 90 分間の動画の説明、セグメンテーション、情報の抽出
  • 動画コンテンツに関する質問に回答する
  • 動画内の特定のタイムスタンプを参照する

Gemini はマルチモーダルを念頭にしてゼロから構築されており、Google は可能性の限界を押し広げ続けています。このガイドでは、Gemini API を使用して動画入力に基づいてテキスト レスポンスを生成する方法について説明します。

始める前に

Gemini API を呼び出す前に、任意の SDK がインストールされ、Gemini API キーが構成され、使用可能であることを確認してください。

ビデオ入力

動画を Gemini に入力する方法は次のとおりです。

動画ファイルをアップロードする

Files API を使用して動画ファイルをアップロードできます。リクエストの合計サイズ(ファイル、テキスト プロンプト、システム インストラクションなど)が 20 MB を超える場合、動画の長さが長い場合、または複数のプロンプトで同じ動画を使用する場合は、必ず Files API を使用してください。

File API は動画ファイル形式を直接受け入れます。この例では、NASA の短編映画「Jupiter's Great Red Spot Shrinks and Grows」 を使用します。クレジット: ゴダード宇宙飛行センター(GSFC)/ David Ladd(2018 年)。

「Jupiter's Great Red Spot Shrinks and Grows」はパブリック ドメインであり、特定できる人物は写っていません。(NASA の画像とメディアの使用に関するガイドライン)。

次のコードは、サンプル動画をダウンロードし、File API を使用してアップロードし、処理が完了するのを待ってから、generateContent リクエストでファイル参照を使用します。

Python

from google import genai

client = genai.Client(api_key="GOOGLE_API_KEY")

myfile = client.files.upload(file="path/to/sample.mp4")

response = client.models.generate_content(
    model="gemini-2.0-flash", contents=[myfile, "Summarize this video. Then create a quiz with an answer key based on the information in this video."]
)

print(response.text)

JavaScript

import {
  GoogleGenAI,
  createUserContent,
  createPartFromUri,
} from "@google/genai";

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });

async function main() {
  const myfile = await ai.files.upload({
    file: "path/to/sample.mp4",
    config: { mimeType: "video/mp4" },
  });

  const response = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents: createUserContent([
      createPartFromUri(myfile.uri, myfile.mimeType),
      "Summarize this video. Then create a quiz with an answer key based on the information in this video.",
    ]),
  });
  console.log(response.text);
}

await main();

Go

file, err := client.UploadFileFromPath(ctx, "path/to/sample.mp4", nil)
if err != nil {
    log.Fatal(err)
}
defer client.DeleteFile(ctx, file.Name)

model := client.GenerativeModel("gemini-2.0-flash")
resp, err := model.GenerateContent(ctx,
    genai.FileData{URI: file.URI},
    genai.Text("Summarize this video. Then create a quiz with an answer key based on the information in this video."))
if err != nil {
    log.Fatal(err)
}

printResponse(resp)

REST

VIDEO_PATH="path/to/sample.mp4"
MIME_TYPE=$(file -b --mime-type "${VIDEO_PATH}")
NUM_BYTES=$(wc -c < "${VIDEO_PATH}")
DISPLAY_NAME=VIDEO

tmp_header_file=upload-header.tmp

echo "Starting file upload..."
curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
  -D ${tmp_header_file} \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
  -H "Content-Type: application/json" \
  -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null

upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"

echo "Uploading video data..."
curl "${upload_url}" \
  -H "Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@${VIDEO_PATH}" 2> /dev/null > file_info.json

file_uri=$(jq -r ".file.uri" file_info.json)
echo file_uri=$file_uri

echo "File uploaded successfully. File URI: ${file_uri}"

# --- 3. Generate content using the uploaded video file ---
echo "Generating content from video..."
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"file_data":{"mime_type": "'"${MIME_TYPE}"'", "file_uri": "'"${file_uri}"'"}},
          {"text": "Summarize this video. Then create a quiz with an answer key based on the information in this video."}]
        }]
      }' 2> /dev/null > response.json

jq -r ".candidates[].content.parts[].text" response.json

メディア ファイルの操作の詳細については、Files API をご覧ください。

動画データをインラインで渡す

File API を使用して動画ファイルをアップロードする代わりに、リクエストで小さい動画を直接 generateContent に渡すことができます。これは、リクエストの合計サイズが 20 MB 未満の短い動画に適しています。

インライン動画データを提供する例を次に示します。

Python

# Only for videos of size <20Mb
video_file_name = "/path/to/your/video.mp4"
video_bytes = open(video_file_name, 'rb').read()

response = client.models.generate_content(
    model='models/gemini-2.0-flash',
    contents=types.Content(
        parts=[
            types.Part(
                inline_data=types.Blob(data=video_bytes, mime_type='video/mp4')
            ),
            types.Part(text='Please summarize the video in 3 sentences.')
        ]
    )
)

JavaScript

import { GoogleGenAI } from "@google/genai";
import * as fs from "node:fs";

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const base64VideoFile = fs.readFileSync("path/to/small-sample.mp4", {
  encoding: "base64",
});

const contents = [
  {
    inlineData: {
      mimeType: "video/mp4",
      data: base64VideoFile,
    },
  },
  { text: "Please summarize the video in 3 sentences." }
];

const response = await ai.models.generateContent({
  model: "gemini-2.0-flash",
  contents: contents,
});
console.log(response.text);

REST

VIDEO_PATH=/path/to/your/video.mp4

if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
  B64FLAGS="--input"
else
  B64FLAGS="-w0"
fi

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
            {
              "inline_data": {
                "mime_type":"video/mp4",
                "data": "'$(base64 $B64FLAGS $VIDEO_PATH)'"
              }
            },
            {"text": "Please summarize the video in 3 sentences."}
        ]
      }]
    }' 2> /dev/null

YouTube の URL を含める

Gemini API と AI Studio は、ファイルデータ Part として YouTube URL をサポートしています。YouTube の URL を、動画コンテンツの要約、翻訳、その他の操作をモデルに指示するプロンプトとともに含めることができます。

制限事項:

  • 1 日にアップロードできる YouTube 動画は 8 時間までです。
  • リクエストごとにアップロードできる動画は 1 本のみです。
  • アップロードできるのは公開動画のみです(非公開動画や限定公開動画はアップロードできません)。

次の例は、プロンプトに YouTube の URL を含める方法を示しています。

Python

response = client.models.generate_content(
    model='models/gemini-2.0-flash',
    contents=types.Content(
        parts=[
            types.Part(
                file_data=types.FileData(file_uri='https://www.youtube.com/watch?v=9hE5-98ZeCg')
            ),
            types.Part(text='Please summarize the video in 3 sentences.')
        ]
    )
)

JavaScript

import { GoogleGenerativeAI } from "@google/generative-ai";

const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro" });
const result = await model.generateContent([
  "Please summarize the video in 3 sentences.",
  {
    fileData: {
      fileUri: "https://www.youtube.com/watch?v=9hE5-98ZeCg",
    },
  },
]);
console.log(result.response.text());

Go

ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GOOGLE_API_KEY")))
if err != nil {
  log.Fatal(err)
}
defer client.Close()

model := client.GenerativeModel("gemini-2.0-flash")
resp, err := model.GenerateContent(ctx,
  genai.FileData{URI: "https://www.youtube.com/watch?v=9hE5-98ZeCg"},
  genai.Text("Please summarize the video in 3 sentences."))
if err != nil {
  log.Fatal(err)
}

// Handle the response of generated text.
for _, c := range resp.Candidates {
  if c.Content != nil {
    fmt.Println(*c.Content)
  }
}

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
            {"text": "Please summarize the video in 3 sentences."},
            {
              "file_data": {
                "file_uri": "https://www.youtube.com/watch?v=9hE5-98ZeCg"
              }
            }
        ]
      }]
    }' 2> /dev/null

コンテンツ内のタイムスタンプを参照する

動画内の特定の時点に関する質問をするには、MM:SS 形式のタイムスタンプを使用します。

Python

prompt = "What are the examples given at 00:05 and 00:10 supposed to show us?" # Adjusted timestamps for the NASA video

JavaScript

const prompt = "What are the examples given at 00:05 and 00:10 supposed to show us?";

Go

    prompt := []genai.Part{
        genai.FileData{URI: currentVideoFile.URI, MIMEType: currentVideoFile.MIMEType},
         // Adjusted timestamps for the NASA video
        genai.Text("What are the examples given at 00:05 and " +
            "00:10 supposed to show us?"),
    }

REST

PROMPT="What are the examples given at 00:05 and 00:10 supposed to show us?"

動画を文字起こしして、視覚的な説明を提供する

Gemini モデルは、音声トラックと映像フレームの両方を処理することで、動画コンテンツの文字起こしを行い、動画コンテンツの視覚的な説明を提供できます。画像の説明の場合、モデルは動画を 1 秒あたり 1 フレームのレートのサンプリングします。このサンプリング レートは、特に映像が急速に変化する動画の場合、説明の詳細レベルに影響する可能性があります。

Python

prompt = "Transcribe the audio from this video, giving timestamps for salient events in the video. Also provide visual descriptions."

JavaScript

const prompt = "Transcribe the audio from this video, giving timestamps for salient events in the video. Also provide visual descriptions.";

Go

    prompt := []genai.Part{
        genai.FileData{URI: currentVideoFile.URI, MIMEType: currentVideoFile.MIMEType},
        genai.Text("Transcribe the audio from this video, giving timestamps for salient events in the video. Also " +
            "provide visual descriptions."),
    }

REST

PROMPT="Transcribe the audio from this video, giving timestamps for salient events in the video. Also provide visual descriptions."

サポートされている動画形式

Gemini は、次の動画形式の MIME タイプをサポートしています。

  • video/mp4
  • video/mpeg
  • video/mov
  • video/avi
  • video/x-flv
  • video/mpg
  • video/webm
  • video/wmv
  • video/3gpp

動画に関する技術的な詳細

  • サポートされているモデルとコンテキスト: Gemini 2.0 と 2.5 のすべてのモデルで動画データを処理できます。
    • 200 万コンテキスト ウィンドウのモデルは最大 2 時間の動画の処理が可能ですが、100 万コンテキスト ウィンドウのモデルは最大 1 時間の動画の処理が可能です。
  • File API による処理: File API を使用する場合、動画は 1 秒あたり 1 フレーム(FPS)でサンプリングされ、音声は 1 Kbps(単一チャネル)で処理されます。タイムスタンプは 1 秒ごとに追加されます。
    • これらのレートは、推論の改善のために今後変更される可能性があります。
  • トークンの計算: 動画の 1 秒間は次のようにトークン化されます。
    • 個々のフレーム(1 FPS でサンプリング): フレームあたり 258 トークン。
    • オーディオ: 1 秒あたり 32 トークン。
    • メタデータも含まれます。
    • 合計: 動画の 1 秒あたり約 300 トークン。
  • タイムスタンプの形式: プロンプト内で動画の特定の部分を参照する場合は、MM:SS 形式を使用します(例: 01:15 は 1 分 15 秒)。
  • ベスト プラクティス:
    • 最適な結果を得るには、プロンプト リクエストごとに 1 つの動画のみを使用します。
    • テキストと 1 つの動画を組み合わせる場合は、contents 配列内の動画部分の後ろにテキスト プロンプトを配置します。
    • 1 FPS のサンプリング レートのため、速いアクション シーケンスでは細部が失われる可能性があります。必要に応じて、そのようなクリップの速度を落とすことを検討してください。

次のステップ

このガイドでは、動画ファイルをアップロードし、動画入力からテキスト出力を生成する方法について説明します。詳細については、次のリソースをご覧ください。

  • システム指示: システム指示を使用すると、特定のニーズやユースケースに基づいてモデルの動作を制御できます。
  • Files API: Gemini で使用するファイルのアップロードと管理の詳細を確認する。
  • ファイル プロンプト戦略: Gemini API は、テキスト、画像、音声、動画データによるプロンプト(マルチモーダル プロンプト)をサポートしています。
  • 安全性に関するガイダンス: 生成 AI モデルは、不正確な出力、バイアスのある出力、不適切な出力など、予期しない出力を生成することがあります。このような出力による被害のリスクを軽減するには、後処理と人間による評価が不可欠です。