google-veo3-1-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +257 -0
  2. package/dist/cli/batch.d.ts +8 -0
  3. package/dist/cli/batch.d.ts.map +1 -0
  4. package/dist/cli/batch.js +289 -0
  5. package/dist/cli/batch.js.map +1 -0
  6. package/dist/index.d.ts +12 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +372 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/tools/extend.d.ts +14 -0
  11. package/dist/tools/extend.d.ts.map +1 -0
  12. package/dist/tools/extend.js +153 -0
  13. package/dist/tools/extend.js.map +1 -0
  14. package/dist/tools/generate.d.ts +10 -0
  15. package/dist/tools/generate.d.ts.map +1 -0
  16. package/dist/tools/generate.js +210 -0
  17. package/dist/tools/generate.js.map +1 -0
  18. package/dist/tools/interpolate.d.ts +12 -0
  19. package/dist/tools/interpolate.d.ts.map +1 -0
  20. package/dist/tools/interpolate.js +170 -0
  21. package/dist/tools/interpolate.js.map +1 -0
  22. package/dist/types/batch.d.ts +121 -0
  23. package/dist/types/batch.d.ts.map +1 -0
  24. package/dist/types/batch.js +37 -0
  25. package/dist/types/batch.js.map +1 -0
  26. package/dist/types/tools.d.ts +154 -0
  27. package/dist/types/tools.d.ts.map +1 -0
  28. package/dist/types/tools.js +134 -0
  29. package/dist/types/tools.js.map +1 -0
  30. package/dist/utils/batch-config.d.ts +26 -0
  31. package/dist/utils/batch-config.d.ts.map +1 -0
  32. package/dist/utils/batch-config.js +283 -0
  33. package/dist/utils/batch-config.js.map +1 -0
  34. package/dist/utils/batch-manager.d.ts +43 -0
  35. package/dist/utils/batch-manager.d.ts.map +1 -0
  36. package/dist/utils/batch-manager.js +310 -0
  37. package/dist/utils/batch-manager.js.map +1 -0
  38. package/dist/utils/debug.d.ts +16 -0
  39. package/dist/utils/debug.d.ts.map +1 -0
  40. package/dist/utils/debug.js +44 -0
  41. package/dist/utils/debug.js.map +1 -0
  42. package/dist/utils/path.d.ts +36 -0
  43. package/dist/utils/path.d.ts.map +1 -0
  44. package/dist/utils/path.js +97 -0
  45. package/dist/utils/path.js.map +1 -0
  46. package/dist/utils/video.d.ts +44 -0
  47. package/dist/utils/video.d.ts.map +1 -0
  48. package/dist/utils/video.js +261 -0
  49. package/dist/utils/video.js.map +1 -0
  50. package/docs/GOOGLE_VEO_3.1_API_SPECIFICATION.md +392 -0
  51. package/examples/batch-config.json +44 -0
  52. package/package.json +48 -0
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Video polling and download utilities for Veo 3.1 API
3
+ */
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+ import { GEMINI_API_BASE_URL, DEFAULT_POLL_INTERVAL, DEFAULT_MAX_POLL_ATTEMPTS } from '../types/tools.js';
7
+ import { debugLog, errorLog } from './debug.js';
8
+ import { normalizeAndValidatePath, generateUniqueFilePath, ensureVideoExtension } from './path.js';
9
+ /**
10
+ * Get API key from environment
11
+ */
12
+ export function getApiKey() {
13
+ const apiKey = process.env.GOOGLE_API_KEY;
14
+ if (!apiKey) {
15
+ throw new Error('GOOGLE_API_KEY environment variable is not set');
16
+ }
17
+ return apiKey;
18
+ }
19
+ /**
20
+ * Check operation status
21
+ */
22
+ export async function getOperationStatus(operationName, apiKey) {
23
+ // For Gemini API, the operation name format is different
24
+ // We need to construct the full URL based on the operation name
25
+ let url;
26
+ if (operationName.startsWith('http')) {
27
+ // Full URL provided
28
+ url = `${operationName}?key=${apiKey}`;
29
+ }
30
+ else if (operationName.startsWith('models/')) {
31
+ // Relative path from Gemini API
32
+ url = `${GEMINI_API_BASE_URL}/${operationName}?key=${apiKey}`;
33
+ }
34
+ else {
35
+ // Assume it's just the operation ID or full path
36
+ url = `${GEMINI_API_BASE_URL}/${operationName}?key=${apiKey}`;
37
+ }
38
+ debugLog('Checking operation status', { url: url.replace(apiKey, '***') });
39
+ const response = await fetch(url, {
40
+ method: 'GET',
41
+ headers: {
42
+ 'Content-Type': 'application/json'
43
+ }
44
+ });
45
+ if (!response.ok) {
46
+ const errorText = await response.text();
47
+ throw new Error(`Failed to get operation status: ${response.status} ${response.statusText} - ${errorText}`);
48
+ }
49
+ const result = await response.json();
50
+ debugLog('Operation status response', result);
51
+ return result;
52
+ }
53
+ /**
54
+ * Poll for video generation completion
55
+ */
56
+ export async function pollVideoResult(operationName, apiKey, pollInterval = DEFAULT_POLL_INTERVAL, maxAttempts = DEFAULT_MAX_POLL_ATTEMPTS) {
57
+ debugLog(`Starting poll for operation: ${operationName}`);
58
+ let attempts = 0;
59
+ while (attempts < maxAttempts) {
60
+ attempts++;
61
+ debugLog(`Poll attempt ${attempts}/${maxAttempts}`);
62
+ try {
63
+ const status = await getOperationStatus(operationName, apiKey);
64
+ if (status.error) {
65
+ // Operation completed with error
66
+ errorLog('Operation failed', status.error);
67
+ return status;
68
+ }
69
+ if (status.done) {
70
+ // Operation completed successfully
71
+ debugLog('Operation completed', status);
72
+ return status;
73
+ }
74
+ // Still processing, wait before next poll
75
+ debugLog(`Operation still processing, waiting ${pollInterval}ms`);
76
+ await sleep(pollInterval);
77
+ }
78
+ catch (error) {
79
+ // Check for transient errors (5xx)
80
+ if (error instanceof Error && error.message.includes('5')) {
81
+ debugLog(`Transient error, retrying: ${error.message}`);
82
+ await sleep(pollInterval);
83
+ continue;
84
+ }
85
+ throw error;
86
+ }
87
+ }
88
+ throw new Error(`Polling timeout: operation did not complete after ${maxAttempts} attempts`);
89
+ }
90
+ /**
91
+ * Download video from URL
92
+ */
93
+ export async function downloadVideo(url, apiKey) {
94
+ let downloadUrl = url;
95
+ // Add API key for Google API URLs
96
+ if (apiKey && url.includes('generativelanguage.googleapis.com')) {
97
+ const separator = url.includes('?') ? '&' : '?';
98
+ downloadUrl = `${url}${separator}key=${apiKey}`;
99
+ }
100
+ debugLog('Downloading video', { url: downloadUrl.replace(apiKey || '', '***') });
101
+ const response = await fetch(downloadUrl);
102
+ if (!response.ok) {
103
+ throw new Error(`Failed to download video: ${response.status} ${response.statusText}`);
104
+ }
105
+ const arrayBuffer = await response.arrayBuffer();
106
+ return Buffer.from(arrayBuffer);
107
+ }
108
+ /**
109
+ * Save video buffer to file
110
+ */
111
+ export async function saveVideo(videoData, outputPath) {
112
+ // Ensure .mp4 extension
113
+ outputPath = ensureVideoExtension(outputPath);
114
+ // Normalize and validate path
115
+ const normalizedPath = normalizeAndValidatePath(outputPath);
116
+ // Generate unique path to avoid overwriting
117
+ const uniquePath = generateUniqueFilePath(normalizedPath);
118
+ debugLog('Saving video', { path: uniquePath });
119
+ // Handle base64 encoded data
120
+ if (typeof videoData === 'string') {
121
+ const buffer = Buffer.from(videoData, 'base64');
122
+ fs.writeFileSync(uniquePath, buffer);
123
+ }
124
+ else {
125
+ fs.writeFileSync(uniquePath, videoData);
126
+ }
127
+ return uniquePath;
128
+ }
129
+ /**
130
+ * Download video and save to file
131
+ */
132
+ export async function downloadAndSaveVideo(url, base64Data, outputPath, apiKey) {
133
+ if (base64Data) {
134
+ // Use base64 data directly
135
+ return saveVideo(base64Data, outputPath);
136
+ }
137
+ if (url) {
138
+ // Download from URL (pass API key for Google API URLs)
139
+ const key = apiKey || process.env.GOOGLE_API_KEY;
140
+ const videoData = await downloadVideo(url, key);
141
+ return saveVideo(videoData, outputPath);
142
+ }
143
+ throw new Error('No video data available (neither URL nor base64 provided)');
144
+ }
145
+ /**
146
+ * Extract video from operation response
147
+ */
148
+ export function extractVideoFromResponse(response) {
149
+ // Handle Gemini API response format
150
+ // Structure: response.generateVideoResponse.generatedSamples[].video.uri
151
+ const generateVideoResponse = response.response?.generateVideoResponse;
152
+ if (generateVideoResponse?.generatedSamples?.length) {
153
+ const video = generateVideoResponse.generatedSamples[0].video;
154
+ if (video) {
155
+ return {
156
+ url: video.uri,
157
+ base64: video.bytesBase64Encoded
158
+ };
159
+ }
160
+ }
161
+ // Fallback: Check for Vertex AI format (generatedVideos)
162
+ if (response.response?.generatedVideos?.length) {
163
+ const video = response.response.generatedVideos[0].video;
164
+ return {
165
+ url: video.uri,
166
+ base64: video.bytesBase64Encoded
167
+ };
168
+ }
169
+ return null;
170
+ }
171
+ /**
172
+ * Read image file and convert to base64
173
+ */
174
+ export async function readImageAsBase64(imagePath) {
175
+ // Check if it's already base64 or a URL
176
+ if (imagePath.startsWith('data:')) {
177
+ // Extract base64 from data URL
178
+ const match = imagePath.match(/^data:[^;]+;base64,(.+)$/);
179
+ if (match) {
180
+ return match[1];
181
+ }
182
+ throw new Error('Invalid data URL format');
183
+ }
184
+ if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {
185
+ // Download image from URL
186
+ const response = await fetch(imagePath);
187
+ if (!response.ok) {
188
+ throw new Error(`Failed to fetch image: ${response.status}`);
189
+ }
190
+ const buffer = await response.arrayBuffer();
191
+ return Buffer.from(buffer).toString('base64');
192
+ }
193
+ if (imagePath.startsWith('gs://')) {
194
+ // GCS URI - return as-is for the API to handle
195
+ throw new Error('GCS URIs should be passed directly to the API, not converted to base64');
196
+ }
197
+ // Assume it's a file path
198
+ const absolutePath = path.isAbsolute(imagePath)
199
+ ? imagePath
200
+ : path.resolve(process.cwd(), imagePath);
201
+ if (!fs.existsSync(absolutePath)) {
202
+ // Check if it's already base64 encoded
203
+ if (isBase64(imagePath)) {
204
+ return imagePath;
205
+ }
206
+ throw new Error(`Image file not found: ${absolutePath}`);
207
+ }
208
+ const buffer = fs.readFileSync(absolutePath);
209
+ return buffer.toString('base64');
210
+ }
211
+ /**
212
+ * Check if a string is base64 encoded
213
+ */
214
+ function isBase64(str) {
215
+ if (str.length < 100)
216
+ return false; // Too short to be an image
217
+ try {
218
+ const decoded = Buffer.from(str, 'base64').toString('base64');
219
+ return decoded === str;
220
+ }
221
+ catch {
222
+ return false;
223
+ }
224
+ }
225
+ /**
226
+ * Read video file and convert to base64
227
+ */
228
+ export async function readVideoAsBase64(videoPath) {
229
+ if (videoPath.startsWith('gs://')) {
230
+ // GCS URI - return as-is for the API to handle
231
+ throw new Error('GCS URIs should be passed directly to the API, not converted to base64');
232
+ }
233
+ if (videoPath.startsWith('http://') || videoPath.startsWith('https://')) {
234
+ const response = await fetch(videoPath);
235
+ if (!response.ok) {
236
+ throw new Error(`Failed to fetch video: ${response.status}`);
237
+ }
238
+ const buffer = await response.arrayBuffer();
239
+ return Buffer.from(buffer).toString('base64');
240
+ }
241
+ // Assume it's a file path
242
+ const absolutePath = path.isAbsolute(videoPath)
243
+ ? videoPath
244
+ : path.resolve(process.cwd(), videoPath);
245
+ if (!fs.existsSync(absolutePath)) {
246
+ // Check if it's already base64 encoded
247
+ if (isBase64(videoPath)) {
248
+ return videoPath;
249
+ }
250
+ throw new Error(`Video file not found: ${absolutePath}`);
251
+ }
252
+ const buffer = fs.readFileSync(absolutePath);
253
+ return buffer.toString('base64');
254
+ }
255
+ /**
256
+ * Sleep utility
257
+ */
258
+ function sleep(ms) {
259
+ return new Promise(resolve => setTimeout(resolve, ms));
260
+ }
261
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/utils/video.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,392 @@
1
+ # Google Veo 3.1 API 仕様書
2
+
3
+ > 最終更新: 2026-02-01
4
+
5
+ ## 概要
6
+
7
+ Veo 3.1はGoogleの最新動画生成AIモデルで、テキストプロンプトや画像から高品質な動画を生成できます。ネイティブオーディオ生成、フレーム補間、リファレンス画像による一貫性維持など、高度な機能を備えています。
8
+
9
+ ---
10
+
11
+ ## 利用可能なAPI
12
+
13
+ Veo 3.1は2つのAPIプラットフォームで利用可能です:
14
+
15
+ | プラットフォーム | 用途 | 認証方式 |
16
+ |-----------------|------|----------|
17
+ | **Gemini API** | 開発者向け、プロトタイピング | APIキー |
18
+ | **Vertex AI** | エンタープライズ、本番環境 | OAuth 2.0 / サービスアカウント |
19
+
20
+ ---
21
+
22
+ ## モデルID一覧
23
+
24
+ ### Gemini API
25
+ | モデルID | 説明 |
26
+ |----------|------|
27
+ | `veo-3.1-generate-preview` | Veo 3.1 標準版(プレビュー) |
28
+ | `veo-3.1-fast-generate-preview` | Veo 3.1 高速版(プレビュー) |
29
+
30
+ ### Vertex AI
31
+ | モデルID | 説明 | ステータス |
32
+ |----------|------|-----------|
33
+ | `veo-3.1-generate-001` | Veo 3.1 標準版 | Production |
34
+ | `veo-3.1-fast-generate-001` | Veo 3.1 高速版 | Production |
35
+ | `veo-3.1-generate-preview` | Veo 3.1 標準版 | Preview |
36
+ | `veo-3.1-fast-generate-preview` | Veo 3.1 高速版 | Preview |
37
+
38
+ ---
39
+
40
+ ## 価格 (2026年1月時点)
41
+
42
+ ### Vertex AI / Gemini API 公式価格
43
+
44
+ | 機能 | 解像度 | 価格(USD) |
45
+ |------|--------|------------|
46
+ | **動画 + オーディオ生成** | 720p, 1080p | **$0.40/秒** |
47
+ | **動画 + オーディオ生成** | 4K | **$0.60/秒** |
48
+ | **動画のみ(音声なし)** | 720p, 1080p | **$0.20/秒** |
49
+
50
+ ### コスト計算例
51
+
52
+ | 動画長 | 音声あり (1080p) | 音声なし (1080p) |
53
+ |--------|-----------------|-----------------|
54
+ | 4秒 | $1.60 | $0.80 |
55
+ | 6秒 | $2.40 | $1.20 |
56
+ | 8秒 | $3.20 | $1.60 |
57
+
58
+ ### Gemini Advanced サブスクリプション
59
+ - **$19.99/月**: Veo 3.1フルアクセス(ネイティブ音声生成、4Kアップスケーリング含む)
60
+ - **$249.99/月 (Ultra)**: 約2,500本のVeo 3.1 Fast動画生成可能
61
+
62
+ ---
63
+
64
+ ## APIエンドポイント
65
+
66
+ ### Gemini API
67
+
68
+ ```
69
+ POST https://generativelanguage.googleapis.com/v1beta/models/{MODEL_ID}:predictLongRunning
70
+ ```
71
+
72
+ **認証ヘッダー:**
73
+ ```
74
+ x-goog-api-key: YOUR_API_KEY
75
+ ```
76
+
77
+ ### Vertex AI
78
+
79
+ ```
80
+ POST https://{LOCATION}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/{MODEL_ID}:predictLongRunning
81
+ ```
82
+
83
+ **認証ヘッダー:**
84
+ ```
85
+ Authorization: Bearer $(gcloud auth print-access-token)
86
+ ```
87
+
88
+ ---
89
+
90
+ ## リクエストパラメータ
91
+
92
+ ### 必須/オプションパラメータ
93
+
94
+ | パラメータ | 型 | 必須 | デフォルト | 説明 |
95
+ |-----------|-----|------|-----------|------|
96
+ | `prompt` | string | △ | - | テキストプロンプト(画像入力時はオプション) |
97
+ | `image` | object | × | - | 開始フレーム画像(image-to-video用) |
98
+ | `lastFrame` | object | × | - | 終了フレーム画像(フレーム補間用) |
99
+ | `video` | object | × | - | 延長対象の動画(video extension用) |
100
+ | `referenceImages` | array | × | - | 参照画像(最大3枚、Veo 3.1のみ) |
101
+ | `negativePrompt` | string | × | - | 生成を避けたい要素 |
102
+
103
+ ### 生成設定パラメータ
104
+
105
+ | パラメータ | 型 | デフォルト | 選択肢/範囲 |
106
+ |-----------|-----|-----------|------------|
107
+ | `aspectRatio` | string | "16:9" | "16:9", "9:16" |
108
+ | `resolution` | string | "720p" | "720p", "1080p", "4k"(プレビューのみ) |
109
+ | `durationSeconds` | integer | 8 | 4, 6, 8 |
110
+ | `sampleCount` | integer | 1 | 1-4 |
111
+ | `generateAudio` | boolean | - | true/false (Veo 3必須) |
112
+ | `personGeneration` | string | "allow_adult" | "allow_adult", "dont_allow", "allow_all" |
113
+ | `seed` | uint32 | ランダム | 0 - 4,294,967,295 |
114
+ | `compressionQuality` | string | "optimized" | "optimized", "lossless" |
115
+ | `resizeMode` | string | "pad" | "pad", "crop" |
116
+ | `storageUri` | string | - | gs://BUCKET/PATH |
117
+
118
+ ### referenceImages の構造
119
+
120
+ ```json
121
+ {
122
+ "referenceImages": [
123
+ {
124
+ "image": {
125
+ "bytesBase64Encoded": "BASE64_DATA"
126
+ },
127
+ "referenceType": "asset"
128
+ }
129
+ ]
130
+ }
131
+ ```
132
+
133
+ - `referenceType`: `"asset"`(キャラクター/オブジェクト)または `"style"`(スタイル)
134
+ - 最大3枚のasset画像、または1枚のstyle画像
135
+
136
+ ---
137
+
138
+ ## サポートされるファイル形式
139
+
140
+ ### 入力画像
141
+ - `image/jpeg`
142
+ - `image/png`
143
+ - `image/webp`
144
+ - **最大サイズ:** 20MB
145
+
146
+ ### 入力動画(video extension用)
147
+ - `video/mp4`, `video/mov`, `video/mpeg`, `video/avi`, `video/wmv`, `video/flv`
148
+ - **要件:** 1-30秒、24fps、720p または 1080p
149
+
150
+ ### 出力動画
151
+ - **形式:** MP4
152
+ - **フレームレート:** 24fps
153
+ - **透かし:** SynthID(デジタルウォーターマーク)
154
+
155
+ ---
156
+
157
+ ## 主要機能
158
+
159
+ ### 1. Text-to-Video(テキストから動画)
160
+ テキストプロンプトから動画を生成
161
+
162
+ ```python
163
+ from google import genai
164
+ from google.genai import types
165
+
166
+ client = genai.Client(api_key="YOUR_API_KEY")
167
+
168
+ operation = client.models.generate_videos(
169
+ model="veo-3.1-generate-preview",
170
+ prompt="A cinematic shot of a golden retriever running through autumn leaves in slow motion",
171
+ config=types.GenerateVideosConfig(
172
+ aspect_ratio="16:9",
173
+ resolution="1080p",
174
+ duration_seconds=8,
175
+ generate_audio=True
176
+ )
177
+ )
178
+
179
+ # ポーリングで完了を待機
180
+ while not operation.done:
181
+ time.sleep(10)
182
+ operation = client.operations.get(operation.name)
183
+
184
+ # 結果を取得
185
+ video = operation.response.generated_videos[0]
186
+ ```
187
+
188
+ ### 2. Image-to-Video(画像から動画)
189
+ 静止画をアニメーション化
190
+
191
+ ```python
192
+ import base64
193
+
194
+ with open("start_frame.jpg", "rb") as f:
195
+ image_data = base64.b64encode(f.read()).decode()
196
+
197
+ operation = client.models.generate_videos(
198
+ model="veo-3.1-generate-preview",
199
+ prompt="Camera slowly zooms in while clouds move in the background",
200
+ image=types.Image(bytes_base64_encoded=image_data),
201
+ config=types.GenerateVideosConfig(
202
+ aspect_ratio="16:9",
203
+ duration_seconds=8
204
+ )
205
+ )
206
+ ```
207
+
208
+ ### 3. First-Last Frame Interpolation(フレーム補間)
209
+ 開始フレームと終了フレームの間を補間
210
+
211
+ ```python
212
+ operation = client.models.generate_videos(
213
+ model="veo-3.1-generate-preview",
214
+ prompt="Smooth transition between scenes",
215
+ image=types.Image(bytes_base64_encoded=first_frame_data),
216
+ last_frame=types.Image(bytes_base64_encoded=last_frame_data),
217
+ config=types.GenerateVideosConfig(
218
+ duration_seconds=8,
219
+ generate_audio=True
220
+ )
221
+ )
222
+ ```
223
+
224
+ ### 4. Video Extension(動画延長)
225
+ 既存の動画を延長(最終1秒から続きを生成)
226
+
227
+ ```python
228
+ operation = client.models.generate_videos(
229
+ model="veo-3.1-generate-preview",
230
+ prompt="Continue the action with the character walking forward",
231
+ video=types.Video(uri="gs://bucket/previous_video.mp4"),
232
+ config=types.GenerateVideosConfig(
233
+ # 延長は7秒、720p固定
234
+ )
235
+ )
236
+ ```
237
+
238
+ ### 5. Reference Images(参照画像によるガイド)
239
+ キャラクターやスタイルの一貫性を維持
240
+
241
+ ```python
242
+ operation = client.models.generate_videos(
243
+ model="veo-3.1-generate-preview",
244
+ prompt="The character walks through a magical forest",
245
+ reference_images=[
246
+ types.ReferenceImage(
247
+ image=types.Image(bytes_base64_encoded=character_image),
248
+ reference_type="asset"
249
+ )
250
+ ],
251
+ config=types.GenerateVideosConfig(
252
+ duration_seconds=8
253
+ )
254
+ )
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Vertex AI REST API例
260
+
261
+ ### リクエスト
262
+
263
+ ```bash
264
+ curl -X POST \
265
+ -H "Authorization: Bearer $(gcloud auth print-access-token)" \
266
+ -H "Content-Type: application/json" \
267
+ "https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/veo-3.1-generate-001:predictLongRunning" \
268
+ -d '{
269
+ "instances": [{
270
+ "prompt": "A timelapse of a flower blooming in soft natural light"
271
+ }],
272
+ "parameters": {
273
+ "aspectRatio": "16:9",
274
+ "resolution": "1080p",
275
+ "durationSeconds": 8,
276
+ "generateAudio": true,
277
+ "sampleCount": 1,
278
+ "storageUri": "gs://my-bucket/output/"
279
+ }
280
+ }'
281
+ ```
282
+
283
+ ### レスポンス(初期)
284
+
285
+ ```json
286
+ {
287
+ "name": "projects/PROJECT_ID/locations/us-central1/publishers/google/models/veo-3.1-generate-001/operations/OPERATION_ID"
288
+ }
289
+ ```
290
+
291
+ ### 操作ステータス確認
292
+
293
+ ```bash
294
+ curl -X GET \
295
+ -H "Authorization: Bearer $(gcloud auth print-access-token)" \
296
+ "https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/veo-3.1-generate-001/operations/${OPERATION_ID}"
297
+ ```
298
+
299
+ ### 完了時レスポンス
300
+
301
+ ```json
302
+ {
303
+ "name": "...",
304
+ "done": true,
305
+ "response": {
306
+ "generatedVideos": [
307
+ {
308
+ "video": {
309
+ "uri": "gs://my-bucket/output/video.mp4",
310
+ "bytesBase64Encoded": "..."
311
+ }
312
+ }
313
+ ]
314
+ }
315
+ }
316
+ ```
317
+
318
+ ---
319
+
320
+ ## クォータと制限
321
+
322
+ | 制限項目 | 値 |
323
+ |----------|-----|
324
+ | リクエスト/分(Production) | 50 |
325
+ | リクエスト/分(Preview) | 10 |
326
+ | 動画長 | 4, 6, 8秒 |
327
+ | 同時生成数 | 最大4本/リクエスト |
328
+ | プロンプト長 | 最大1,024トークン |
329
+ | 入力画像サイズ | 最大20MB |
330
+ | 動画保持期間 | 2日間(サーバー側) |
331
+ | レイテンシー | 11秒 〜 6分 |
332
+
333
+ ### 地域制限
334
+ - EU/UK/CH/MENA地域: `personGeneration`は`"allow_adult"`のみ利用可
335
+
336
+ ---
337
+
338
+ ## プロンプトのベストプラクティス
339
+
340
+ ### 構成要素
341
+ 1. **Subject(被写体)**: オブジェクト、人物、動物、風景
342
+ 2. **Action(動作)**: 被写体が何をしているか
343
+ 3. **Style(スタイル)**: 映画的スタイル、カメラワーク
344
+
345
+ ### 良いプロンプト例
346
+
347
+ ```
348
+ A cinematic drone shot of a lone surfer riding a massive wave at sunset,
349
+ golden hour lighting, slow motion, shot on ARRI Alexa,
350
+ shallow depth of field with ocean spray in foreground
351
+ ```
352
+
353
+ ### 音声キューの指定
354
+
355
+ ```
356
+ A chef in a busy kitchen, the sound of sizzling pans and chopping vegetables,
357
+ ambient kitchen chatter in the background
358
+ ```
359
+
360
+ ---
361
+
362
+ ## エラーハンドリング
363
+
364
+ ### 一般的なエラー
365
+
366
+ | エラーコード | 原因 | 対処法 |
367
+ |-------------|------|--------|
368
+ | 400 | 無効なパラメータ | リクエストパラメータを確認 |
369
+ | 401 | 認証エラー | APIキー/トークンを確認 |
370
+ | 429 | レート制限超過 | リトライまたはクォータ増加を申請 |
371
+ | 500 | サーバーエラー | 時間をおいてリトライ |
372
+
373
+ ### コンテンツフィルタリング
374
+
375
+ 生成された動画が安全性ポリシーに違反する場合、空の結果が返されます。`negativePrompt`を使用して不適切なコンテンツの生成を抑制してください。
376
+
377
+ ---
378
+
379
+ ## 参考リンク
380
+
381
+ - [Gemini API Video Generation](https://ai.google.dev/gemini-api/docs/video)
382
+ - [Vertex AI Veo 3.1 Documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/models/veo/3-1-generate)
383
+ - [Vertex AI Veo API Reference](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo-video-generation)
384
+ - [Google Developers Blog - Veo 3.1 Announcement](https://developers.googleblog.com/en/introducing-veo-3-1-and-new-creative-capabilities-in-the-gemini-api/)
385
+
386
+ ---
387
+
388
+ ## 変更履歴
389
+
390
+ | 日付 | 変更内容 |
391
+ |------|----------|
392
+ | 2026-02-01 | 初版作成 |