opencode-nanobanana 0.1.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/.ralph-events.json +151 -0
- package/.ralph-last-branch +1 -0
- package/.ralph-monitor-state.json +7 -0
- package/.ralph-monitor.pid +1 -0
- package/.ralph-timing.json +26 -0
- package/README.md +708 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/platforms/android.d.ts +94 -0
- package/dist/platforms/android.d.ts.map +1 -0
- package/dist/platforms/android.js +123 -0
- package/dist/platforms/android.js.map +1 -0
- package/dist/platforms/ios.d.ts +51 -0
- package/dist/platforms/ios.d.ts.map +1 -0
- package/dist/platforms/ios.js +149 -0
- package/dist/platforms/ios.js.map +1 -0
- package/dist/platforms/macos.d.ts +33 -0
- package/dist/platforms/macos.d.ts.map +1 -0
- package/dist/platforms/macos.js +50 -0
- package/dist/platforms/macos.js.map +1 -0
- package/dist/platforms/watchos.d.ts +36 -0
- package/dist/platforms/watchos.d.ts.map +1 -0
- package/dist/platforms/watchos.js +113 -0
- package/dist/platforms/watchos.js.map +1 -0
- package/dist/platforms/web.d.ts +64 -0
- package/dist/platforms/web.d.ts.map +1 -0
- package/dist/platforms/web.js +96 -0
- package/dist/platforms/web.js.map +1 -0
- package/dist/providers/gemini.d.ts +41 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +177 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/tools/analyze/compare.d.ts +12 -0
- package/dist/tools/analyze/compare.d.ts.map +1 -0
- package/dist/tools/analyze/compare.js +83 -0
- package/dist/tools/analyze/compare.js.map +1 -0
- package/dist/tools/analyze/mockup.d.ts +12 -0
- package/dist/tools/analyze/mockup.d.ts.map +1 -0
- package/dist/tools/analyze/mockup.js +88 -0
- package/dist/tools/analyze/mockup.js.map +1 -0
- package/dist/tools/analyze/screenshot.d.ts +12 -0
- package/dist/tools/analyze/screenshot.d.ts.map +1 -0
- package/dist/tools/analyze/screenshot.js +61 -0
- package/dist/tools/analyze/screenshot.js.map +1 -0
- package/dist/tools/app-assets/app-icon.d.ts +9 -0
- package/dist/tools/app-assets/app-icon.d.ts.map +1 -0
- package/dist/tools/app-assets/app-icon.js +133 -0
- package/dist/tools/app-assets/app-icon.js.map +1 -0
- package/dist/tools/app-assets/device-mockup.d.ts +9 -0
- package/dist/tools/app-assets/device-mockup.d.ts.map +1 -0
- package/dist/tools/app-assets/device-mockup.js +139 -0
- package/dist/tools/app-assets/device-mockup.js.map +1 -0
- package/dist/tools/app-assets/launch-images.d.ts +3 -0
- package/dist/tools/app-assets/launch-images.d.ts.map +1 -0
- package/dist/tools/app-assets/launch-images.js +171 -0
- package/dist/tools/app-assets/launch-images.js.map +1 -0
- package/dist/tools/app-assets/resize-devices.d.ts +14 -0
- package/dist/tools/app-assets/resize-devices.d.ts.map +1 -0
- package/dist/tools/app-assets/resize-devices.js +296 -0
- package/dist/tools/app-assets/resize-devices.js.map +1 -0
- package/dist/tools/app-assets/screenshots.d.ts +14 -0
- package/dist/tools/app-assets/screenshots.d.ts.map +1 -0
- package/dist/tools/app-assets/screenshots.js +186 -0
- package/dist/tools/app-assets/screenshots.js.map +1 -0
- package/dist/tools/core/edit-image.d.ts +12 -0
- package/dist/tools/core/edit-image.d.ts.map +1 -0
- package/dist/tools/core/edit-image.js +102 -0
- package/dist/tools/core/edit-image.js.map +1 -0
- package/dist/tools/core/generate-image.d.ts +12 -0
- package/dist/tools/core/generate-image.d.ts.map +1 -0
- package/dist/tools/core/generate-image.js +96 -0
- package/dist/tools/core/generate-image.js.map +1 -0
- package/dist/tools/core/restore-image.d.ts +12 -0
- package/dist/tools/core/restore-image.d.ts.map +1 -0
- package/dist/tools/core/restore-image.js +104 -0
- package/dist/tools/core/restore-image.js.map +1 -0
- package/dist/tools/design/mockup-to-code.d.ts +3 -0
- package/dist/tools/design/mockup-to-code.d.ts.map +1 -0
- package/dist/tools/design/mockup-to-code.js +311 -0
- package/dist/tools/design/mockup-to-code.js.map +1 -0
- package/dist/tools/design/sketch-to-code.d.ts +3 -0
- package/dist/tools/design/sketch-to-code.d.ts.map +1 -0
- package/dist/tools/design/sketch-to-code.js +325 -0
- package/dist/tools/design/sketch-to-code.js.map +1 -0
- package/dist/tools/docs/architecture-diagram.d.ts +12 -0
- package/dist/tools/docs/architecture-diagram.d.ts.map +1 -0
- package/dist/tools/docs/architecture-diagram.js +179 -0
- package/dist/tools/docs/architecture-diagram.js.map +1 -0
- package/dist/tools/docs/readme-banner.d.ts +6 -0
- package/dist/tools/docs/readme-banner.d.ts.map +1 -0
- package/dist/tools/docs/readme-banner.js +108 -0
- package/dist/tools/docs/readme-banner.js.map +1 -0
- package/dist/tools/docs/sequence-diagram.d.ts +12 -0
- package/dist/tools/docs/sequence-diagram.d.ts.map +1 -0
- package/dist/tools/docs/sequence-diagram.js +161 -0
- package/dist/tools/docs/sequence-diagram.js.map +1 -0
- package/dist/tools/docs/social-preview.d.ts +11 -0
- package/dist/tools/docs/social-preview.d.ts.map +1 -0
- package/dist/tools/docs/social-preview.js +111 -0
- package/dist/tools/docs/social-preview.js.map +1 -0
- package/dist/tools/video/extend-video.d.ts +14 -0
- package/dist/tools/video/extend-video.d.ts.map +1 -0
- package/dist/tools/video/extend-video.js +39 -0
- package/dist/tools/video/extend-video.js.map +1 -0
- package/dist/tools/video/generate-video.d.ts +14 -0
- package/dist/tools/video/generate-video.d.ts.map +1 -0
- package/dist/tools/video/generate-video.js +39 -0
- package/dist/tools/video/generate-video.js.map +1 -0
- package/dist/tools/video/image-to-video.d.ts +15 -0
- package/dist/tools/video/image-to-video.d.ts.map +1 -0
- package/dist/tools/video/image-to-video.js +42 -0
- package/dist/tools/video/image-to-video.js.map +1 -0
- package/dist/tools/video/storyboard-video.d.ts +91 -0
- package/dist/tools/video/storyboard-video.d.ts.map +1 -0
- package/dist/tools/video/storyboard-video.js +230 -0
- package/dist/tools/video/storyboard-video.js.map +1 -0
- package/dist/utils/ffmpeg.d.ts +30 -0
- package/dist/utils/ffmpeg.d.ts.map +1 -0
- package/dist/utils/ffmpeg.js +205 -0
- package/dist/utils/ffmpeg.js.map +1 -0
- package/dist/utils/file-handler.d.ts +7 -0
- package/dist/utils/file-handler.d.ts.map +1 -0
- package/dist/utils/file-handler.js +10 -0
- package/dist/utils/file-handler.js.map +1 -0
- package/dist/utils/image-processing.d.ts +7 -0
- package/dist/utils/image-processing.d.ts.map +1 -0
- package/dist/utils/image-processing.js +10 -0
- package/dist/utils/image-processing.js.map +1 -0
- package/docs/PLUGIN-VERIFICATION.md +182 -0
- package/logs/notifications.jsonl +46 -0
- package/package.json +61 -0
- package/prd.json +216 -0
- package/progress.txt +145 -0
- package/ralph-report.html +297 -0
- package/src/index.ts +23 -0
- package/src/platforms/android/.gitkeep +0 -0
- package/src/platforms/ios/.gitkeep +0 -0
- package/src/platforms/web/.gitkeep +0 -0
- package/src/providers/.gitkeep +0 -0
- package/src/providers/gemini.ts +288 -0
- package/src/tools/core/.gitkeep +0 -0
- package/src/tools/platform/.gitkeep +0 -0
- package/src/tools/video/extend-video.ts +71 -0
- package/src/tools/video/generate-video.ts +70 -0
- package/src/tools/video/image-to-video.ts +76 -0
- package/src/tools/video/storyboard-video.ts +325 -0
- package/src/utils/.gitkeep +0 -0
- package/src/utils/ffmpeg.ts +266 -0
- package/src/utils/file-handler.ts +10 -0
- package/src/utils/image-processing.ts +10 -0
- package/templates/.gitkeep +0 -0
- package/test-analyze-screenshot.ts +50 -0
- package/test-app-icons.ts +55 -0
- package/test-cat-sunset.ts +30 -0
- package/test-full-plugin.ts +88 -0
- package/test-icon-gen.ts +30 -0
- package/test-output/test-edit.png +0 -0
- package/test-output/test-generate.png +0 -0
- package/test-output/test-video.mp4 +0 -0
- package/test-plugin-load.js +45 -0
- package/test-princess-emma-continue.ts +35 -0
- package/test-princess-emma-full.ts +38 -0
- package/test-princess-emma-short.ts +32 -0
- package/test-princess-emma-with-reference.ts +34 -0
- package/test-princess-emma.ts +38 -0
- package/test-product-ad.ts +66 -0
- package/test-ralph-droid.ts +30 -0
- package/test-social-preview.ts +61 -0
- package/test-veo31-live.ts +187 -0
- package/test-video-gen.ts +40 -0
- package/test-video-veo.ts +73 -0
- package/test-zurich-video.ts +64 -0
- package/tests/.gitkeep +0 -0
- package/tests/providers/gemini.test.ts +388 -0
- package/tests/utils/ffmpeg.test.ts +328 -0
- package/tests/video/storyboard.test.ts +469 -0
- package/tsconfig.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
# OpenCode Visual Toolkit
|
|
2
|
+
|
|
3
|
+
An OpenCode plugin providing comprehensive visual capabilities powered by Google's Gemini API, including advanced video generation with Veo 3.1, storyboard creation, and video extension features.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **🎬 Storyboard Video Generation** - Create multi-scene videos with transitions, character consistency, and audio mixing
|
|
8
|
+
- **🎥 Video Generation** - Generate videos from text prompts with Veo 3.1 and native audio
|
|
9
|
+
- **🖼️ Image to Video** - Animate static images into videos with motion and audio
|
|
10
|
+
- **🎥 Video Extension** - Extend existing videos with new content using Veo 3.1
|
|
11
|
+
- **🎨 Image Generation** - Generate images using Nano Banana (Imagen 3)
|
|
12
|
+
- **📱 App Asset Pipelines** - Generate complete icon sets for iOS, Android, macOS, and Web
|
|
13
|
+
- **🔍 Visual Analysis** - Analyze images and screenshots
|
|
14
|
+
- **🎞️ Video Processing** - FFmpeg utilities for concatenation, transitions, and audio mixing
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install opencode-visual-toolkit
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Requirements
|
|
23
|
+
|
|
24
|
+
- Node.js >= 18.0.0
|
|
25
|
+
- FFmpeg (for video features)
|
|
26
|
+
|
|
27
|
+
#### Installing FFmpeg
|
|
28
|
+
|
|
29
|
+
**macOS:**
|
|
30
|
+
```bash
|
|
31
|
+
brew install ffmpeg
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Ubuntu/Debian:**
|
|
35
|
+
```bash
|
|
36
|
+
sudo apt update
|
|
37
|
+
sudo apt install ffmpeg
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Windows:**
|
|
41
|
+
Download from [ffmpeg.org](https://ffmpeg.org/download.html) or use:
|
|
42
|
+
```bash
|
|
43
|
+
choco install ffmpeg
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import {
|
|
50
|
+
generateVideo,
|
|
51
|
+
imageToVideo,
|
|
52
|
+
generateStoryboardVideo,
|
|
53
|
+
extendVideo
|
|
54
|
+
} from 'opencode-visual-toolkit';
|
|
55
|
+
|
|
56
|
+
// Generate a video from a text prompt
|
|
57
|
+
const video = await generateVideo({
|
|
58
|
+
apiKey: 'your-gemini-api-key',
|
|
59
|
+
prompt: 'A serene mountain landscape at sunrise',
|
|
60
|
+
outputPath: './mountain.mp4'
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Animate an image
|
|
64
|
+
const animated = await imageToVideo({
|
|
65
|
+
apiKey: 'your-gemini-api-key',
|
|
66
|
+
imagePath: './photo.jpg',
|
|
67
|
+
prompt: 'Slow camera pan from left to right',
|
|
68
|
+
outputPath: './animated.mp4'
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Generate a multi-scene storyboard video
|
|
72
|
+
const storyboard = await generateStoryboardVideo({
|
|
73
|
+
apiKey: 'your-gemini-api-key',
|
|
74
|
+
scenes: [
|
|
75
|
+
'A serene mountain landscape at sunrise',
|
|
76
|
+
'A hiker reaching the summit',
|
|
77
|
+
'Panoramic view from the peak'
|
|
78
|
+
],
|
|
79
|
+
style: 'cinematic',
|
|
80
|
+
transition: 'crossfade',
|
|
81
|
+
outputPath: './mountain-journey.mp4'
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Storyboard Video Generation
|
|
86
|
+
|
|
87
|
+
The `generateStoryboardVideo` tool creates multi-scene videos by generating individual scenes in parallel and stitching them together with professional transitions.
|
|
88
|
+
|
|
89
|
+
### Features
|
|
90
|
+
|
|
91
|
+
- **Parallel Scene Generation** - All scenes generate simultaneously for maximum speed
|
|
92
|
+
- **Professional Transitions** - Cut, crossfade, or fade transitions between scenes
|
|
93
|
+
- **Character Consistency** - Maintain consistent characters across scenes using reference images
|
|
94
|
+
- **Native Audio** - Veo 3.1 generates audio automatically for each scene
|
|
95
|
+
- **Background Music** - Add background music with volume control
|
|
96
|
+
- **Progress Tracking** - Detailed progress logs for each scene
|
|
97
|
+
|
|
98
|
+
### API Reference
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
interface StoryboardVideoOptions {
|
|
102
|
+
/** Array of scene descriptions */
|
|
103
|
+
scenes: string[];
|
|
104
|
+
|
|
105
|
+
/** Style to apply to all scenes (e.g., 'cinematic', 'commercial') */
|
|
106
|
+
style?: string;
|
|
107
|
+
|
|
108
|
+
/** Character description to prepend to each scene for consistency */
|
|
109
|
+
characterDescription?: string;
|
|
110
|
+
|
|
111
|
+
/** Array of reference image paths for character/scene consistency (max 3) */
|
|
112
|
+
referenceImages?: string[];
|
|
113
|
+
|
|
114
|
+
/** Aspect ratio for all scenes (default: '16:9') */
|
|
115
|
+
aspectRatio?: '16:9' | '9:16' | '1:1';
|
|
116
|
+
|
|
117
|
+
/** Transition type between scenes (default: 'crossfade') */
|
|
118
|
+
transition?: 'cut' | 'crossfade' | 'fade';
|
|
119
|
+
|
|
120
|
+
/** Transition duration in seconds (default: 0.5) */
|
|
121
|
+
transitionDuration?: number;
|
|
122
|
+
|
|
123
|
+
/** Enable native Veo audio generation (default: true) */
|
|
124
|
+
generateAudio?: boolean;
|
|
125
|
+
|
|
126
|
+
/** Path to background music audio file (optional) */
|
|
127
|
+
backgroundMusic?: string;
|
|
128
|
+
|
|
129
|
+
/** Volume level for background music (0.0-1.0, default: 0.3) */
|
|
130
|
+
musicVolume?: number;
|
|
131
|
+
|
|
132
|
+
/** Output path for the final video */
|
|
133
|
+
outputPath?: string;
|
|
134
|
+
|
|
135
|
+
/** Gemini API key */
|
|
136
|
+
apiKey: string;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Examples
|
|
141
|
+
|
|
142
|
+
#### Basic Multi-Scene Video
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const result = await generateStoryboardVideo({
|
|
146
|
+
apiKey: 'your-api-key',
|
|
147
|
+
scenes: [
|
|
148
|
+
'A peaceful coffee shop in the morning',
|
|
149
|
+
'A barista expertly crafting latte art',
|
|
150
|
+
'A customer enjoying their coffee with a smile'
|
|
151
|
+
],
|
|
152
|
+
style: 'commercial',
|
|
153
|
+
transition: 'crossfade',
|
|
154
|
+
transitionDuration: 0.5,
|
|
155
|
+
outputPath: './coffee-shop-ad.mp4'
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
console.log(`Generated ${result.successCount} scenes in ${result.totalTime / 1000}s`);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Character Consistency
|
|
162
|
+
|
|
163
|
+
Use character descriptions and reference images to maintain consistent characters across all scenes:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const result = await generateStoryboardVideo({
|
|
167
|
+
apiKey: 'your-api-key',
|
|
168
|
+
|
|
169
|
+
// Character consistency features
|
|
170
|
+
characterDescription: 'A young woman with long brown hair wearing a red jacket',
|
|
171
|
+
referenceImages: ['./character-ref-1.jpg', './character-ref-2.jpg'],
|
|
172
|
+
|
|
173
|
+
scenes: [
|
|
174
|
+
'Walking through a forest path',
|
|
175
|
+
'Discovering a hidden waterfall',
|
|
176
|
+
'Setting up camp at sunset',
|
|
177
|
+
'Roasting marshmallows by the campfire'
|
|
178
|
+
],
|
|
179
|
+
|
|
180
|
+
style: 'cinematic',
|
|
181
|
+
aspectRatio: '16:9',
|
|
182
|
+
transition: 'crossfade',
|
|
183
|
+
outputPath: './adventure-story.mp4'
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Tips for Character Consistency:**
|
|
188
|
+
- Provide 1-3 reference images showing the character from different angles
|
|
189
|
+
- Include detailed character descriptions (appearance, clothing, distinguishing features)
|
|
190
|
+
- Keep scene descriptions focused on actions/settings rather than re-describing the character
|
|
191
|
+
|
|
192
|
+
#### Background Music
|
|
193
|
+
|
|
194
|
+
Add background music to your storyboard while preserving native Veo audio:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const result = await generateStoryboardVideo({
|
|
198
|
+
apiKey: 'your-api-key',
|
|
199
|
+
scenes: [
|
|
200
|
+
'Product reveal with dramatic lighting',
|
|
201
|
+
'Close-up of premium features',
|
|
202
|
+
'Happy customer testimonials'
|
|
203
|
+
],
|
|
204
|
+
|
|
205
|
+
// Audio options
|
|
206
|
+
generateAudio: true, // Native Veo audio (footsteps, ambient sounds)
|
|
207
|
+
backgroundMusic: './upbeat.mp3', // Background music track
|
|
208
|
+
musicVolume: 0.3, // 30% volume for background music
|
|
209
|
+
|
|
210
|
+
style: 'commercial',
|
|
211
|
+
transition: 'fade',
|
|
212
|
+
outputPath: './product-demo.mp4'
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Audio Mixing Behavior:**
|
|
217
|
+
- `generateAudio: true` - Veo generates natural audio for each scene (footsteps, voices, ambient sounds)
|
|
218
|
+
- `backgroundMusic` - Your music track plays underneath at the specified volume
|
|
219
|
+
- Final video has both native audio (100% volume) and background music (musicVolume % volume)
|
|
220
|
+
|
|
221
|
+
#### Different Transitions
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// Cut transition (no transition effect, immediate cut)
|
|
225
|
+
const cutVideo = await generateStoryboardVideo({
|
|
226
|
+
apiKey: 'your-api-key',
|
|
227
|
+
scenes: ['Scene 1', 'Scene 2', 'Scene 3'],
|
|
228
|
+
transition: 'cut', // Instant cuts between scenes
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Crossfade transition (blend between scenes)
|
|
232
|
+
const crossfadeVideo = await generateStoryboardVideo({
|
|
233
|
+
apiKey: 'your-api-key',
|
|
234
|
+
scenes: ['Scene 1', 'Scene 2', 'Scene 3'],
|
|
235
|
+
transition: 'crossfade',
|
|
236
|
+
transitionDuration: 1.0, // 1 second crossfade
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Fade transition (fade to black, then fade in)
|
|
240
|
+
const fadeVideo = await generateStoryboardVideo({
|
|
241
|
+
apiKey: 'your-api-key',
|
|
242
|
+
scenes: ['Scene 1', 'Scene 2', 'Scene 3'],
|
|
243
|
+
transition: 'fade',
|
|
244
|
+
transitionDuration: 0.5, // 0.5 second fade
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Video Extension
|
|
249
|
+
|
|
250
|
+
The `extendVideo` tool seamlessly extends an existing video with new content using Veo 3.1's video extension API.
|
|
251
|
+
|
|
252
|
+
### API Reference
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
interface ExtendVideoOptions {
|
|
256
|
+
/** Path to the existing video to extend */
|
|
257
|
+
videoPath: string;
|
|
258
|
+
|
|
259
|
+
/** Description of the extension content */
|
|
260
|
+
prompt: string;
|
|
261
|
+
|
|
262
|
+
/** Aspect ratio for the extended video (default: '16:9') */
|
|
263
|
+
aspectRatio?: '16:9' | '9:16' | '1:1';
|
|
264
|
+
|
|
265
|
+
/** Resolution for the extended video (default: '720p') */
|
|
266
|
+
resolution?: '720p' | '1080p';
|
|
267
|
+
|
|
268
|
+
/** Output path for the extended video (optional, defaults to temp file) */
|
|
269
|
+
outputPath?: string;
|
|
270
|
+
|
|
271
|
+
/** Gemini API key */
|
|
272
|
+
apiKey: string;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Examples
|
|
277
|
+
|
|
278
|
+
#### Basic Video Extension
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const result = await extendVideo({
|
|
282
|
+
apiKey: 'your-api-key',
|
|
283
|
+
videoPath: './intro-scene.mp4',
|
|
284
|
+
prompt: 'The camera pans to reveal a stunning sunset over the ocean',
|
|
285
|
+
outputPath: './extended-intro.mp4'
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
console.log(`Extended video: ${result.videoPath}`);
|
|
289
|
+
console.log(`Generation time: ${result.generationTime / 1000}s`);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
#### High-Resolution Extension
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
const result = await extendVideo({
|
|
296
|
+
apiKey: 'your-api-key',
|
|
297
|
+
videoPath: './product-showcase.mp4',
|
|
298
|
+
prompt: 'Text appears: "Available now at our stores"',
|
|
299
|
+
resolution: '1080p',
|
|
300
|
+
aspectRatio: '16:9',
|
|
301
|
+
outputPath: './product-showcase-with-cta.mp4'
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Combining Storyboard with Extension
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// First, create a storyboard
|
|
309
|
+
const storyboard = await generateStoryboardVideo({
|
|
310
|
+
apiKey: 'your-api-key',
|
|
311
|
+
scenes: [
|
|
312
|
+
'A product sits on a pedestal',
|
|
313
|
+
'The product rotates slowly'
|
|
314
|
+
],
|
|
315
|
+
style: 'commercial',
|
|
316
|
+
outputPath: './product-base.mp4'
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// Then extend it with a call-to-action
|
|
320
|
+
const final = await extendVideo({
|
|
321
|
+
apiKey: 'your-api-key',
|
|
322
|
+
videoPath: storyboard.videoPath,
|
|
323
|
+
prompt: 'Text overlay fades in: "Order now - Limited time offer"',
|
|
324
|
+
outputPath: './product-final.mp4'
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Video Generation
|
|
329
|
+
|
|
330
|
+
The `generateVideo` tool creates videos from text prompts using Veo 3.1 with native audio support.
|
|
331
|
+
|
|
332
|
+
### API Reference
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
interface GenerateVideoOptions {
|
|
336
|
+
/** Description of the video to generate */
|
|
337
|
+
prompt: string;
|
|
338
|
+
|
|
339
|
+
/** Aspect ratio for the video (default: '16:9') */
|
|
340
|
+
aspectRatio?: '16:9' | '9:16' | '1:1';
|
|
341
|
+
|
|
342
|
+
/** Resolution for the video (default: '720p') */
|
|
343
|
+
resolution?: '720p' | '1080p';
|
|
344
|
+
|
|
345
|
+
/** Video duration in seconds (default: 8) */
|
|
346
|
+
duration?: 4 | 6 | 8;
|
|
347
|
+
|
|
348
|
+
/** Enable native audio generation (default: true) */
|
|
349
|
+
generateAudio?: boolean;
|
|
350
|
+
|
|
351
|
+
/** Output path for the video (optional, defaults to temp file) */
|
|
352
|
+
outputPath?: string;
|
|
353
|
+
|
|
354
|
+
/** Gemini API key */
|
|
355
|
+
apiKey: string;
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Examples
|
|
360
|
+
|
|
361
|
+
#### Basic Video Generation
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
const result = await generateVideo({
|
|
365
|
+
apiKey: 'your-api-key',
|
|
366
|
+
prompt: 'A serene mountain landscape at sunrise',
|
|
367
|
+
outputPath: './mountain.mp4'
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
console.log(`Video created: ${result.videoPath}`);
|
|
371
|
+
console.log(`Generation time: ${result.generationTime / 1000}s`);
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### High Quality with Custom Settings
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
const result = await generateVideo({
|
|
378
|
+
apiKey: 'your-api-key',
|
|
379
|
+
prompt: 'A bustling city street at night with neon lights',
|
|
380
|
+
resolution: '1080p',
|
|
381
|
+
duration: 8,
|
|
382
|
+
aspectRatio: '16:9',
|
|
383
|
+
generateAudio: true,
|
|
384
|
+
outputPath: './city-night.mp4'
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### Silent Video (No Audio)
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
const result = await generateVideo({
|
|
392
|
+
apiKey: 'your-api-key',
|
|
393
|
+
prompt: 'A peaceful garden with blooming flowers',
|
|
394
|
+
generateAudio: false,
|
|
395
|
+
outputPath: './silent-garden.mp4'
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
#### Short Duration Video
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
const result = await generateVideo({
|
|
403
|
+
apiKey: 'your-api-key',
|
|
404
|
+
prompt: 'Product logo reveal with dynamic motion',
|
|
405
|
+
duration: 4, // 4 second video
|
|
406
|
+
resolution: '1080p',
|
|
407
|
+
aspectRatio: '1:1', // Square format for social media
|
|
408
|
+
outputPath: './logo-reveal.mp4'
|
|
409
|
+
});
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Image to Video
|
|
413
|
+
|
|
414
|
+
The `imageToVideo` tool animates static images into videos using Veo 3.1 with native audio support.
|
|
415
|
+
|
|
416
|
+
### API Reference
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
interface ImageToVideoOptions {
|
|
420
|
+
/** Path to the image to animate */
|
|
421
|
+
imagePath: string;
|
|
422
|
+
|
|
423
|
+
/** Description of the animation */
|
|
424
|
+
prompt: string;
|
|
425
|
+
|
|
426
|
+
/** Aspect ratio for the video (default: '16:9') */
|
|
427
|
+
aspectRatio?: '16:9' | '9:16' | '1:1';
|
|
428
|
+
|
|
429
|
+
/** Resolution for the video (default: '720p') */
|
|
430
|
+
resolution?: '720p' | '1080p';
|
|
431
|
+
|
|
432
|
+
/** Video duration in seconds (default: 8) */
|
|
433
|
+
duration?: 4 | 6 | 8;
|
|
434
|
+
|
|
435
|
+
/** Enable native audio generation (default: true) */
|
|
436
|
+
generateAudio?: boolean;
|
|
437
|
+
|
|
438
|
+
/** Output path for the video (optional, defaults to temp file) */
|
|
439
|
+
outputPath?: string;
|
|
440
|
+
|
|
441
|
+
/** Gemini API key */
|
|
442
|
+
apiKey: string;
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Examples
|
|
447
|
+
|
|
448
|
+
#### Basic Image Animation
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
const result = await imageToVideo({
|
|
452
|
+
apiKey: 'your-api-key',
|
|
453
|
+
imagePath: './landscape.jpg',
|
|
454
|
+
prompt: 'Slow camera pan from left to right',
|
|
455
|
+
outputPath: './animated-landscape.mp4'
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
console.log(`Animated video: ${result.videoPath}`);
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### Product Showcase
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
const result = await imageToVideo({
|
|
465
|
+
apiKey: 'your-api-key',
|
|
466
|
+
imagePath: './product.png',
|
|
467
|
+
prompt: 'Product rotates 360 degrees on a pedestal',
|
|
468
|
+
resolution: '1080p',
|
|
469
|
+
duration: 6,
|
|
470
|
+
generateAudio: true,
|
|
471
|
+
outputPath: './product-showcase.mp4'
|
|
472
|
+
});
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
#### Portrait Animation
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
const result = await imageToVideo({
|
|
479
|
+
apiKey: 'your-api-key',
|
|
480
|
+
imagePath: './portrait.jpg',
|
|
481
|
+
prompt: 'Subtle breathing motion and eye blinks',
|
|
482
|
+
aspectRatio: '9:16', // Vertical format
|
|
483
|
+
duration: 4,
|
|
484
|
+
outputPath: './animated-portrait.mp4'
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
#### Logo Animation for Social Media
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
const result = await imageToVideo({
|
|
492
|
+
apiKey: 'your-api-key',
|
|
493
|
+
imagePath: './logo.png',
|
|
494
|
+
prompt: 'Logo pulses with energy and glows',
|
|
495
|
+
aspectRatio: '1:1', // Square format
|
|
496
|
+
duration: 4,
|
|
497
|
+
resolution: '1080p',
|
|
498
|
+
generateAudio: false, // Silent for social media
|
|
499
|
+
outputPath: './logo-animation.mp4'
|
|
500
|
+
});
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
## Video Generation Options (Veo 3.1)
|
|
504
|
+
|
|
505
|
+
All video tools use Veo 3.1 with these capabilities:
|
|
506
|
+
|
|
507
|
+
- **Resolutions**: `720p` (default) or `1080p`
|
|
508
|
+
- **Durations**: 4, 6, or 8 seconds (default: 8s)
|
|
509
|
+
- **Aspect Ratios**: `16:9`, `9:16`, or `1:1`
|
|
510
|
+
- **Native Audio**: Automatic audio generation (can be disabled)
|
|
511
|
+
- **Reference Images**: Up to 3 reference images for character/scene consistency
|
|
512
|
+
|
|
513
|
+
## FFmpeg Utilities
|
|
514
|
+
|
|
515
|
+
The plugin includes comprehensive FFmpeg utilities for video processing:
|
|
516
|
+
|
|
517
|
+
```typescript
|
|
518
|
+
import {
|
|
519
|
+
checkFfmpegInstalled,
|
|
520
|
+
concatenateVideos,
|
|
521
|
+
getVideoDuration,
|
|
522
|
+
trimVideo,
|
|
523
|
+
addAudioTrack
|
|
524
|
+
} from 'opencode-visual-toolkit';
|
|
525
|
+
|
|
526
|
+
// Check if FFmpeg is installed
|
|
527
|
+
const isInstalled = await checkFfmpegInstalled();
|
|
528
|
+
|
|
529
|
+
// Concatenate videos with transitions
|
|
530
|
+
await concatenateVideos(
|
|
531
|
+
['scene1.mp4', 'scene2.mp4', 'scene3.mp4'],
|
|
532
|
+
'output.mp4',
|
|
533
|
+
{
|
|
534
|
+
transition: 'crossfade',
|
|
535
|
+
transitionDuration: 0.5
|
|
536
|
+
}
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
// Get video duration
|
|
540
|
+
const duration = await getVideoDuration('video.mp4');
|
|
541
|
+
|
|
542
|
+
// Trim a video
|
|
543
|
+
await trimVideo('input.mp4', 5.0, 10.0, 'trimmed.mp4');
|
|
544
|
+
|
|
545
|
+
// Add audio track (mixes with existing audio)
|
|
546
|
+
await addAudioTrack('video.mp4', 'music.mp3', 'output.mp4', 0.3);
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
## Error Handling
|
|
550
|
+
|
|
551
|
+
The storyboard tool handles partial failures gracefully:
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
const result = await generateStoryboardVideo({
|
|
555
|
+
apiKey: 'your-api-key',
|
|
556
|
+
scenes: [
|
|
557
|
+
'Valid scene 1',
|
|
558
|
+
'Valid scene 2',
|
|
559
|
+
'Invalid scene that might fail',
|
|
560
|
+
'Valid scene 3'
|
|
561
|
+
]
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
// Check results
|
|
565
|
+
console.log(`Success: ${result.successCount} scenes`);
|
|
566
|
+
console.log(`Failed: ${result.failureCount} scenes`);
|
|
567
|
+
|
|
568
|
+
// Video is still created with successful scenes
|
|
569
|
+
if (result.successCount > 0) {
|
|
570
|
+
console.log(`Video saved to: ${result.videoPath}`);
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
## Progress Tracking
|
|
575
|
+
|
|
576
|
+
Both video tools provide detailed progress logging:
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
const result = await generateStoryboardVideo({
|
|
580
|
+
apiKey: 'your-api-key',
|
|
581
|
+
scenes: ['Scene 1', 'Scene 2', 'Scene 3']
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
// Console output shows:
|
|
585
|
+
// 🎬 Starting storyboard generation with 3 scene(s)
|
|
586
|
+
// ⚙️ Configuration:
|
|
587
|
+
// - Aspect ratio: 16:9
|
|
588
|
+
// - Transition: crossfade (0.5s)
|
|
589
|
+
// - Audio: enabled
|
|
590
|
+
//
|
|
591
|
+
// 📹 Generating scenes...
|
|
592
|
+
// [1/3] Starting: "Scene 1"
|
|
593
|
+
// ✅ [1/3] Completed in 12.3s
|
|
594
|
+
// [2/3] Starting: "Scene 2"
|
|
595
|
+
// ✅ [2/3] Completed in 11.8s
|
|
596
|
+
// [3/3] Starting: "Scene 3"
|
|
597
|
+
// ✅ [3/3] Completed in 13.1s
|
|
598
|
+
//
|
|
599
|
+
// 🎞️ Stitching 3 scene(s) together...
|
|
600
|
+
// - Transition: crossfade
|
|
601
|
+
// - Duration: 0.5s
|
|
602
|
+
//
|
|
603
|
+
// ✨ Storyboard generation complete!
|
|
604
|
+
// 📊 Summary:
|
|
605
|
+
// - Total time: 45.2s
|
|
606
|
+
// - Scenes generated: 3/3
|
|
607
|
+
// - Average scene time: 12.4s
|
|
608
|
+
// - Success rate: 100%
|
|
609
|
+
// 📁 Output: ./output.mp4
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
## Best Practices
|
|
613
|
+
|
|
614
|
+
### Scene Descriptions
|
|
615
|
+
|
|
616
|
+
- Be specific and descriptive for best results
|
|
617
|
+
- Include camera movements, lighting, and mood
|
|
618
|
+
- Keep each scene focused on a single moment or action
|
|
619
|
+
|
|
620
|
+
**Good:**
|
|
621
|
+
```typescript
|
|
622
|
+
scenes: [
|
|
623
|
+
'Close-up of a chef\'s hands carefully plating a gourmet dish',
|
|
624
|
+
'Wide shot of an elegant restaurant interior with soft lighting',
|
|
625
|
+
'Customer\'s face lighting up as they taste the food'
|
|
626
|
+
]
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
**Less Effective:**
|
|
630
|
+
```typescript
|
|
631
|
+
scenes: [
|
|
632
|
+
'A chef', // Too vague
|
|
633
|
+
'Restaurant', // Lacks detail
|
|
634
|
+
'Eating' // No context or mood
|
|
635
|
+
]
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### Character Consistency
|
|
639
|
+
|
|
640
|
+
- Use both `characterDescription` and `referenceImages` together for best results
|
|
641
|
+
- Provide 2-3 reference images from different angles
|
|
642
|
+
- Be specific about distinguishing features (hair, clothing, accessories)
|
|
643
|
+
|
|
644
|
+
### Performance
|
|
645
|
+
|
|
646
|
+
- Scenes generate in parallel - 10 scenes take roughly the same time as 1 scene
|
|
647
|
+
- Average scene generation: 10-15 seconds
|
|
648
|
+
- FFmpeg stitching is fast (< 5 seconds for most videos)
|
|
649
|
+
- Use `720p` for faster generation, `1080p` for final production
|
|
650
|
+
|
|
651
|
+
### Audio
|
|
652
|
+
|
|
653
|
+
- Native Veo audio is high quality and scene-appropriate
|
|
654
|
+
- Background music should be instrumental (avoid vocals conflicting with scene audio)
|
|
655
|
+
- Recommended `musicVolume`: 0.2-0.4 for background ambiance
|
|
656
|
+
|
|
657
|
+
## Troubleshooting
|
|
658
|
+
|
|
659
|
+
### FFmpeg Not Found
|
|
660
|
+
|
|
661
|
+
```
|
|
662
|
+
Error: FFmpeg is not installed or not available in PATH
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**Solution:** Install FFmpeg using the instructions in the [Requirements](#requirements) section.
|
|
666
|
+
|
|
667
|
+
### API Rate Limits
|
|
668
|
+
|
|
669
|
+
If you hit API rate limits, reduce the number of parallel scenes or add delays between generations.
|
|
670
|
+
|
|
671
|
+
### Memory Issues
|
|
672
|
+
|
|
673
|
+
For long storyboards (10+ scenes), ensure you have sufficient disk space for temporary files (each scene is ~5-10 MB).
|
|
674
|
+
|
|
675
|
+
## TypeScript Support
|
|
676
|
+
|
|
677
|
+
Full TypeScript support with comprehensive type definitions:
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
import type {
|
|
681
|
+
StoryboardVideoOptions,
|
|
682
|
+
StoryboardVideoResult,
|
|
683
|
+
ExtendVideoOptions,
|
|
684
|
+
ExtendVideoResult,
|
|
685
|
+
ConcatenateOptions
|
|
686
|
+
} from 'opencode-visual-toolkit';
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
## Examples
|
|
690
|
+
|
|
691
|
+
Check out the example scripts in the repository:
|
|
692
|
+
|
|
693
|
+
- `test-storyboard-basic.ts` - Basic multi-scene storyboard
|
|
694
|
+
- `test-storyboard-character.ts` - Character consistency example
|
|
695
|
+
- `test-storyboard-music.ts` - Background music example
|
|
696
|
+
- `test-video-extend.ts` - Video extension examples
|
|
697
|
+
|
|
698
|
+
## License
|
|
699
|
+
|
|
700
|
+
MIT
|
|
701
|
+
|
|
702
|
+
## Contributing
|
|
703
|
+
|
|
704
|
+
Contributions are welcome! Please open an issue or pull request.
|
|
705
|
+
|
|
706
|
+
## Support
|
|
707
|
+
|
|
708
|
+
For issues, questions, or feature requests, please open an issue on GitHub.
|