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.
- package/README.md +257 -0
- package/dist/cli/batch.d.ts +8 -0
- package/dist/cli/batch.d.ts.map +1 -0
- package/dist/cli/batch.js +289 -0
- package/dist/cli/batch.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +372 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/extend.d.ts +14 -0
- package/dist/tools/extend.d.ts.map +1 -0
- package/dist/tools/extend.js +153 -0
- package/dist/tools/extend.js.map +1 -0
- package/dist/tools/generate.d.ts +10 -0
- package/dist/tools/generate.d.ts.map +1 -0
- package/dist/tools/generate.js +210 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/interpolate.d.ts +12 -0
- package/dist/tools/interpolate.d.ts.map +1 -0
- package/dist/tools/interpolate.js +170 -0
- package/dist/tools/interpolate.js.map +1 -0
- package/dist/types/batch.d.ts +121 -0
- package/dist/types/batch.d.ts.map +1 -0
- package/dist/types/batch.js +37 -0
- package/dist/types/batch.js.map +1 -0
- package/dist/types/tools.d.ts +154 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +134 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/batch-config.d.ts +26 -0
- package/dist/utils/batch-config.d.ts.map +1 -0
- package/dist/utils/batch-config.js +283 -0
- package/dist/utils/batch-config.js.map +1 -0
- package/dist/utils/batch-manager.d.ts +43 -0
- package/dist/utils/batch-manager.d.ts.map +1 -0
- package/dist/utils/batch-manager.js +310 -0
- package/dist/utils/batch-manager.js.map +1 -0
- package/dist/utils/debug.d.ts +16 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +44 -0
- package/dist/utils/debug.js.map +1 -0
- package/dist/utils/path.d.ts +36 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +97 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/video.d.ts +44 -0
- package/dist/utils/video.d.ts.map +1 -0
- package/dist/utils/video.js +261 -0
- package/dist/utils/video.js.map +1 -0
- package/docs/GOOGLE_VEO_3.1_API_SPECIFICATION.md +392 -0
- package/examples/batch-config.json +44 -0
- 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 | 初版作成 |
|