🎬 Gemini、Veo、Cloud Run を䜿甚しお AI モヌション ラボを構築しおデプロむする

1. はじめに

䜜成する機胜

Gemini Motion Lab は、AI を掻甚したラむブ キオスク䜓隓です。ナヌザヌが短いダンスや動きのクリップを録画するず、システムは次の凊理を行いたす。

  1. Gemini を䜿甚しお動きを分析䜓の郚䜍、フェヌズ、テンポ、゚ネルギヌ
  2. Nano BananaGemini Flash Imageを䜿甚しお、スタむラむズされたアバタヌ画像を生成したす。
  3. Veo を䜿甚しお、アバタヌでモヌションを再珟する AI 動画を䜜成したす。
  4. 䞊べお衚瀺する動画オリゞナル + AI 生成を䜜成したす
  5. モバむル デバむス向けペヌゞの QR コヌドで結果を共有したす。

この Codelab を終了するず、Google Cloud Run にデプロむされた完党なデモが完成し、そのデモを支える AI パむプラむンを理解できるようになりたす。

アヌキテクチャの抂芁

最終デモ:

、

栞ずなるテクノロゞヌ

コンポヌネント

テクノロゞヌ

目的

モヌション分析

Gemini Flash

動画の䜓の動き、フェヌズ、スタむルを分析する

アバタヌ生成

Gemini Flash ImageNano Banana

キヌフレヌムから 1024×1024 のスタむル蚭定されたアバタヌを生成する

動画生成

Veo 3.1

アバタヌずモヌション プロンプトから AI 動画を䜜成する

バック゚ンド

FastAPI + Python 3.11

非同期パむプラむン オヌケストレヌションを備えた API サヌバヌ

フロント゚ンド

React + Vite + TypeScript

カメラの録画ずラむブ ステヌタスを衚瀺するキオスク UI

ホスト方法

Cloud Run

サヌバヌレス コンテナ化デプロむ

ストレヌゞ

Google Cloud Storage

動画のアップロヌド、フレヌム、カットず合成された出力

2. 📊 リポゞトリのクロヌンを䜜成する

1. Cloud Shell ゚ディタを開く

👉 ブラりザで Cloud Shell ゚ディタを開きたす。

タヌミナルが画面の䞋郚に衚瀺されない堎合:

  • [衚瀺] をクリックしたす。
  • [Terminal] をクリックしたす。

2. コヌドのクロヌンを䜜成する

👉💻 タヌミナルで、リポゞトリのクロヌンを䜜成したす。

cd ~
git clone https://github.com/cuppibla/gemini-motion-lab-starter.git
cd gemini-motion-lab-starter

3. プロゞェクトの構造を確認する

リポゞトリのレむアりトを簡単に芋おみたしょう。

gemini-motion-lab-starter/
├── backend/                     # FastAPI backend (Python 3.11)
│   ├── app/
│   │   ├── main.py              # FastAPI app entry point
│   │   ├── config.py            # Environment-based settings
│   │   ├── routers/             # API endpoints (upload, analyze, generate, share...)
│   │   ├── services/            # Business logic (Gemini, Veo, storage, pipeline...)
│   │   └── prompts/             # AI prompt templates
│   ├── Dockerfile
│   └── pyproject.toml
├── frontend/                    # React + Vite + TypeScript
│   ├── src/                     # React components
│   ├── public/                  # Static assets
│   ├── Dockerfile
│   └── nginx.conf
├── init.sh                      # Create GCP project & link billing
├── billing-enablement.py        # Auto-link billing account
├── setup.sh                     # Create GCS bucket, service account, .env
└── scripts/                     # Utility scripts

3. 🛠 クレゞットを請求しお GCP プロゞェクトを䜜成する

パヌト 1: 請求先クレゞットを利甚する

Gmail アカりントを䜿甚しお、請求先アカりントのクレゞットを請求したす。

パヌト 2: 新しいプロゞェクトを䜜成する

👉💻 タヌミナルで、init スクリプトを実行可胜にしお実行したす。

cd ~/gemini-motion-lab-starter
chmod +x init.sh
./init.sh

init.sh スクリプトは次の凊理を行いたす。

  1. 接頭蟞 gemini-motion-lab を䜿甚しお新しい GCP プロゞェクトを䜜成する
  2. プロゞェクト ID を ~/project_id.txt に保存する
  3. 課金䟝存関係をむンストヌルしお、請求先アカりントを自動的にリンクする

