ā§§. āĻā§āĻŽāĻŋāĻāĻž
āĻāĻĒāύāĻŋ āϝāĻž āϤā§āϰāĻŋ āĻāϰāĻŦā§āύ
āĻā§āĻŽāĻŋāύāĻŋ āĻŽā§āĻļāύ āϞā§āϝāĻžāĻŦ āĻšāϞ⧠āĻāĻāĻāĻŋ āϞāĻžāĻāĻ āĻāĻāĻ-āĻāĻžāϞāĻŋāϤ āĻāĻŋāϝāĻŧāϏā§āĻ āĻ āĻāĻŋāĻā§āĻāϤāĻžāĨ¤ āĻāĻāĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰ⧠āĻāĻāĻāĻŋ āϏāĻāĻā§āώāĻŋāĻĒā§āϤ āύāĻžāĻ āĻŦāĻž āĻāϤāĻŋāϰ āĻā§āϞāĻŋāĻĒ āϰā§āĻāϰā§āĻĄ āĻāϰā§āύ āĻāĻŦāĻ āϏāĻŋāϏā§āĻā§āĻŽāĻāĻŋ:
- āĻā§āĻŽāĻŋāύāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāϤāĻŋāĻŦāĻŋāϧāĻŋ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰ⧠(āĻļāϰā§āϰā§āϰ āĻ āĻā§āĻāĻĒā§āϰāϤā§āϝāĻā§āĻ, āĻĒāϰā§āϝāĻžāϝāĻŧ, āĻāϤāĻŋ, āĻļāĻā§āϤāĻŋ)
- āύā§āϝāĻžāύ⧠āĻŦā§āϝāĻžāύāĻžāύāĻž (āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļ āĻāĻŽā§āĻ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻāĻāĻŋ āĻļā§āϞā§āϝā§āĻā§āϤ āĻ āĻŦāϤāĻžāϰ āĻāĻŋāϤā§āϰ āϤā§āϰāĻŋ āĻāϰ⧠āĨ¤
- Veo āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻāĻāĻŋ AI āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰ⧠āϝāĻž āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰā§āϰ āĻāϤāĻŋāĻŦāĻŋāϧāĻŋāĻā§ āĻĒā§āύāϰāĻžāϝāĻŧ āĻĢā§āĻāĻŋāϝāĻŧā§ āϤā§āϞā§āĨ¤
- āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻāĻāĻāĻŋ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰ⧠(āĻŽā§āϞ + āĻāĻāĻ-āύāĻŋāϰā§āĻŽāĻŋāϤ)
- āĻŽā§āĻŦāĻžāĻāϞ-āĻ āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻāĻĄ āĻĒā§āĻā§ āĻāĻāĻāĻŋ āĻāĻŋāĻāĻāϰ āĻā§āĻĄā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻĢāϞāĻžāĻĢāϞ āĻļā§āϝāĻŧāĻžāϰ āĻāϰ⧠āĨ¤
āĻāĻ āĻā§āĻĄāϞā§āϝāĻžāĻŦāĻāĻŋ āĻļā§āώ āĻāϰāĻžāϰ āĻĒāϰ, āĻāĻĒāύāĻŋ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ- āĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻĄā§āĻŽā§āĻāĻŋ āĻĄā§āĻĒā§āϞāϝāĻŧ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āĻāĻŦāĻ āĻāϰ āĻĒā§āĻāύā§āϰ āĻāĻāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āĻŦā§āĻāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤
āϏā§āĻĨāĻžāĻĒāϤā§āϝā§āϰ āϏāĻāĻā§āώāĻŋāĻĒā§āϤ āĻŦāĻŋāĻŦāϰāĻŖ

āĻā§āĻĄāĻŧāĻžāύā§āϤ āĻĄā§āĻŽā§:

āĻŽā§āϞ āĻĒā§āϰāϝā§āĻā§āϤāĻŋ
āĻāĻĒāĻžāĻĻāĻžāύ | āĻĒā§āϰāϝā§āĻā§āϤāĻŋ | āĻāĻĻā§āĻĻā§āĻļā§āϝ |
āĻāϤāĻŋ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ | āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļ | āĻļāĻžāϰā§āϰāĻŋāĻ āĻ āĻā§āĻāĻāĻā§āĻāĻŋ, āĻĒāϰā§āϝāĻžāϝāĻŧ āĻāĻŦāĻ āĻļā§āϞ⧠āĻŦā§āĻāĻžāϰ āĻāύā§āϝ āĻāĻŋāĻĄāĻŋāĻāĻāĻŋ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰā§āύāĨ¤ |
āĻ āĻŦāϤāĻžāϰ āĻĒā§āϰāĻāύā§āĻŽ | āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļ āĻāĻŽā§āĻ (āύā§āϝāĻžāύ⧠āĻāϞāĻž) | āĻāĻāĻāĻŋ āĻā§ āĻĢā§āϰā§āĻŽ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻļā§āϞā§āĻĒāĻŋāĻ ā§§ā§Ļ⧍ā§ĒÃā§§ā§Ļ⧍ā§Ē āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϤā§āϰāĻŋ āĻāϰā§āύ |
āĻāĻŋāĻĄāĻŋāĻ āĻā§āύāĻžāϰā§āĻļāύ | Veo 3.1 | āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āĻ āĻŽā§āĻļāύ āĻĒā§āϰāĻŽā§āĻĒāĻ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻāĻāĻ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰā§āύ |
āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ | āĻĢāĻžāϏā§āĻāĻāĻĒāĻŋāĻāĻ + āĻĒāĻžāĻāĻĨāύ ā§Š.ā§§ā§§ | āĻ ā§āϝāĻžāϏāĻŋāĻā§āĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ āĻ āϰā§āĻā§āϏā§āĻā§āϰā§āĻļāύ āϏāĻš āĻāĻĒāĻŋāĻāĻ āϏāĻžāϰā§āĻāĻžāϰ |
āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ | āϰāĻŋāĻ ā§āϝāĻžāĻā§āĻ + āĻāĻžāĻāĻ + āĻāĻžāĻāĻĒāϏā§āĻā§āϰāĻŋāĻĒā§āĻ | āĻā§āϝāĻžāĻŽā§āϰāĻž āϰā§āĻāϰā§āĻĄāĻŋāĻ āĻāĻŦāĻ āϞāĻžāĻāĻ āϏā§āĻā§āϝāĻžāĻāĻžāϏ āϏāĻš āĻāĻŋāϝāĻŧāϏā§āĻ UI |
āĻšā§āϏā§āĻāĻŋāĻ | āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ | āϏāĻžāϰā§āĻāĻžāϰāĻŦāĻŋāĻšā§āύ āĻāύā§āĻā§āĻāύāĻžāϰāĻžāĻāĻāĻĄ āĻĄā§āĻĒā§āϞāϝāĻŧāĻŽā§āύā§āĻ |
āϏā§āĻā§āϰā§āĻ | āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϏā§āĻā§āϰā§āĻ | āĻāĻŋāĻĄāĻŋāĻ āĻāĻĒāϞā§āĻĄ, āĻĢā§āϰā§āĻŽ, āĻāĻžāĻāĻāĻžāĻ āĻāϰāĻž āĻāĻŦāĻ āĻāĻŽā§āĻĒā§āĻ āĻāϰāĻž āĻāĻāĻāĻĒā§āĻ |
⧍. đĻ āϰāĻŋāĻĒā§āĻāĻŋāĻāϰāĻŋāĻāĻŋ āĻā§āϞā§āύ āĻāϰā§āύ
ā§§. āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ āĻā§āϞā§āύ
đ āĻāĻĒāύāĻžāϰ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ āĻā§āϞā§āύāĨ¤
āϝāĻĻāĻŋ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞāĻāĻŋ āϏā§āĻā§āϰāĻŋāύā§āϰ āύā§āĻā§ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āύāĻž āĻšāϝāĻŧ:
- āĻāĻŋāĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύ
- āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ
⧍. āĻā§āĻĄāĻāĻŋ āĻā§āϞā§āύ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āϰāĻŋāĻĒā§āĻāĻŋāĻāϰāĻŋāĻāĻŋ āĻā§āϞā§āύ āĻāϰā§āύ:
cd ~
git clone https://github.com/cuppibla/gemini-motion-lab-starter.git
cd gemini-motion-lab-starter
ā§Š. āĻĒā§āϰāĻāϞā§āĻĒā§āϰ āĻāĻžāĻ āĻžāĻŽā§ āĻ āύā§āĻŦā§āώāĻŖ āĻāϰā§āύ
āϰāĻŋāĻĒā§āĻāĻŋāĻāϰāĻŋ āϞā§āĻāĻāĻāĻāĻŋ āĻĻā§āϰā§āϤ āĻĻā§āĻā§ āύāĻŋāύ:
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
ā§Š. đ ī¸ āĻā§āϰā§āĻĄāĻŋāĻ āĻĻāĻžāĻŦāĻŋ āĻāϰā§āύ āĻāĻŦāĻ GCP āĻĒā§āϰāĻā§āĻā§āĻ āϤā§āϰāĻŋ āĻāϰā§āύ
āĻĒāϰā§āĻŦ ā§§: āĻāĻĒāύāĻžāϰ āĻŦāĻŋāϞāĻŋāĻ āĻā§āϰā§āĻĄāĻŋāĻ āĻĻāĻžāĻŦāĻŋ āĻāϰā§āύ
đ āĻāĻĒāύāĻžāϰ Gmail āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻĒāύāĻžāϰ āĻŦāĻŋāϞāĻŋāĻ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻā§āϰ āĻā§āϰā§āĻĄāĻŋāĻ āĻĻāĻžāĻŦāĻŋ āĻāϰā§āύāĨ¤
āĻĒāϰā§āĻŦ ⧍: āĻāĻāĻāĻŋ āύāϤā§āύ āĻĒā§āϰāĻāϞā§āĻĒ āϤā§āϰāĻŋ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, init āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋāĻā§ āĻāĻā§āϏāĻŋāĻāĻŋāĻāĻā§āĻŦāϞ āĻāϰ⧠āĻāĻžāϞāĻžāύ:
cd ~/gemini-motion-lab-starter
chmod +x init.sh
./init.sh
init.sh āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋ āϝāĻž āĻāϰāĻŦā§:
-
gemini-motion-labāĻĒā§āϰāĻŋāĻĢāĻŋāĻā§āϏ āĻĻāĻŋāϝāĻŧā§ āĻāĻāĻāĻŋ āύāϤā§āύ GCP āĻĒā§āϰāĻā§āĻā§āĻ āϤā§āϰāĻŋ āĻāϰā§āύāĨ¤ - āĻĒā§āϰāĻā§āĻā§āĻ āĻāĻāĻĄāĻŋāĻāĻŋ
~/project_id.txtāĻĢāĻžāĻāϞ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āύāĨ¤ - āĻŦāĻŋāϞāĻŋāĻ āύāĻŋāϰā§āĻāϰāϤāĻž āĻāύāϏā§āĻāϞ āĻāϰā§āύ āĻāĻŦāĻ āĻāĻĒāύāĻžāϰ āĻŦāĻŋāϞāĻŋāĻ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻ āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ āϞāĻŋāĻā§āĻ āĻāϰā§āύ
āĻĒāϰā§āĻŦ ā§Š: āĻĒā§āϰāĻā§āĻā§āĻ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰā§āύ āĻāĻŦāĻ āĻāĻĒāĻŋāĻāĻ āϏāĻā§āϰāĻŋāϝāĻŧ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻā§āĻā§āĻ āĻāĻāĻĄāĻŋ āϏā§āĻ āĻāϰā§āύ:
gcloud config set project $(cat ~/project_id.txt) --quiet
đđģ āĻāĻ āĻĒā§āϰā§āĻā§āĻā§āĻā§āϰ āĻāύā§āϝ āĻĒā§āϰāϝāĻŧā§āĻāύā§āϝāĻŧ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āĻāĻĒāĻŋāĻāĻāĻā§āϞ⧠āϏāĻā§āϰāĻŋāϝāĻŧ āĻāϰā§āύ (āĻāϤ⧠āĻĒā§āϰāĻžāϝāĻŧ ā§§-⧍ āĻŽāĻŋāύāĻŋāĻ āϏāĻŽāϝāĻŧ āϞāĻžāĻāĻŦā§):
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
storage.googleapis.com \
artifactregistry.googleapis.com
ā§Ē. đ§ [āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻĒāĻžāĻ ā§āϰ āĻāύā§āϝ] āϏā§āĻĨāĻžāĻĒāϤā§āϝ āĻŦā§āĻāĻž
āĻāĻ āĻ āĻāĻļā§ āĻāĻāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āĻļā§āϰ⧠āĻĨā§āĻā§ āĻļā§āώ āĻĒāϰā§āϝāύā§āϤ āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰ⧠āϤāĻž āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤ āĻā§āύ⧠āĻĒāĻĻāĻā§āώā§āĻĒ āύā§āĻāϝāĻŧāĻžāϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻ â āĻĄā§āĻĒā§āϞāϝāĻŧ āĻāϰāĻžāϰ āĻāĻā§ āϏāĻŋāϏā§āĻā§āĻŽāĻāĻŋ āĻŦā§āĻāĻžāϰ āĻāύā§āϝ āĻļā§āϧ⧠āĻĒāĻĄāĻŧā§āύāĨ¤
āĻāĻāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ
āϝāĻāύ āĻā§āύ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰ⧠āĻāĻŋāϝāĻŧāϏā§āĻā§ āĻāĻāĻāĻŋ āĻŽā§āĻļāύ āĻā§āϞāĻŋāĻĒ āϰā§āĻāϰā§āĻĄ āĻāϰā§āύ, āϤāĻāύ āĻĒāĻžāĻāĻāĻāĻŋ āĻĒāϰā§āϝāĻžāϝāĻŧ āĻā§āϰāĻŽāĻžāύā§āϏāĻžāϰ⧠āĻāϞā§:

āĻĒāϰā§āϝāĻžāϝāĻŧ ā§§: āĻāĻŋāĻĄāĻŋāĻ āĻāĻĒāϞā§āĻĄ
āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻā§āϝāĻžāĻŽā§āϰāĻž āĻĨā§āĻā§ āĻāĻāĻāĻŋ ā§Ģ-āϏā§āĻā§āύā§āĻĄā§āϰ WebM āĻā§āϞāĻŋāĻĒ āϰā§āĻāϰā§āĻĄ āĻāϰ⧠āĻāĻŦāĻ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄā§āϰ /api/upload āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āϏā§āĻāĻŋ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϏā§āĻā§āϰā§āĻā§ āĻāĻĒāϞā§āĻĄ āĻāϰā§āĨ¤
POST /api/upload/{video_id} â gs://BUCKET/uploads/{video_id}.webm
āĻĒāϰā§āϝāĻžāϝāĻŧ ⧍: āĻŽāĻŋāĻĨā§āύ āϰāĻžāĻļāĻŋāϰ āĻāϤāĻŋ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ
āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž āĻāĻŋāĻĄāĻŋāĻāĻāĻŋāĻā§ āĻāĻžāĻ āĻžāĻŽā§āĻāϤ āĻŦāĻŋāĻļā§āϞā§āώāĻŖā§āϰ āĻāύā§āϝ āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļā§ ( 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)
āĻĒāϰā§āϝāĻžāϝāĻŧ ā§Š: āύā§āϝāĻžāύ⧠āĻāϞāĻž āĻ āĻŦāϤāĻžāϰ āϤā§āϰāĻŋ
āĻāĻŋāĻĄāĻŋāĻ āĻĨā§āĻā§ āύā§āĻāϝāĻŧāĻž āϏā§āϰāĻž āĻĢā§āϰā§āĻŽāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§, āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļ āĻāĻŽā§āĻ ( gemini-3.1-flash-image-preview ) āĻāĻāĻāĻŋ ā§§ā§Ļ⧍ā§ĒÃā§§ā§Ļ⧍ā§Ē āϏā§āĻāĻžāĻāϞāĻžāĻāĻāĻĄ āĻ
ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϤā§āϰāĻŋ āĻāϰā§āĨ¤
āĻāĻāĻŋ āϝā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰ⧠( 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-āĻ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž āĻšāϝāĻŧ āĻāĻŦāĻ āĻĒāϰāĻŦāϰā§āϤ⧠āϧāĻžāĻĒā§ āĻĒāĻžāĻ āĻžāύ⧠āĻšāϝāĻŧāĨ¤
āĻĒāϰā§āϝāĻžāϝāĻŧ ā§Ē: āĻāĻŋāĻ āĻāĻŋāĻĄāĻŋāĻ āĻā§āύāĻžāϰā§āĻļāύ
ā§Ž-āϏā§āĻā§āύā§āĻĄā§āϰ āĻāĻāĻāĻŋ āĻāĻāĻ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰāĻžāϰ āĻāύā§āϝ āĻ
ā§āϝāĻžāĻāĻžāĻāĻžāϰ āĻāĻŦāĻŋāĻāĻŋ Veo 3.1 ( veo-3.1-fast-generate-001 )-āĻāϰ āϰā§āĻĢāĻžāϰā§āύā§āϏ āĻ
ā§āϝāĻžāϏā§āĻ āĻšāĻŋāϏā§āĻŦā§ āĻŦā§āϝāĻŦāĻšā§āϤ āĻšāϝāĻŧāĨ¤
āĻāĻāĻŋ āϝā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰ⧠( 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 āĻā§āύāĻžāϰā§āĻļāύ āĻ ā§āϝāĻžāϏāĻŋāĻā§āĻā§āϰā§āύāĻžāϏ â āĻāĻāĻŋ āϤāĻžā§āĻā§āώāĻŖāĻŋāĻāĻāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻ āĻĒāĻžāϰā§āĻļāύ āĻāĻāĻĄāĻŋ āϰāĻŋāĻāĻžāϰā§āύ āĻāϰā§āĨ¤ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻ āĻĒāĻžāϰā§āĻļāύāĻāĻŋ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āύāĻž āĻšāĻāϝāĻŧāĻž āĻĒāϰā§āϝāύā§āϤ (āϏāϰā§āĻŦā§āĻā§āĻ ā§§ā§Ļ āĻŽāĻŋāύāĻŋāĻ āĻĒāϰā§āϝāύā§āϤ) āĻĒā§āϞ āĻāϰāϤ⧠āĻĨāĻžāĻā§āĨ¤
āĻĒāϰā§āϝāĻžāϝāĻŧ ā§Ģ: āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāϰāĻŖ-āĻĒāϰāĻŦāϰā§āϤ⧠āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ
Veo-āĻāϰ āĻāĻžāĻ āĻļā§āώ āĻšāϞā§, āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ ( backend/app/services/pipeline.py ) āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ āĻāĻžāϞ⧠āĻšāϝāĻŧ:
- ā§Ž āϏā§āĻā§āύā§āĻĄā§āϰ Veo āĻāĻāĻāĻĒā§āĻāĻāĻŋ āĻāĻŽāĻŋāϝāĻŧā§ ā§Š āϏā§āĻā§āύā§āĻĄ āĻāϰā§āύāĨ¤
- āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻāĻāĻāĻŋ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰā§āύ (āĻŦāĻžāĻŽā§ āĻŽā§āϞ āϰā§āĻāϰā§āĻĄāĻŋāĻ, āĻĄāĻžāύ⧠āĻāĻāĻ āĻāĻŋāĻĄāĻŋāĻ)
- āϤā§āϰāĻŋ āĻāϰāĻž āĻāĻŋāĻĄāĻŋāĻāĻāĻŋ GCS-āĻ āĻāĻĒāϞā§āĻĄ āĻāϰā§āύ āĨ¤
- āĻāĻŋāĻ āϏā§āϞāĻāĻāĻŋ āĻāĻžāϞāĻŋ āĻāϰā§āύ
āĻāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āĻāĻāĻāĻŋ āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ asyncio.Task āĻšāĻŋāϏā§āĻŦā§ āĻāϞ⧠â āĻāĻŋāϝāĻŧāϏā§āĻ āĻĢā§āϰāύā§āĻāĻāύā§āĻĄāĻā§ āĻ
āĻĒā§āĻā§āώāĻž āĻāϰāϤ⧠āĻšāϝāĻŧ āύāĻžāĨ¤
āϏāĻžāϰāĻŋ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž
āϝā§āĻšā§āϤ⧠Veo āϤā§āϰāĻŋ āĻāϰāĻž āĻāĻāĻāĻŋ āϏāĻŽā§āĻĒāĻĻ-āύāĻŋāĻŦāĻŋāĻĄāĻŧ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž, āϤāĻžāĻ āϏāĻŋāϏā§āĻā§āĻŽāĻāĻŋ āĻāĻāϝā§āĻā§ āϏāϰā§āĻŦā§āĻā§āĻ ā§ŠāĻāĻŋ āĻāĻžāĻ āĻāĻžāϞāĻžāύā§āϰ āύāĻŋāϝāĻŧāĻŽ āĻāϰā§āĻĒ āĻāϰā§:
# 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) āĻāϞ āĻāϰā§, āϤāĻāύ āĻĒāϰāĻŦāϰā§āϤ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāύā§āϝ āϏā§āϞāĻāĻāĻŋ āĻā§āϞ⧠āϝāĻžāϝāĻŧāĨ¤
āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ â āϏāĻžāϰā§āĻāĻžāϰāĻŦāĻŋāĻšā§āύ āĻāύā§āĻā§āĻāύāĻžāϰ
āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻāĻŦāĻ āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ āĻāĻāϝāĻŧāĻ āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ āĻĒāϰāĻŋāώā§āĻŦāĻž āĻšāĻŋāϏāĻžāĻŦā§ āϏā§āĻĨāĻžāĻĒāύ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§:
āĻĒāϰāĻŋāώā§āĻŦāĻž | āĻāĻĻā§āĻĻā§āĻļā§āϝ | āĻŽā§āϞ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ |
āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ | āĻĢāĻžāϏā§āĻāĻāĻĒāĻŋāĻāĻ āĻāĻĒāĻŋāĻāĻ āϏāĻžāϰā§āĻāĻžāϰ | ⧍ āĻāĻŋāĻŦāĻŋ āĻŽā§āĻŽāϰāĻŋ (ffmpeg-āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻŋāĻĄāĻŋāĻ āĻĒā§āϰāϏā§āϏāĻŋāĻāϝāĻŧā§āϰ āĻāύā§āϝ) |
āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ | Nginx āĻĻā§āĻŦāĻžāϰāĻž āĻĒāϰāĻŋāĻŦā§āĻļāĻŋāϤ āϏā§āĻā§āϝāĻžāĻāĻŋāĻ āϰāĻŋāϝāĻŧā§āϝāĻžāĻā§āĻ āĻ ā§āϝāĻžāĻĒ | āĻĄāĻŋāĻĢāϞā§āĻ āĻŽā§āĻŽāϰāĻŋ |
ā§Ģ. âī¸ āϏā§āĻāĻāĻĒ āϏā§āĻā§āϰāĻŋāĻĒā§āĻ āĻāĻžāϞāĻžāύ
ā§§. āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧ āϏā§āĻāĻāĻĒāĻāĻŋ āĻāĻžāϞāĻžāύ
setup.sh āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋ āĻĒā§āϰāϝāĻŧā§āĻāύā§āϝāĻŧ āĻā§āϞāĻžāĻāĻĄ āϰāĻŋāϏā§āϰā§āϏ āϤā§āϰāĻŋ āĻāϰ⧠āĻāĻŦāĻ āĻāĻĒāύāĻžāϰ .env āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āύāĻžāϰā§āĻ āĻāϰā§āĨ¤
đđģ āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋāĻā§ āĻāĻā§āϏāĻŋāĻāĻŋāĻāĻā§āĻŦāϞ āĻāϰ⧠āĻāĻžāϞāĻžāύ:
cd ~/gemini-motion-lab-starter
chmod +x setup.sh
./setup.sh
⧍. āĻāĻāĻāĻāĻŽ āĻā§āĻŽāĻŋāĻāĻž āĻŽāĻā§āĻā§āϰ āĻāϰā§āύ
āĻāĻāύ āϏāĻžāϰā§āĻāĻŋāϏ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻāĻāĻŋāĻā§ āĻĒā§āϰāϝāĻŧā§āĻāύā§āϝāĻŧ āĻ āύā§āĻŽāϤāĻŋāĻā§āϞ⧠āĻĒā§āϰāĻĻāĻžāύ āĻāϰā§āύāĨ¤
đđģ āĻāĻĒāύāĻžāϰ āĻĒā§āϰā§āĻā§āĻā§āĻ āĻāĻāĻĄāĻŋ āϏā§āĻ āĻāϰāϤ⧠āĻāĻŦāĻ āϤāĻŋāύāĻāĻŋ āϰā§āϞāĻ āĻĒā§āϰāĻĻāĻžāύ āĻāϰāϤ⧠āύāĻŋāĻā§āϰ āĻāĻŽāĻžāύā§āĻĄāĻā§āϞ⧠āĻāĻžāϞāĻžāύ:
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"
ā§Š. āĻāĻĒāύāĻžāϰ .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
ā§Ŧ. đ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻĄāĻŋāĻĒā§āϞāϝāĻŧ āĻāϰā§āύ
ā§§. āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻĄāĻāĻžāϰāĻĢāĻžāĻāϞāĻāĻŋ āĻŦā§āĻā§āύ
āĻĄāĻŋāĻĒā§āϞāϝāĻŧ āĻāϰāĻžāϰ āĻāĻā§, āĻāϞā§āύ āĻā§āύ⧠āύā§āĻāϝāĻŧāĻž āϝāĻžāĻ āĻāύā§āĻā§āĻāύāĻžāϰāĻāĻŋ āĻĻā§āĻāϤ⧠āĻā§āĻŽāύ:
# 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"]
⧍. āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ⧠āϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ
đđģ āĻāĻĒāύāĻžāϰ āĻāύāĻāĻžāϝāĻŧāϰāύāĻŽā§āύā§āĻ āĻā§āϰāĻŋāϝāĻŧā§āĻŦāϞāĻā§āϞ⧠āϞā§āĻĄ āĻāϰā§āύ āĻāĻŦāĻ āĻĄāĻŋāĻĒā§āϞāϝāĻŧ āĻāϰā§āύ:
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"
āĻāϤ⧠āĻĒā§āϰāĻžāϝāĻŧ ā§Š-ā§Ģ āĻŽāĻŋāύāĻŋāĻ āϏāĻŽāϝāĻŧ āϞāĻžāĻā§āĨ¤ āĻā§āϞāĻžāĻāĻĄ āĻŦāĻŋāϞā§āĻĄ āϝāĻž āĻāϰāĻŦā§:
- āĻāĻĒāύāĻžāϰ āϏā§āϰā§āϏ āĻā§āĻĄ āĻāĻĒāϞā§āĻĄ āĻāϰā§āύ
- āĻĄāĻāĻžāϰ āĻāĻŽā§āĻ āϤā§āϰāĻŋ āĻāϰā§āύ
- āĻāϰā§āĻāĻŋāĻĢā§āϝāĻžāĻā§āĻ āϰā§āĻāĻŋāϏā§āĻā§āϰāĻŋ-āϤ⧠āĻāĻāĻŋ āĻĒā§āĻļ āĻāϰā§āύ
- āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ⧠āĻāĻāĻŋ āϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ
ā§Š. āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻāĻāĻāϰāĻāϞāĻāĻŋ āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āύāĨ¤
đđģ āĻĄā§āĻĒā§āϞāϝāĻŧ āĻāϰāĻžāϰ āĻĒāϰ, āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ 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"
ā§Ē. āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻļā§āϝāĻŧāĻžāϰ āĻāĻāĻāϰāĻāϞ āĻāĻĒāĻĄā§āĻ āĻāϰā§āύ
āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻāĻŋāĻāĻāϰ āĻā§āĻĄ āϤā§āϰāĻŋ āĻāϰā§, āϝāĻžāϤ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰāĻž āϤāĻžāĻĻā§āϰ āĻāĻŋāĻĄāĻŋāĻ āĻĄāĻžāĻāύāϞā§āĻĄ āĻāϰāϤ⧠āĻĒāĻžāϰā§āĨ¤ āĻāĻ āĻāĻžāĻāĻāĻŋ āĻāϰāĻžāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄāĻāĻŋāϰ āύāĻŋāĻā§āϰ āĻĒāĻžāĻŦāϞāĻŋāĻ āĻāĻāĻāϰāĻāϞ āĻāĻžāύāĻž āĻĒā§āϰāϝāĻŧā§āĻāύāĨ¤
đđģ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύāĻāĻŋ āĻāϰ āύāĻŋāĻāϏā§āĻŦ URL āĻĻāĻŋāϝāĻŧā§ āĻāĻĒāĻĄā§āĻ āĻāϰā§āύ:
gcloud run services update gemini-motion-lab-backend \
--region us-central1 \
--update-env-vars PUBLIC_BASE_URL=$BACKEND_URL \
--project $GOOGLE_CLOUD_PROJECT
ā§Ģ. āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āϝāĻžāĻāĻžāĻ āĻāϰā§āύ
đđģ āϏā§āĻŦāĻžāϏā§āĻĨā§āϝāĻāϤ āĻĢāϞāĻžāĻĢāϞ āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ:
curl $BACKEND_URL/api/health
āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āĻāĻāĻāĻĒā§āĻ:
{"status":"ok"}
đđģ āϏāĻžāϰāĻŋāϰ āĻ āĻŦāϏā§āĻĨāĻž āĻĻā§āĻā§āύ:
curl $BACKEND_URL/api/queue/status
āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āĻāĻāĻāĻĒā§āĻ:
{"active_jobs":0,"max_jobs":3,"available":true}
ā§. đ¨ āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ āĻĄāĻŋāĻĒā§āϞāϝāĻŧ āĻāϰā§āύ
ā§§. āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ āĻĄāĻāĻžāϰāĻĢāĻžāĻāϞāĻāĻŋ āĻŦā§āĻā§āύ
āĻĢā§āϰāύā§āĻāĻāύā§āĻĄāĻāĻŋ āĻāĻāĻāĻŋ āĻŦāĻšā§-āĻĒāϰā§āϝāĻžāϝāĻŧā§āϰ āĻŦāĻŋāϞā§āĻĄ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠â āĻĒā§āϰāĻĨāĻŽā§ 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
⧍. āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ⧠āϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ
đđģ āĻĒā§āϰāĻĨāĻŽā§, āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ 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
āĻāϤ⧠āĻĒā§āϰāĻžāϝāĻŧ ⧍-ā§Š āĻŽāĻŋāύāĻŋāĻ āϏāĻŽāϝāĻŧ āϞāĻžāĻā§āĨ¤
ā§Š. āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ āĻāĻāĻāϰāĻāϞāĻāĻŋ āύāĻŋāύāĨ¤
đđģ āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ 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-āĻāĻŋ āĻā§āϞā§āύ â āĻāĻĒāύāĻŋ āĻā§āĻŽāĻŋāύāĻŋ āĻŽā§āĻļāύ āϞā§āϝāĻžāĻŦ āĻāĻŋāϝāĻŧāϏā§āĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ!
ā§Ž. đŽ [āĻāĻā§āĻāĻŋāĻ] āĻĄā§āĻŽā§āĻāĻŋ āĻĻāĻŋāϝāĻŧā§ āĻā§āϞā§āύ
ā§§. āĻāĻāĻāĻŋ āĻĒā§āϰāϏā§āϤāĻžāĻŦ āύāĻĨāĻŋāĻā§āĻā§āϤ āĻāϰā§āύ
- āĻāĻĒāύāĻžāϰ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ āĻāĻāĻāϰāĻāϞāĻāĻŋ āĻā§āϞā§āύ (āϏā§āϰāĻž āĻā§āϝāĻžāĻŽā§āϰāĻž āϏāĻžāĻĒā§āϰā§āĻā§āϰ āĻāύā§āϝ āĻā§āϰā§āĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻļā§āϰā§āϝāĻŧ)āĨ¤
- āϰā§āĻāϰā§āĻĄāĻŋāĻ āĻļā§āϰ⧠āĻāϰāϤ⧠āϏā§āĻāĻžāϰā§āĻ-āĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύāĨ¤
- āĻĒā§āϰāĻžāϝāĻŧ ā§Ģ āϏā§āĻā§āύā§āĻĄ āϧāϰ⧠āύāĻžāĻā§āύ āĻŦāĻž āύāĻĄāĻŧāĻžāĻāĻĄāĻŧāĻž āĻāϰā§āύ â āĻāϤ⧠āĻšāĻžāϤā§āϰ āĻŦāĻĄāĻŧ āĻŦāĻĄāĻŧ āύāĻĄāĻŧāĻžāĻāĻĄāĻŧāĻž āĻāĻŦāĻ āĻāϤāĻŋāĻļā§āϞ āĻāĻā§āĻāĻŋ āϏāĻŦāĻā§āϝāĻŧā§ āĻāĻžāϞ⧠āĻāĻžāĻ āĻāϰā§āĨ¤
- āϰā§āĻāϰā§āĻĄāĻŋāĻ āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ āĻŦāύā§āϧ āĻšāϝāĻŧā§ āĻāĻĒāϞā§āĻĄ āĻšāĻŦā§āĨ¤
⧍. āĻāĻāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ āĻĒāϰā§āϝāĻŦā§āĻā§āώāĻŖ āĻāϰā§āύ
āĻāĻĒāϞā§āĻĄ āĻāϰāĻžāϰ āĻĒāϰā§, āĻāĻĒāύāĻŋ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āϰāĻŋāϝāĻŧā§āϞ āĻāĻžāĻāĻŽā§ āĻāϞāϤ⧠āĻĻā§āĻāĻŦā§āύ:
āĻĒāϰā§āϝāĻžāϝāĻŧ | āĻā§ āĻāĻāĻā§ | āϏāĻŽāϝāĻŧāĻāĻžāϞ |
āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰāĻž āĻšāĻā§āĻā§... | āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļ āĻāĻĒāύāĻžāϰ āĻāĻŋāĻĄāĻŋāĻāϤ⧠āĻāϤāĻŋāĻŦāĻŋāϧāĻŋāϰ āϧāϰāĻŖ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰā§āĨ¤ | ~ā§Ģ-ā§§ā§Ļ āϏā§āĻā§āύā§āĻĄ |
āĻ āĻŦāϤāĻžāϰ āϤā§āϰāĻŋ āĻšāĻā§āĻā§... | āύā§āϝāĻžāύ⧠āĻŦā§āϝāĻžāύāĻžāύāĻž āĻāĻĒāύāĻžāϰ āϏā§āϰāĻž āĻĢā§āϰā§āĻŽ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āϏā§āĻāĻžāĻāϞāĻŋāĻļ āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϤā§āϰāĻŋ āĻāϰā§āĨ¤ | ~ā§Ž-⧧⧍ āϏā§āĻā§āύā§āĻĄ |
āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰāĻž āĻšāĻā§āĻā§... | Veo 3.1 āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āĻ āĻŽā§āĻļāύ āĻĒā§āϰāĻŽā§āĻĒāĻ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻāĻāĻ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰā§āĨ¤ | ~ā§Ŧā§Ļ-⧧⧍ā§Ļ āϏā§āĻā§āύā§āĻĄ |
āϰāĻāύāĻž āĻāϰāĻž... | ffmpeg āĻāĻžāĻāĻāĻžāĻ āĻāϰ⧠āĻāĻŦāĻ āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āϤā§āϞāύāĻž āϤā§āϰāĻŋ āĻāϰā§āĨ¤ | ~ā§Ģ-ā§§ā§Ļ āϏā§āĻā§āύā§āĻĄ |
ā§Š. āĻāĻĒāύāĻžāϰ āϏā§āώā§āĻāĻŋ āĻļā§āϝāĻŧāĻžāϰ āĻāϰā§āύ
āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻšāϞā§:
- āĻāĻŋāϝāĻŧāϏā§āĻ āϏā§āĻā§āϰāĻŋāύ⧠āĻāĻāĻāĻŋ āĻāĻŋāĻāĻāϰ āĻā§āĻĄ āĻĻā§āĻāĻž āϝāĻžāϝāĻŧāĨ¤
- āĻāĻĒāύāĻžāϰ āĻĢā§āύ āĻĻāĻŋāϝāĻŧā§ āĻāĻŋāĻāĻāϰ āĻā§āĻĄāĻāĻŋ āϏā§āĻā§āϝāĻžāύ āĻāϰā§āύāĨ¤
- āĻāĻĒāύāĻŋ āĻāĻĒāύāĻžāϰ āϤā§āϰāĻŋ āĻāϰāĻž āĻāĻŋāĻĄāĻŋāĻ āϏāĻš āĻāĻāĻāĻŋ āĻŽā§āĻŦāĻžāĻāϞ-āĻ āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻāĻĄ āĻļā§āϝāĻŧāĻžāϰ āĻĒā§āĻ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύāĨ¤
ā§Ē. āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āϞāĻāĻā§āϞ⧠āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ
đđģ āĻĻā§āĻā§āύ āύā§āĻĒāĻĨā§āϝ⧠āĻā§ āĻāĻā§āĻāĻŋāϞ:
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
ā§Ģ. āϏāĻžāϰāĻŋāĻāĻŋ āĻĒāϰā§āϝāĻŦā§āĻā§āώāĻŖ āĻāϰā§āύ
đđģ āĻāϤāĻā§āϞ⧠āĻāĻžāĻ āĻāϞāĻā§ āϤāĻž āĻĻā§āĻā§āύ:
curl $BACKEND_URL/api/queue/status
āϝāĻĻāĻŋ āĻāĻāĻ āϏāĻžāĻĨā§ ā§ŠāĻāĻŋ āϏā§āĻļāύ āϏāĻā§āϰāĻŋāϝāĻŧ āĻĨāĻžāĻā§, āϤāĻžāĻšāϞ⧠āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻžāĻāĻŋ āύāĻŋāĻŽā§āύāϰā§āĻĒ āĻšāĻŦā§:
{"active_jobs":3,"max_jobs":3,"available":false}
āύāϤā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āĻĻā§āϰ āĻāĻāĻāĻŋ āϏā§āϞāĻ āĻāĻžāϞāĻŋ āĻšāĻāϝāĻŧāĻž āĻĒāϰā§āϝāύā§āϤ āĻ āĻĒā§āĻā§āώāĻž āĻāϰāϤ⧠āĻŦāϞāĻž āĻšāĻŦā§āĨ¤
⧝. đ āĻāĻĒāϏāĻāĻšāĻžāϰ
āĻāĻĒāύāĻŋ āϝāĻž āϤā§āϰāĻŋ āĻāϰā§āĻā§āύ
â āĻāĻāĻ āĻŽā§āĻļāύ āĻ ā§āϝāĻžāύāĻžāϞāĻžāĻāϏāĻŋāϏ â āĻā§āĻŽāĻŋāύāĻŋ āĻĢā§āϞā§āϝāĻžāĻļ āĻāĻŋāĻĄāĻŋāĻāϰ āĻāϤāĻŋ, āĻāύā§āĻĻ āĻāĻŦāĻ āĻļā§āϞ⧠āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰā§āĨ¤
â āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϤā§āϰāĻŋ â āύā§āϝāĻžāύ⧠āĻŦā§āϝāĻžāύāĻžāύāĻž āĻāĻŋāĻĄāĻŋāĻ āĻĢā§āϰā§āĻŽ āĻĨā§āĻā§ āϏā§āĻāĻžāĻāϞāĻŋāĻļ āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϤā§āϰāĻŋ āĻāϰā§
â āĻāĻāĻ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ â Veo 3.1 āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāϤāĻŋāĻŦāĻŋāϧāĻŋāϰ āϏāĻžāĻĨā§ āĻŽāĻŋāϞāĻŋāϝāĻŧā§ āύāϤā§āύ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰā§āĨ¤
â āĻ ā§āϝāĻžāϏāĻŋāĻā§āĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ â āĻāĻŋāĻ āĻŽā§āϝāĻžāύā§āĻāĻŽā§āύā§āĻ āϏāĻš āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ āĻĒā§āϰāϏā§āϏāĻŋāĻ (āĻāĻāϏāĻžāĻĨā§ āϏāϰā§āĻŦā§āĻā§āĻ ā§ŠāĻāĻŋ)
â āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻāĻŽā§āĻĒā§āĻāĻŋāĻļāύ â āĻāĻĢāĻāĻĢāĻāĻŽāĻĒāĻŋāĻāĻāĻŋ-āĻāĻžāϞāĻŋāϤ āĻāĻŋāĻĄāĻŋāĻ āĻāĻŽā§āĻĒā§āĻāĻŋāĻāĻŋāĻ
â āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ āĻĄā§āĻĒā§āϞāϝāĻŧāĻŽā§āύā§āĻ â āϏāĻžāϰā§āĻāĻžāϰāĻŦāĻŋāĻšā§āύ, āĻ āĻā§-āϏā§āĻā§āϞāĻŋāĻ, āĻā§āύ⧠āϏāĻžāϰā§āĻāĻžāϰ āĻŦā§āϝāĻŦāϏā§āĻĨāĻžāĻĒāύāĻžāϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻ
āĻāĻĒāύāĻŋ āϝ⧠āĻŽā§āϞ āϧāĻžāϰāĻŖāĻžāĻā§āϞ⧠āĻļāĻŋāĻā§āĻā§āύ
- āĻā§āĻŽāĻŋāύāĻŋ āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ â āĻāύāĻĒā§āĻ āĻšāĻŋāϏāĻžāĻŦā§ āĻāĻŋāĻĄāĻŋāĻ āĻĒā§āϰā§āϰāĻŖ āĻāĻŦāĻ āĻāĻžāĻ āĻžāĻŽā§āĻāϤ JSON āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻā§āϰāĻšāĻŖ
- āύā§āϝāĻžāύ⧠āĻŦāĻžāύāĻžāύāĻž (āĻā§āĻŽāĻŋāύāĻŋ āĻāĻŽā§āĻ āĻā§āύāĻžāϰā§āĻļāύ) â āϰā§āĻĢāĻžāϰā§āύā§āϏ āĻāĻŽā§āĻ āĻ āϏā§āĻāĻžāĻāϞ āĻĒā§āϰāĻŽā§āĻĒāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻ ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϤā§āϰāĻŋ āĻāϰāĻž
- Veo 3.1 â āϰā§āĻĢāĻžāϰā§āύā§āϏ āĻ ā§āϝāĻžāϏā§āĻ āĻāĻŦāĻ āĻā§āĻā§āϏāĻ āĻĒā§āϰāĻŽā§āĻĒāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻ ā§āϝāĻžāϏāĻŋāĻā§āĻā§āϰā§āύāĻžāϏ āĻāĻŋāĻĄāĻŋāĻ āϤā§āϰāĻŋ
- āĻā§āϞāĻžāĻāĻĄ āϰāĻžāύ â āĻāύāĻāĻžāϝāĻŧāϰāύāĻŽā§āύā§āĻ āĻā§āϰāĻŋāϝāĻŧā§āĻŦāϞ āĻāĻŦāĻ āĻ āĻā§-āϏā§āĻā§āϞāĻŋāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāύā§āĻā§āĻāύāĻžāϰ āĻĄā§āĻĒā§āϞāϝāĻŧ āĻāϰāĻž
- āĻ
ā§āϝāĻžāϏāĻŋāĻā§āĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ â āĻĻā§āϰā§āĻāϏā§āĻĨāĻžāϝāĻŧā§ āĻāĻāĻ āĻ
āĻĒāĻžāϰā§āĻļāύā§āϰ āĻāύā§āϝ
asyncio.TaskāĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻĢāĻžāϝāĻŧāĻžāϰ-āĻ ā§āϝāĻžāύā§āĻĄ-āĻĢāϰāĻā§āĻ āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ āĻāĻžāϏā§āĻāĨ¤ - āĻāĻŋāĻ āĻŽā§āϝāĻžāύā§āĻāĻŽā§āύā§āĻ â āĻāϰāĻ āĻāĻŦāĻ āĻāĻĒāĻŋāĻāĻ āĻā§āĻāĻž āύāĻŋāϝāĻŧāύā§āϤā§āϰāĻŖā§āϰ āĻāύā§āϝ āϝā§āĻāĻĒā§ āĻāĻāĻ āĻāĻŦāĻā§āϞā§āϰ āϰā§āĻ-āϞāĻŋāĻŽāĻŋāĻāĻŋāĻ
āϏā§āĻĨāĻžāĻĒāϤā§āϝā§āϰ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ

āĻāϰāĻĒāϰ āĻā§?
- āĻāϰāĻ āĻ
ā§āϝāĻžāĻāĻžāĻāĻžāϰ āϏā§āĻāĻžāĻāϞ āϝā§āĻ āĻāϰā§āύ â
backend/app/prompts/avatar_generation.pyāϏāĻŽā§āĻĒāĻžāĻĻāύāĻž āĻāϰā§āύ - Veo āĻĒā§āϰāĻŽā§āĻĒāĻ āĻāĻžāϏā§āĻāĻŽāĻžāĻāĻ āĻāϰā§āύ â
backend/app/prompts/video_generation.pyāϏāĻŽā§āĻĒāĻžāĻĻāύāĻž āĻāϰā§āύāĨ¤ - āĻŽāĻ āĻŽā§āĻĄā§ āϏā§āĻĨāĻžāύā§āϝāĻŧāĻāĻžāĻŦā§ āĻāĻžāϞāĻžāύ â āĻāĻĒāĻŋāĻāĻ āĻāϞ āĻāĻžāĻĄāĻŧāĻž āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻā§āϰ āĻāύā§āϝ
.envāĻĢāĻžāĻāϞā§MOCK_AI=trueāϏā§āĻ āĻāϰā§āύāĨ¤ - āĻāĻā§āύā§āĻā§āϰ āĻāύā§āϝ āϏā§āĻā§āϞ â
--max-instancesāĻāĻŦāĻMAX_CONCURRENT_JOBSāĻŦā§āĻĻā§āϧāĻŋ āĻāϰā§āύāĨ¤