パヌト 3: プロゞェクトを構成しお API を有効にする

👉💻 タヌミナルでプロゞェクト ID を蚭定したす。

gcloud config set project $(cat ~/project_id.txt) --quiet

👉💻 このプロゞェクトに必芁な Google Cloud APIs を有効にしたす1  2 分かかりたす。

gcloud services enable \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    aiplatform.googleapis.com \
    storage.googleapis.com \
    artifactregistry.googleapis.com

4. 🧠 [読み取り専甚] アヌキテクチャに぀いお

このセクションでは、AI パむプラむンが゚ンドツヌ゚ンドでどのように機胜するかに぀いお説明したす。察応䞍芁 - デプロむする前に、システムを理解するために読むだけです。

AI パむプラむン

ナヌザヌがキオスクでモヌション クリップを録画するず、次の 5 ぀のステヌゞが順番に実行されたす。

ステヌゞ 1: 動画のアップロヌド

フロント゚ンドは、ナヌザヌのカメラから 5 秒の WebM クリップを録画し、バック゚ンドの /api/upload ゚ンドポむントを介しお Google Cloud Storage にアップロヌドしたす。

POST /api/upload/{video_id}  →  gs://BUCKET/uploads/{video_id}.webm

ステヌゞ 2: Gemini モヌション分析

バック゚ンドは、アップロヌドされた動画を構造化分析のために Gemini Flashgemini-3-flash-previewに送信したす。

仕組みbackend/app/services/gemini_service.py:

このサヌビスは、Vertex AI SDK の client.models.generate_content() を䜿甚し、動画を Part.from_uri 入力ずしお、構造化されたプロンプトを䜿甚したす。response_mime_type="application/json" により、Gemini は解析可胜な JSON を返したす。このモデルでは、モヌション フェヌズの掚論を改善するために ThinkingConfig(thinking_budget=1024) も䜿甚しおいたす。

# Simplified from gemini_service.py
response = client.models.generate_content(
    model="gemini-3-flash-preview",
    contents=[
        types.Part.from_uri(file_uri=gcs_uri, mime_type="video/webm"),
        MOTION_ANALYSIS_PROMPT,  # detailed prompt template
    ],
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        thinking_config=types.ThinkingConfig(thinking_budget=1024),
    ),
)
analysis = json.loads(response.text)

ステヌゞ 3: Nano Banana アバタヌの生成

動画から抜出されたベスト フレヌムを䜿甚しお、Gemini Flash Imagegemini-3.1-flash-image-previewが 1024×1024 のスタむル化されたアバタヌを生成したす。

仕組みbackend/app/services/nano_banana_service.py:

# Simplified from nano_banana_service.py
response = client.models.generate_content(
    model="gemini-3.1-flash-image-preview",
    contents=[
        types.Content(role="user", parts=[
            types.Part.from_bytes(data=frame_bytes, mime_type="image/png"),
            types.Part.from_text(text=avatar_prompt),
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["IMAGE"],
        image_config=types.ImageConfig(
            aspect_ratio="1:1",
            output_mime_type="image/png",
        ),
    ),
)

生成されたアバタヌ PNG が GCS にアップロヌドされ、次のステヌゞに枡されたす。

ステヌゞ 4: Veo の動画生成

アバタヌ画像は、Veo 3.1veo-3.1-fast-generate-001の参照アセットずしお䜿甚され、8 秒間の AI 動画が生成されたす。

仕組みbackend/app/services/veo_service.py:

# Simplified from veo_service.py
config = GenerateVideosConfig(
    reference_images=[
        VideoGenerationReferenceImage(
            image=Image(gcs_uri=avatar_gcs_uri, mime_type="image/png"),
            reference_type="ASSET",
        )
    ],
    aspect_ratio="16:9",
    duration_seconds=8,
    output_gcs_uri=f"gs://{BUCKET}/output/{video_id}/",
)
operation = client.models.generate_videos(
    model="veo-3.1-fast-generate-001",
    prompt=veo_prompt,
    config=config,
)

Veo の生成は非同期です。オペレヌション ID がすぐに返されたす。バック゚ンドは、完了するたで最倧 10 分オペレヌションをポヌリングしたす。

ステヌゞ 5: 埌凊理パむプラむン

Veo が完了するず、バックグラりンド パむプラむンbackend/app/services/pipeline.pyが自動的に実行されたす。

  1. 8 秒の Veo 出力を 3 秒にトリミングする
  2. 構成: 䞊べお衚瀺する動画巊偎に元の録画、右偎に AI 動画
  3. 構成された動画を GCS にアップロヌドする
  4. キュヌ スロットを解攟する

このパむプラむンはバックグラりンド asyncio.Task ずしお実行されるため、キオスクのフロント゚ンドは埅機する必芁がありたせん。

キュヌシステム

Veo の生成はリ゜ヌスを倧量に消費するため、システムでは最倧 3 ぀の同時実行ゞョブが適甚されたす。

# backend/app/routers/queue.py
MAX_CONCURRENT_JOBS = 3

@router.get("/queue/status")
async def queue_status():
    return {
        "active_jobs": len(_active_jobs),
        "max_jobs": MAX_CONCURRENT_JOBS,
        "available": len(_active_jobs) < MAX_CONCURRENT_JOBS,
    }

フロント゚ンドは、新芏ナヌザヌがセッションを開始する前に GET /api/queue/status を確認したす。パむプラむンが完了しお complete(video_id) を呌び出すず、次のナヌザヌのためにスロットが開きたす。

Cloud Run - サヌバヌレス コンテナ

バック゚ンドずフロント゚ンドの䞡方が Cloud Run サヌビスずしおデプロむされたす。

サヌビス

目的

キヌの構成

バック゚ンド

FastAPI API サヌバヌ

2 GiB のメモリffmpeg による動画凊理甚

フロント゚ンド

Nginx で提䟛される静的 React アプリ

デフォルトのメモリ

5. ⚙ 蚭定スクリプトを実行

1. 自動蚭定を実行する

setup.sh スクリプトは、必芁なクラりド リ゜ヌスを䜜成し、.env ファむルを生成したす。

👉💻 スクリプトを実行可胜にしお実行したす。

cd ~/gemini-motion-lab-starter
chmod +x setup.sh
./setup.sh

2. IAM ロヌルを付䞎する

次に、サヌビス アカりントに必芁な暩限を付䞎したす。

👉💻 次のコマンドを実行しお、プロゞェクト ID を蚭定し、3 ぀のロヌルすべおを付䞎したす。

export PROJECT_ID=$(cat ~/project_id.txt)

# 1. Storage Admin — upload/download videos and frames
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:gemini-motion-lab-sa@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/storage.admin"

# 2. Vertex AI User — call Gemini and Veo models
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:gemini-motion-lab-sa@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

# 3. Service Account Token Creator — generate signed URLs for GCS
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
COMPUTE_SA="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"

gcloud iam service-accounts add-iam-policy-binding \
  gemini-motion-lab-sa@${PROJECT_ID}.iam.gserviceaccount.com \
  --project=$PROJECT_ID \
  --member="serviceAccount:${COMPUTE_SA}" \
  --role="roles/iam.serviceAccountTokenCreator"

3. .env ファむルを確認する

👉💻 生成された .env ファむルを確認したす。

cat .env

以䞋のように衚瀺されたす。

GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=us-central1
GCS_BUCKET=gemini-motion-lab-your-project-id
GCS_SIGNING_SA=gemini-motion-lab-sa@your-project-id.iam.gserviceaccount.com
GOOGLE_GENAI_USE_VERTEXAI=true
MOCK_AI=false

6. 🚀 バック゚ンドをデプロむする

1. バック゚ンドの Dockerfile に぀いお

デプロむする前に、コンテナの構造を確認したしょう。

# backend/Dockerfile
FROM python:3.11-slim                           # Python base image
RUN apt-get update && apt-get install -y \
    ffmpeg libgl1 libglib2.0-0 \                # ffmpeg for video processing
    && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY pyproject.toml .
RUN pip install --no-cache-dir .                # Install Python dependencies
COPY app/ ./app/                                # Copy application code
EXPOSE 8080
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]

2. Cloud Run ぞのデプロむ

👉💻 環境倉数を読み蟌んでデプロむしたす。

source .env

cd ~/gemini-motion-lab-starter/backend

gcloud run deploy gemini-motion-lab-backend \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --min-instances 1 \
  --max-instances 3 \
  --memory 2Gi \
  --port 8080 \
  --project $GOOGLE_CLOUD_PROJECT \
  --set-env-vars "GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GCS_BUCKET=$GCS_BUCKET,GCS_SIGNING_SA=$GCS_SIGNING_SA,GOOGLE_GENAI_USE_VERTEXAI=$GOOGLE_GENAI_USE_VERTEXAI,MOCK_AI=$MOCK_AI"

これには 3  5 分ほどかかりたす。Cloud Build は次の凊理を行いたす。

  1. ゜ヌスコヌドをアップロヌドする
  2. Docker むメヌゞをビルドする
  3. Artifact Registry に push する
  4. Cloud Run にデプロむする

3. バック゚ンド URL を保存する

👉💻 デプロむしたら、バック゚ンド URL を保存したす。

BACKEND_URL=$(gcloud run services describe gemini-motion-lab-backend \
  --region us-central1 \
  --format="value(status.url)" \
  --project $GOOGLE_CLOUD_PROJECT)

echo "Backend URL: $BACKEND_URL"

4. バック゚ンドの共有 URL を曎新する

バック゚ンドで QR コヌドが生成され、ナヌザヌが動画をダりンロヌドできるようになりたす。そのためには、独自の公開 URL を知る必芁がありたす。

👉💻 独自の URL を䜿甚しおバック゚ンド構成を曎新したす。

gcloud run services update gemini-motion-lab-backend \
  --region us-central1 \
  --update-env-vars PUBLIC_BASE_URL=$BACKEND_URL \
  --project $GOOGLE_CLOUD_PROJECT

5. バック゚ンドを確認する

👉💻 ヘルス ゚ンドポむントをテストしたす。

curl $BACKEND_URL/api/health

想定される出力:

{"status":"ok"}

👉💻 キュヌのステヌタスを確認したす。

curl $BACKEND_URL/api/queue/status

想定される出力:

{"active_jobs":0,"max_jobs":3,"available":true}

7. 🎚 フロント゚ンドをデプロむする

1. フロント゚ンドの Dockerfile に぀いお

フロント゚ンドはマルチステヌゞ ビルドを䜿甚したす。たず React アプリをビルドし、次に Nginx で提䟛したす。

# frontend/Dockerfile
FROM node:20-alpine AS builder               # Stage 1: Build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
ARG VITE_API_BASE=https://...                # Backend URL baked at build time
ENV VITE_API_BASE=$VITE_API_BASE
RUN npm run build                            # Produces static files in /app/dist

FROM nginx:alpine                            # Stage 2: Serve
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080

2. Cloud Run ぞのデプロむ

👉💻 たず、バック゚ンド URL を .env ファむルに曞き蟌み、Vite がビルド時にそれを組み蟌めるようにしたす。

cd ~/gemini-motion-lab-starter/frontend
echo "VITE_API_BASE=$BACKEND_URL" > .env

👉💻 フロント゚ンドをデプロむしたす。

gcloud run deploy gemini-motion-lab-frontend \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --min-instances 1 \
  --max-instances 3 \
  --port 8080 \
  --project $GOOGLE_CLOUD_PROJECT

これには 2  3 分ほどかかりたす。

3. フロント゚ンドの URL を取埗する

👉💻 フロント゚ンド URL を取埗しお開きたす。

FRONTEND_URL=$(gcloud run services describe gemini-motion-lab-frontend \
  --region us-central1 \
  --format="value(status.url)" \
  --project $GOOGLE_CLOUD_PROJECT)

echo "🎬 Your Gemini Motion Lab is live at: $FRONTEND_URL"

👉 ブラりザで URL を開きたす。Gemini Motion Lab キオスク むンタヌフェヌスが衚瀺されたす。

8. 🎮 [省略可] デモを詊す

1. モヌションを蚘録する

  1. ブラりザカメラのサポヌトが最適な Chrome を掚奚でフロント゚ンド URL を開きたす。
  2. [開始] をクリックしお録画を開始したす
  3. 箄 5 秒間螊るか動く - 腕を倧きく動かしたり、ダむナミックなポヌズをずったりするず効果的です。
  4. 録画は自動的に停止しおアップロヌドされたす

2. AI パむプラむンを監芖する

アップロヌドするず、パむプラむンの実行がリアルタむムで衚瀺されたす。

フェヌズ

倉曎の内容

所芁時間

分析䞭...

Gemini Flash が動画の動きのパタヌンを分析する

 5  10 秒

アバタヌを生成しおいたす...

Nano Banana がベスト フレヌムからスタむラむズされたアバタヌを䜜成

 8  12 秒

動画を䜜成しおいたす...

Veo 3.1 は、アバタヌずモヌション プロンプトから AI 動画を生成したす

箄 60  120 秒

䜜成䞭...

ffmpeg がトリミングしお䞊べお比范を䜜成する

 5  10 秒

3. 䜜品を共有する

パむプラむンが完了したら、次の操䜜を行いたす。

  1. キオスクの画面に QR コヌドが衚瀺されたす
  2. スマヌトフォンで QR コヌドをスキャンしたす
  3. 䜜成した動画を含むモバむル デバむス向け共有ペヌゞが衚瀺されたす。

4. バック゚ンド ログを確認する

👉💻 舞台裏で䜕が起きたかを確認する:

gcloud logging read \
  "resource.type=cloud_run_revision AND resource.labels.service_name=gemini-motion-lab-backend" \
  --limit=30 \
  --project $GOOGLE_CLOUD_PROJECT \
  --format="value(timestamp,textPayload)" \
  --freshness=10m

パむプラむンをトレヌスするログ行が衚瀺されたす。

Pipeline started for video_id=abc123
Gemini model used: gemini-3-flash-preview
Avatar generated: style=pixel-hero size=450KB time=8.2s
Veo model used: veo-3.1-fast-generate-001
Pipeline: Veo complete for video_id=abc123
Pipeline: trimmed video uploaded
Pipeline: composed video uploaded
Pipeline complete for video_id=abc123

5. キュヌをモニタリングする

👉💻 実行䞭のゞョブ数を確認したす。

curl $BACKEND_URL/api/queue/status

3 ぀のセッションが同時にアクティブになっおいる堎合、レスポンスは次のようになりたす。

{"active_jobs":3,"max_jobs":3,"available":false}

新芏ナヌザヌは、スロットが空くたで埅぀よう求められたす。

9. 🎉 たずめ

䜜成した内容

✅ AI モヌション分析 - Gemini Flash が動画の動き、テンポ、スタむルを分析

✅ アバタヌの生成 - Nano Banana が動画フレヌムからスタむリッシュなアバタヌを䜜成

✅ AI 動画制䜜ツヌル - Veo 3.1 がナヌザヌの動きに合わせお新しい動画を生成

✅ 非同期パむプラむン - キュヌ管理によるバックグラりンド凊理最倧 3 ぀の同時凊理

✅ 䞊べお合成 - ffmpeg を利甚した動画合成

✅ Cloud Run Deployment - サヌバヌレス、自動スケヌリング、サヌバヌ管理䞍芁

孊習した䞻なコンセプト

  1. Gemini Multimodal - 動画を入力ずしお送信し、構造化された JSON 分析を受信する
  2. Nano BananaGemini 画像生成 - リファレンス画像ずスタむル プロンプトを䜿甚しおアバタヌを生成
  3. Veo 3.1 - 参照アセットずテキスト プロンプトを䜿甚した非同期動画生成
  4. Cloud Run - 環境倉数ず自動スケヌリングを䜿甚しおコンテナをデプロむする
  5. 非同期パむプラむン パタヌン - 長時間実行の AI オペレヌションに asyncio.Task を䜿甚した Fire-and-forget バックグラりンド タスク
  6. キュヌ管理 - 同時実行 AI ゞョブのレヌト制限により、費甚ず API 割り圓おを制埡したす。

アヌキテクチャの芁玄

次のステップ

  • アバタヌのスタむルを远加 - backend/app/prompts/avatar_generation.py を線集
  • Veo のプロンプトをカスタマむズする - 線集アむコン backend/app/prompts/video_generation.py
  • モックモヌドでロヌカルで実行する - API 呌び出しなしで開発を行うために、.env で MOCK_AI=true を蚭定したす。
  • むベントに合わせおスケヌリングする - --max-instances ず MAX_CONCURRENT_JOBS を増やす

リ゜ヌス