video-maker-mcp 0.1.4 → 0.1.6
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 +85 -9
- package/dist/cli/configure-image.d.ts +20 -0
- package/dist/cli/configure-image.js +148 -0
- package/dist/cli/configure-image.js.map +1 -0
- package/dist/cli/index.js +53 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/assets.d.ts +48 -0
- package/dist/core/assets.js +205 -54
- package/dist/core/assets.js.map +1 -1
- package/dist/core/env.d.ts +8 -0
- package/dist/core/env.js +13 -1
- package/dist/core/env.js.map +1 -1
- package/dist/mcp/server.js +32 -5
- package/dist/mcp/server.js.map +1 -1
- package/dist/providers/image/seedream.d.ts +17 -0
- package/dist/providers/image/seedream.js +87 -0
- package/dist/providers/image/seedream.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Local MCP storyboard video renderer for Codex-driven short video generation.
|
|
4
4
|
|
|
5
|
-
`video-maker-mcp` does not run its own LLM
|
|
5
|
+
`video-maker-mcp` does not run its own LLM. Codex writes the script and storyboard, then this MCP server uses Doubao Seedream to generate scene images, validates assets, generates Doubao/Volcengine narration, and renders a 9:16 MP4 with ffmpeg. The requested duration is treated as a target; final video length follows the generated narration audio so speech is not cut off or padded with silence.
|
|
6
6
|
|
|
7
7
|
## Install With Codex
|
|
8
8
|
|
|
@@ -15,6 +15,9 @@ npx -y video-maker-mcp@latest install --host codex
|
|
|
15
15
|
如果提示缺少 ffmpeg,请按提示安装 ffmpeg,然后重新运行:
|
|
16
16
|
npx -y video-maker-mcp@latest doctor
|
|
17
17
|
|
|
18
|
+
如果提示缺少图片配置,请执行:
|
|
19
|
+
npx -y video-maker-mcp@latest configure-image
|
|
20
|
+
|
|
18
21
|
如果提示缺少 TTS 配置,请执行:
|
|
19
22
|
npx -y video-maker-mcp@latest configure-tts
|
|
20
23
|
|
|
@@ -25,6 +28,7 @@ Manual command:
|
|
|
25
28
|
|
|
26
29
|
```bash
|
|
27
30
|
npx -y video-maker-mcp@latest install --host codex
|
|
31
|
+
npx -y video-maker-mcp@latest configure-image
|
|
28
32
|
npx -y video-maker-mcp@latest configure-tts
|
|
29
33
|
npx -y video-maker-mcp@latest doctor
|
|
30
34
|
```
|
|
@@ -42,6 +46,7 @@ It does not silently install system packages and does not bundle `ffmpeg-static`
|
|
|
42
46
|
- Node.js 20+
|
|
43
47
|
- Codex CLI
|
|
44
48
|
- ffmpeg on PATH
|
|
49
|
+
- Doubao Seedream image generation credentials
|
|
45
50
|
- Doubao/Volcengine TTS credentials
|
|
46
51
|
|
|
47
52
|
ffmpeg install hints:
|
|
@@ -57,6 +62,46 @@ sudo apt update && sudo apt install -y ffmpeg
|
|
|
57
62
|
winget install Gyan.FFmpeg
|
|
58
63
|
```
|
|
59
64
|
|
|
65
|
+
## Image Environment
|
|
66
|
+
|
|
67
|
+
Scene image generation uses Doubao Seedream by default. Configure it before creating videos:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx -y video-maker-mcp@latest configure-image
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The command prompts for the API key locally, does not require pasting the key into an LLM chat, and writes the configuration to `~/.video-maker/.env`. By default it does not generate a test image, to avoid spending image-generation quota. To run a smoke test:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx -y video-maker-mcp@latest configure-image --test
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
It writes:
|
|
80
|
+
|
|
81
|
+
```env
|
|
82
|
+
VIDEO_MAKER_IMAGE_API_KEY=your-ark-api-key
|
|
83
|
+
VIDEO_MAKER_IMAGE_MODEL=doubao-seedream-5-0-260128
|
|
84
|
+
VIDEO_MAKER_IMAGE_ENDPOINT=https://ark.cn-beijing.volces.com/api/v3/images/generations
|
|
85
|
+
VIDEO_MAKER_IMAGE_SIZE=2K
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`VIDEO_MAKER_IMAGE_API_KEY` can also be supplied as `ARK_API_KEY` or `VOLCENGINE_API_KEY`, but the `VIDEO_MAKER_*` key is preferred for this tool.
|
|
89
|
+
|
|
90
|
+
Quick image smoke test:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm run build
|
|
94
|
+
node dist/cli/index.js image-test --prompt "一张 9:16 竖屏科技短视频封面,真实摄影质感,无文字,无水印。"
|
|
95
|
+
open ~/Downloads/video-maker/seedream-image-test.png
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`image-test --out` accepts either a directory or a `.png` file:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
node dist/cli/index.js image-test --out ~/Downloads/video-maker
|
|
102
|
+
node dist/cli/index.js image-test --out ~/Downloads/my-seedream-test.png
|
|
103
|
+
```
|
|
104
|
+
|
|
60
105
|
## TTS Environment
|
|
61
106
|
|
|
62
107
|
Narrated video generation requires Doubao/Volcengine TTS credentials before `generate_audio` can work.
|
|
@@ -111,7 +156,7 @@ node dist/cli/index.js tts-test --out ~/Downloads/my-voice-test.mp3
|
|
|
111
156
|
Once installed, ask Codex:
|
|
112
157
|
|
|
113
158
|
```text
|
|
114
|
-
用 video-maker
|
|
159
|
+
用 video-maker 把下面文稿生成一个约 60 秒竖屏中文解说视频。请先检查环境,然后创建项目,生成分镜计划,用 Seedream 生成每个分镜图片,验证素材,生成语音,最后渲染 mp4,并把最终文件导出到 ~/Downloads/video-maker。
|
|
115
160
|
```
|
|
116
161
|
|
|
117
162
|
The MCP workflow is:
|
|
@@ -121,23 +166,53 @@ The MCP workflow is:
|
|
|
121
166
|
3. `get_video_plan_schema`
|
|
122
167
|
4. `save_video_plan`
|
|
123
168
|
5. `list_required_assets`
|
|
124
|
-
6.
|
|
125
|
-
7. `
|
|
126
|
-
8. Optional: `
|
|
127
|
-
9. `
|
|
128
|
-
10. `
|
|
129
|
-
11.
|
|
169
|
+
6. `generate_assets`
|
|
170
|
+
7. Optional fallback: `assert_image_generation_contract` + host image generation
|
|
171
|
+
8. Optional fallback bridge: `save_generated_image`
|
|
172
|
+
9. `verify_assets`
|
|
173
|
+
10. Optional: `create_asset_contact_sheet`
|
|
174
|
+
11. `generate_audio`
|
|
175
|
+
12. `render_video`
|
|
176
|
+
13. Optional: `export_video`
|
|
130
177
|
|
|
131
178
|
Important asset contract:
|
|
132
179
|
|
|
180
|
+
- Default: call `generate_assets`. The MCP server uses Doubao Seedream and writes generated images directly to the required project asset paths.
|
|
181
|
+
- Host image generation is only a fallback when Seedream credentials are unavailable and the user explicitly agrees.
|
|
182
|
+
- Do not call ad-hoc external image URLs/APIs from the host to bypass `generate_assets`.
|
|
183
|
+
- Host fallback requires `generate_image_to_file(prompt, absolutePath)`: call a real image model and save the generated bitmap directly to the requested local file path.
|
|
184
|
+
- Fallback bridge: if the host image tool exposes a real generated image as a temporary local file or base64/data URL, call `save_generated_image(projectId, assetPath, sourcePath|imageBase64)` to let MCP persist it to the required asset path.
|
|
185
|
+
- If the host can only show generated images in chat and cannot expose a local file path or bytes/base64, stop. Do not continue with fallback graphics.
|
|
133
186
|
- `list_required_assets` returns the image paths the tool will use, including `assets/cover.png` and scene paths such as `assets/scene_001.png`.
|
|
134
187
|
- Codex must save the actual generated scene image to each returned `absolutePath`.
|
|
135
188
|
- The cover must be a dedicated, content-rich 9:16 cover image generated for the video. It should not be a first-frame extraction.
|
|
136
|
-
- Do not substitute SVGs, chart screenshots, CSS drawings, preview strips, or manually created placeholder graphics.
|
|
189
|
+
- Do not substitute SVGs, chart screenshots, CSS drawings, HTML/canvas/sharp scripted graphics, preview strips, first-frame extractions, or manually created placeholder graphics.
|
|
137
190
|
- `verify_assets` rejects missing files, unreadable files, wrong aspect ratios, tiny files, suspicious placeholder-sized images, and PNG files with same-name SVG sources such as `scene_001.svg`.
|
|
138
191
|
- `create_asset_contact_sheet` creates `output/asset_contact_sheet.png` from the exact image files that `render_video` will use. Check this if the preview does not match the intended generated images.
|
|
139
192
|
- If you intentionally use very small stylized images, override the size threshold with `VIDEO_MAKER_MIN_ASSET_BYTES`.
|
|
140
193
|
|
|
194
|
+
`save_generated_image` accepts exactly one source:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"projectId": "vid_...",
|
|
199
|
+
"assetPath": "assets/scene_001.png",
|
|
200
|
+
"sourcePath": "/tmp/host-generated-image.png"
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
or:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"projectId": "vid_...",
|
|
209
|
+
"assetPath": "assets/scene_001.png",
|
|
210
|
+
"imageBase64": "data:image/png;base64,..."
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
It only writes to asset paths returned by `list_required_assets`, rejects SVG input, normalizes the bitmap to the target format, and immediately runs asset validation.
|
|
215
|
+
|
|
141
216
|
## Timing Model
|
|
142
217
|
|
|
143
218
|
The video is audio-driven:
|
|
@@ -146,6 +221,7 @@ The video is audio-driven:
|
|
|
146
221
|
- After `generate_audio`, `render_video` reads the real narration duration with `ffprobe`.
|
|
147
222
|
- Scene durations and subtitle timing are scaled to fill the audio duration.
|
|
148
223
|
- The final MP4 duration is set to the audio duration, so narration is not cut off and the video does not continue after speech ends.
|
|
224
|
+
- Duration requests are soft targets. For example, a "60 秒" request can finish around 50-70 seconds unless the user explicitly asks for an exact duration. Do not regenerate audio only because it is a few seconds above or below target.
|
|
149
225
|
|
|
150
226
|
## Subtitle Alignment
|
|
151
227
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ConfigureImageOptions {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
model?: string;
|
|
4
|
+
endpoint?: string;
|
|
5
|
+
size?: string;
|
|
6
|
+
envFile?: string;
|
|
7
|
+
test?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ConfigureImageResult {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
envFile: string;
|
|
12
|
+
wroteKeys: string[];
|
|
13
|
+
test?: {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
outputPath?: string;
|
|
16
|
+
bytes?: number;
|
|
17
|
+
error?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function configureImage(options?: ConfigureImageOptions): Promise<ConfigureImageResult>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import readline from "node:readline/promises";
|
|
4
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
5
|
+
import sharp from "sharp";
|
|
6
|
+
import { defaultEnvFile, exportDir, resolveUserPath } from "../core/paths.js";
|
|
7
|
+
import { DEFAULT_SEEDREAM_IMAGE_ENDPOINT, DEFAULT_SEEDREAM_IMAGE_MODEL, DEFAULT_SEEDREAM_IMAGE_SIZE, generateSeedreamImage } from "../providers/image/seedream.js";
|
|
8
|
+
const CONFIG_KEYS = [
|
|
9
|
+
"VIDEO_MAKER_IMAGE_API_KEY",
|
|
10
|
+
"VIDEO_MAKER_IMAGE_MODEL",
|
|
11
|
+
"VIDEO_MAKER_IMAGE_ENDPOINT",
|
|
12
|
+
"VIDEO_MAKER_IMAGE_SIZE"
|
|
13
|
+
];
|
|
14
|
+
export async function configureImage(options = {}) {
|
|
15
|
+
const envFile = options.envFile ? resolveUserPath(options.envFile) : defaultEnvFile();
|
|
16
|
+
const apiKey = (options.apiKey ?? await promptHidden("Doubao Seedream image API Key (hidden): ")).trim();
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
throw new Error("VIDEO_MAKER_IMAGE_API_KEY cannot be empty.");
|
|
19
|
+
}
|
|
20
|
+
const model = options.model ?? await promptWithDefault("Seedream image model", process.env.VIDEO_MAKER_IMAGE_MODEL ?? DEFAULT_SEEDREAM_IMAGE_MODEL);
|
|
21
|
+
const endpoint = options.endpoint ?? await promptWithDefault("Seedream image endpoint", process.env.VIDEO_MAKER_IMAGE_ENDPOINT ?? DEFAULT_SEEDREAM_IMAGE_ENDPOINT);
|
|
22
|
+
const size = options.size ?? await promptWithDefault("Seedream image size", process.env.VIDEO_MAKER_IMAGE_SIZE ?? DEFAULT_SEEDREAM_IMAGE_SIZE);
|
|
23
|
+
await upsertEnvFile(envFile, {
|
|
24
|
+
VIDEO_MAKER_IMAGE_API_KEY: apiKey,
|
|
25
|
+
VIDEO_MAKER_IMAGE_MODEL: model,
|
|
26
|
+
VIDEO_MAKER_IMAGE_ENDPOINT: endpoint,
|
|
27
|
+
VIDEO_MAKER_IMAGE_SIZE: size
|
|
28
|
+
});
|
|
29
|
+
process.env.VIDEO_MAKER_IMAGE_API_KEY = apiKey;
|
|
30
|
+
process.env.VIDEO_MAKER_IMAGE_MODEL = model;
|
|
31
|
+
process.env.VIDEO_MAKER_IMAGE_ENDPOINT = endpoint;
|
|
32
|
+
process.env.VIDEO_MAKER_IMAGE_SIZE = size;
|
|
33
|
+
const result = {
|
|
34
|
+
ok: true,
|
|
35
|
+
envFile,
|
|
36
|
+
wroteKeys: CONFIG_KEYS
|
|
37
|
+
};
|
|
38
|
+
if (options.test) {
|
|
39
|
+
const outputPath = path.join(exportDir(), "seedream-image-test.png");
|
|
40
|
+
try {
|
|
41
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
42
|
+
const image = await generateSeedreamImage("一张 9:16 竖屏短视频封面,现代科技感,丰富细节,真实摄影质感,无文字,无水印。");
|
|
43
|
+
await sharp(image.bytes)
|
|
44
|
+
.rotate()
|
|
45
|
+
.resize(1080, 1920, { fit: "cover", position: "center" })
|
|
46
|
+
.png()
|
|
47
|
+
.toFile(outputPath);
|
|
48
|
+
const stat = await fs.stat(outputPath);
|
|
49
|
+
result.test = {
|
|
50
|
+
ok: true,
|
|
51
|
+
outputPath,
|
|
52
|
+
bytes: stat.size
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
result.ok = false;
|
|
57
|
+
result.test = {
|
|
58
|
+
ok: false,
|
|
59
|
+
error: error instanceof Error ? error.message : String(error)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
async function promptWithDefault(label, defaultValue) {
|
|
66
|
+
const answer = await promptVisible(`${label} [${defaultValue}]: `);
|
|
67
|
+
return answer.trim() || defaultValue;
|
|
68
|
+
}
|
|
69
|
+
async function promptVisible(question) {
|
|
70
|
+
const rl = readline.createInterface({ input, output });
|
|
71
|
+
try {
|
|
72
|
+
return await rl.question(question);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
rl.close();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function promptHidden(question) {
|
|
79
|
+
if (!input.isTTY || !output.isTTY) {
|
|
80
|
+
return promptVisible(question);
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
let value = "";
|
|
84
|
+
const onData = (buffer) => {
|
|
85
|
+
const char = buffer.toString("utf8");
|
|
86
|
+
if (char === "\u0003") {
|
|
87
|
+
cleanup();
|
|
88
|
+
reject(new Error("Canceled."));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (char === "\r" || char === "\n") {
|
|
92
|
+
cleanup();
|
|
93
|
+
output.write("\n");
|
|
94
|
+
resolve(value);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (char === "\u007f" || char === "\b") {
|
|
98
|
+
value = value.slice(0, -1);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
value += char;
|
|
102
|
+
};
|
|
103
|
+
const cleanup = () => {
|
|
104
|
+
input.off("data", onData);
|
|
105
|
+
input.setRawMode(false);
|
|
106
|
+
input.pause();
|
|
107
|
+
};
|
|
108
|
+
output.write(question);
|
|
109
|
+
input.setRawMode(true);
|
|
110
|
+
input.resume();
|
|
111
|
+
input.on("data", onData);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async function upsertEnvFile(envFile, values) {
|
|
115
|
+
await fs.mkdir(path.dirname(envFile), { recursive: true });
|
|
116
|
+
let existing = "";
|
|
117
|
+
try {
|
|
118
|
+
existing = await fs.readFile(envFile, "utf8");
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (error.code !== "ENOENT")
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
const seen = new Set();
|
|
125
|
+
const lines = existing.length > 0 ? existing.split(/\r?\n/) : [];
|
|
126
|
+
const nextLines = lines.map((line) => {
|
|
127
|
+
const match = /^([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(line);
|
|
128
|
+
if (!match)
|
|
129
|
+
return line;
|
|
130
|
+
const key = match[1];
|
|
131
|
+
if (!(key in values))
|
|
132
|
+
return line;
|
|
133
|
+
seen.add(key);
|
|
134
|
+
return `${key}=${formatEnvValue(values[key])}`;
|
|
135
|
+
});
|
|
136
|
+
for (const [key, value] of Object.entries(values)) {
|
|
137
|
+
if (!seen.has(key)) {
|
|
138
|
+
nextLines.push(`${key}=${formatEnvValue(value)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const content = `${nextLines.filter((line, index, all) => line.length > 0 || index < all.length - 1).join("\n")}\n`;
|
|
142
|
+
await fs.writeFile(envFile, content, { mode: 0o600 });
|
|
143
|
+
await fs.chmod(envFile, 0o600).catch(() => undefined);
|
|
144
|
+
}
|
|
145
|
+
function formatEnvValue(value) {
|
|
146
|
+
return JSON.stringify(value);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=configure-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-image.js","sourceRoot":"","sources":["../../src/cli/configure-image.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -9,6 +9,9 @@ import { synthesizeVolcengineSpeech } from "../providers/tts/volcengine.js";
|
|
|
9
9
|
import { loadCliEnv } from "./load-env.js";
|
|
10
10
|
import { DEFAULT_EXPORT_DIR, resolveUserPath } from "../core/paths.js";
|
|
11
11
|
import { configureTts } from "./configure-tts.js";
|
|
12
|
+
import { configureImage } from "./configure-image.js";
|
|
13
|
+
import { generateSeedreamImage } from "../providers/image/seedream.js";
|
|
14
|
+
import sharp from "sharp";
|
|
12
15
|
loadCliEnv();
|
|
13
16
|
const program = new Command();
|
|
14
17
|
function readPackageVersion() {
|
|
@@ -23,6 +26,9 @@ function readPackageVersion() {
|
|
|
23
26
|
function defaultTtsTestPath() {
|
|
24
27
|
return path.join(DEFAULT_EXPORT_DIR, "doubao-tts-test.mp3");
|
|
25
28
|
}
|
|
29
|
+
function defaultImageTestPath() {
|
|
30
|
+
return path.join(DEFAULT_EXPORT_DIR, "seedream-image-test.png");
|
|
31
|
+
}
|
|
26
32
|
async function resolveOutputPath(output) {
|
|
27
33
|
const resolved = resolveUserPath(output);
|
|
28
34
|
if (path.extname(resolved).toLowerCase() === ".mp3") {
|
|
@@ -32,6 +38,15 @@ async function resolveOutputPath(output) {
|
|
|
32
38
|
await fs.mkdir(resolved, { recursive: true });
|
|
33
39
|
return path.join(resolved, "doubao-tts-test.mp3");
|
|
34
40
|
}
|
|
41
|
+
async function resolvePngOutputPath(output) {
|
|
42
|
+
const resolved = resolveUserPath(output);
|
|
43
|
+
if (path.extname(resolved).toLowerCase() === ".png") {
|
|
44
|
+
await fs.mkdir(path.dirname(resolved), { recursive: true });
|
|
45
|
+
return resolved;
|
|
46
|
+
}
|
|
47
|
+
await fs.mkdir(resolved, { recursive: true });
|
|
48
|
+
return path.join(resolved, "seedream-image-test.png");
|
|
49
|
+
}
|
|
35
50
|
program
|
|
36
51
|
.name("video-maker-mcp")
|
|
37
52
|
.description("Local MCP storyboard video renderer for Codex.")
|
|
@@ -89,6 +104,28 @@ program
|
|
|
89
104
|
if (!result.ok)
|
|
90
105
|
process.exitCode = 1;
|
|
91
106
|
});
|
|
107
|
+
program
|
|
108
|
+
.command("configure-image")
|
|
109
|
+
.description("Configure Doubao Seedream image generation credentials in the local video-maker env file.")
|
|
110
|
+
.option("--model <id>", "Seedream image model", undefined)
|
|
111
|
+
.option("--endpoint <url>", "Seedream image endpoint", undefined)
|
|
112
|
+
.option("--size <size>", "Seedream image size, e.g. 2K or 3K", undefined)
|
|
113
|
+
.option("--config-file <path>", "Env file to write; defaults to ~/.video-maker/.env")
|
|
114
|
+
.option("--test", "Generate a test PNG after writing configuration.")
|
|
115
|
+
.addOption(new Option("--api-key <key>", "Image API key").hideHelp())
|
|
116
|
+
.action(async (opts) => {
|
|
117
|
+
const result = await configureImage({
|
|
118
|
+
apiKey: opts.apiKey,
|
|
119
|
+
model: opts.model,
|
|
120
|
+
endpoint: opts.endpoint,
|
|
121
|
+
size: opts.size,
|
|
122
|
+
envFile: opts.configFile,
|
|
123
|
+
test: opts.test
|
|
124
|
+
});
|
|
125
|
+
console.log(JSON.stringify(result, null, 2));
|
|
126
|
+
if (!result.ok)
|
|
127
|
+
process.exitCode = 1;
|
|
128
|
+
});
|
|
92
129
|
program
|
|
93
130
|
.command("tts-test")
|
|
94
131
|
.description("Generate a short MP3 with the configured Doubao/Volcengine TTS credentials.")
|
|
@@ -100,6 +137,22 @@ program
|
|
|
100
137
|
await fs.writeFile(outputPath, audio);
|
|
101
138
|
console.log(JSON.stringify({ ok: true, outputPath, bytes: audio.length }, null, 2));
|
|
102
139
|
});
|
|
140
|
+
program
|
|
141
|
+
.command("image-test")
|
|
142
|
+
.description("Generate a short PNG with the configured Doubao Seedream image credentials.")
|
|
143
|
+
.option("--prompt <prompt>", "Prompt to generate", "一张 9:16 竖屏短视频封面,现代科技感,丰富细节,真实摄影质感,无文字,无水印。")
|
|
144
|
+
.option("--out <path>", "Output PNG path or directory", defaultImageTestPath())
|
|
145
|
+
.action(async (opts) => {
|
|
146
|
+
const outputPath = await resolvePngOutputPath(opts.out);
|
|
147
|
+
const image = await generateSeedreamImage(opts.prompt);
|
|
148
|
+
await sharp(image.bytes)
|
|
149
|
+
.rotate()
|
|
150
|
+
.resize(1080, 1920, { fit: "cover", position: "center" })
|
|
151
|
+
.png()
|
|
152
|
+
.toFile(outputPath);
|
|
153
|
+
const stat = await fs.stat(outputPath);
|
|
154
|
+
console.log(JSON.stringify({ ok: true, outputPath, bytes: stat.size, source: image.source }, null, 2));
|
|
155
|
+
});
|
|
103
156
|
program.parseAsync(process.argv).catch((error) => {
|
|
104
157
|
console.error(error instanceof Error ? error.message : String(error));
|
|
105
158
|
process.exitCode = 1;
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/core/assets.d.ts
CHANGED
|
@@ -37,7 +37,54 @@ export interface AssetContactSheetResult {
|
|
|
37
37
|
contactSheetPath: string;
|
|
38
38
|
absolutePath: string;
|
|
39
39
|
}
|
|
40
|
+
export interface SavedGeneratedImageResult {
|
|
41
|
+
projectId: string;
|
|
42
|
+
assetPath: string;
|
|
43
|
+
absolutePath: string;
|
|
44
|
+
source: "sourcePath" | "imageBase64";
|
|
45
|
+
asset: VerifiedAsset;
|
|
46
|
+
}
|
|
47
|
+
export interface GeneratedAsset {
|
|
48
|
+
kind: "scene" | "cover";
|
|
49
|
+
sceneId: string;
|
|
50
|
+
assetPath: string;
|
|
51
|
+
absolutePath: string;
|
|
52
|
+
provider: "seedream";
|
|
53
|
+
model: string;
|
|
54
|
+
skipped: boolean;
|
|
55
|
+
source?: "url" | "b64_json";
|
|
56
|
+
revisedPrompt?: string;
|
|
57
|
+
asset: VerifiedAsset;
|
|
58
|
+
}
|
|
59
|
+
export interface GenerateAssetsResult {
|
|
60
|
+
projectId: string;
|
|
61
|
+
provider: "seedream";
|
|
62
|
+
model: string;
|
|
63
|
+
endpoint: string;
|
|
64
|
+
generated: GeneratedAsset[];
|
|
65
|
+
}
|
|
66
|
+
export interface ImageGenerationContract {
|
|
67
|
+
ok: false;
|
|
68
|
+
requiredCapability: "host_image_fallback";
|
|
69
|
+
contract: {
|
|
70
|
+
operation: string;
|
|
71
|
+
mustUseRealImageModel: true;
|
|
72
|
+
mustSaveToExactAbsolutePath: true;
|
|
73
|
+
mustStopIfUnsupported: true;
|
|
74
|
+
forbiddenFallbacks: string[];
|
|
75
|
+
};
|
|
76
|
+
instruction: string;
|
|
77
|
+
}
|
|
78
|
+
export interface SaveGeneratedImageInput {
|
|
79
|
+
sourcePath?: string;
|
|
80
|
+
imageBase64?: string;
|
|
81
|
+
}
|
|
82
|
+
export declare function imageGenerationContract(): ImageGenerationContract;
|
|
40
83
|
export declare function listRequiredAssets(projectId: string): Promise<RequiredAsset[]>;
|
|
84
|
+
export declare function generateAssets(projectId: string, options?: {
|
|
85
|
+
overwrite?: boolean;
|
|
86
|
+
includeCover?: boolean;
|
|
87
|
+
}): Promise<GenerateAssetsResult>;
|
|
41
88
|
export declare function verifyAssets(projectId: string): Promise<{
|
|
42
89
|
ok: boolean;
|
|
43
90
|
assets: Array<VerifiedAsset | AssetIssue>;
|
|
@@ -46,4 +93,5 @@ export declare function verifySceneAssets(projectId: string): Promise<{
|
|
|
46
93
|
ok: boolean;
|
|
47
94
|
assets: Array<VerifiedAsset | AssetIssue>;
|
|
48
95
|
}>;
|
|
96
|
+
export declare function saveGeneratedImage(projectId: string, assetPath: string, input: SaveGeneratedImageInput): Promise<SavedGeneratedImageResult>;
|
|
49
97
|
export declare function createAssetContactSheet(projectId: string): Promise<AssetContactSheetResult>;
|
package/dist/core/assets.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import sharp from "sharp";
|
|
4
|
+
import { generateSeedreamImage, seedreamImageConfigFromEnv } from "../providers/image/seedream.js";
|
|
3
5
|
import { readVideoPlan, markStatus } from "./project.js";
|
|
4
|
-
import { toProjectPath } from "./paths.js";
|
|
6
|
+
import { resolveUserPath, toProjectPath } from "./paths.js";
|
|
5
7
|
const DEFAULT_MIN_ASSET_BYTES = 150 * 1024;
|
|
6
8
|
const MIN_ASSET_WIDTH = 720;
|
|
7
9
|
const MIN_ASSET_HEIGHT = 1280;
|
|
@@ -14,6 +16,30 @@ function minAssetBytes() {
|
|
|
14
16
|
const parsed = Number(raw);
|
|
15
17
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_MIN_ASSET_BYTES;
|
|
16
18
|
}
|
|
19
|
+
export function imageGenerationContract() {
|
|
20
|
+
return {
|
|
21
|
+
ok: false,
|
|
22
|
+
requiredCapability: "host_image_fallback",
|
|
23
|
+
contract: {
|
|
24
|
+
operation: "fallback only: generate_image_to_file(prompt, absolutePath), or save_generated_image(projectId, assetPath, sourcePath|imageBase64)",
|
|
25
|
+
mustUseRealImageModel: true,
|
|
26
|
+
mustSaveToExactAbsolutePath: true,
|
|
27
|
+
mustStopIfUnsupported: true,
|
|
28
|
+
forbiddenFallbacks: [
|
|
29
|
+
"chat-only image preview without local file output",
|
|
30
|
+
"SVG generation",
|
|
31
|
+
"SVG-to-PNG conversion",
|
|
32
|
+
"HTML/CSS/canvas drawing",
|
|
33
|
+
"sharp/Jimp/canvas scripted graphics",
|
|
34
|
+
"chart or infographic screenshots",
|
|
35
|
+
"first-frame extraction",
|
|
36
|
+
"placeholder or manually composed fallback images",
|
|
37
|
+
"ad-hoc external image API calls from the host"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
instruction: "Default image generation should use generate_assets with Doubao Seedream. This contract is only for an explicit host fallback when Seedream credentials are unavailable and the user agrees. The host must provide a real image generation capability that can save the generated bitmap directly to the requested absolutePath, or expose a real generated image file path/base64 for save_generated_image. Do not call temporary external image URLs/APIs from the host to bypass generate_assets."
|
|
41
|
+
};
|
|
42
|
+
}
|
|
17
43
|
export async function listRequiredAssets(projectId) {
|
|
18
44
|
const plan = await readVideoPlan(projectId);
|
|
19
45
|
const sceneAssets = plan.scenes.map((scene) => ({
|
|
@@ -28,7 +54,7 @@ export async function listRequiredAssets(projectId) {
|
|
|
28
54
|
minHeight: MIN_ASSET_HEIGHT,
|
|
29
55
|
aspectRatio: "9:16",
|
|
30
56
|
minBytes: minAssetBytes(),
|
|
31
|
-
note: "
|
|
57
|
+
note: "Default: generate_assets uses Doubao Seedream and writes a real image model output exactly to this path. Do not create placeholder SVGs, charts, screenshots, HTML/CSS/canvas/sharp scripted graphics, preview strips, manually drawn fallback graphics, or host-side ad-hoc external API downloads."
|
|
32
58
|
}
|
|
33
59
|
}));
|
|
34
60
|
return [
|
|
@@ -44,7 +70,7 @@ export async function listRequiredAssets(projectId) {
|
|
|
44
70
|
minHeight: MIN_ASSET_HEIGHT,
|
|
45
71
|
aspectRatio: "9:16",
|
|
46
72
|
minBytes: minAssetBytes(),
|
|
47
|
-
note: "
|
|
73
|
+
note: "Default: generate_assets uses Doubao Seedream to create a dedicated, content-rich vertical cover image. It should not be a screenshot, SVG, chart-only graphic, HTML/CSS/canvas/sharp scripted graphic, first-frame extraction, or host-side ad-hoc external API download."
|
|
48
74
|
}
|
|
49
75
|
},
|
|
50
76
|
...sceneAssets
|
|
@@ -62,6 +88,71 @@ function buildCoverPrompt(plan) {
|
|
|
62
88
|
`Visual themes from the storyboard: ${sceneSummary}`
|
|
63
89
|
].join(" ");
|
|
64
90
|
}
|
|
91
|
+
export async function generateAssets(projectId, options = {}) {
|
|
92
|
+
const config = seedreamImageConfigFromEnv();
|
|
93
|
+
const required = (await listRequiredAssets(projectId)).filter((asset) => options.includeCover !== false || asset.kind !== "cover");
|
|
94
|
+
const generated = [];
|
|
95
|
+
for (const asset of required) {
|
|
96
|
+
if (!options.overwrite) {
|
|
97
|
+
const existing = await validateRequiredAsset(asset);
|
|
98
|
+
if (existing.ok) {
|
|
99
|
+
generated.push({
|
|
100
|
+
kind: asset.kind,
|
|
101
|
+
sceneId: asset.sceneId,
|
|
102
|
+
assetPath: asset.assetPath,
|
|
103
|
+
absolutePath: asset.absolutePath,
|
|
104
|
+
provider: "seedream",
|
|
105
|
+
model: config.model,
|
|
106
|
+
skipped: true,
|
|
107
|
+
asset: existing
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const image = await generateSeedreamImage(buildSeedreamPrompt(asset), config);
|
|
113
|
+
await fs.mkdir(path.dirname(asset.absolutePath), { recursive: true });
|
|
114
|
+
await sharp(image.bytes)
|
|
115
|
+
.rotate()
|
|
116
|
+
.resize(1080, 1920, { fit: "cover", position: "center" })
|
|
117
|
+
.toFormat(outputFormat(asset.assetPath))
|
|
118
|
+
.toFile(asset.absolutePath);
|
|
119
|
+
const verified = await validateRequiredAsset(asset);
|
|
120
|
+
if (!verified.ok) {
|
|
121
|
+
throw new Error(`Seedream generated invalid asset ${asset.assetPath}: ${verified.error}`);
|
|
122
|
+
}
|
|
123
|
+
generated.push({
|
|
124
|
+
kind: asset.kind,
|
|
125
|
+
sceneId: asset.sceneId,
|
|
126
|
+
assetPath: asset.assetPath,
|
|
127
|
+
absolutePath: asset.absolutePath,
|
|
128
|
+
provider: "seedream",
|
|
129
|
+
model: config.model,
|
|
130
|
+
skipped: false,
|
|
131
|
+
source: image.source,
|
|
132
|
+
revisedPrompt: image.revisedPrompt,
|
|
133
|
+
asset: verified
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (generated.length > 0 && generated.every((item) => item.asset.ok)) {
|
|
137
|
+
const cover = generated.find((item) => item.kind === "cover");
|
|
138
|
+
await markStatus(projectId, "assets_ready", cover ? { coverPath: cover.assetPath } : {});
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
projectId,
|
|
142
|
+
provider: "seedream",
|
|
143
|
+
model: config.model,
|
|
144
|
+
endpoint: config.endpoint,
|
|
145
|
+
generated
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function buildSeedreamPrompt(asset) {
|
|
149
|
+
return [
|
|
150
|
+
asset.prompt,
|
|
151
|
+
"Vertical 9:16 short-video production still.",
|
|
152
|
+
"Generate a rich, photographic/editorial bitmap image suitable for a 1080x1920 video scene.",
|
|
153
|
+
"No watermarks. No real brand logos. Avoid tiny unreadable text. Avoid charts-only visuals, screenshots, UI mockups, SVG/vector style, or placeholder graphics."
|
|
154
|
+
].join("\n");
|
|
155
|
+
}
|
|
65
156
|
export async function verifyAssets(projectId) {
|
|
66
157
|
return verifyProjectAssets(projectId, { includeCover: true });
|
|
67
158
|
}
|
|
@@ -70,57 +161,7 @@ export async function verifySceneAssets(projectId) {
|
|
|
70
161
|
}
|
|
71
162
|
async function verifyProjectAssets(projectId, options) {
|
|
72
163
|
const required = (await listRequiredAssets(projectId)).filter((asset) => options.includeCover || asset.kind !== "cover");
|
|
73
|
-
const assets = await Promise.all(required.map(
|
|
74
|
-
try {
|
|
75
|
-
await fs.access(asset.absolutePath);
|
|
76
|
-
const forbiddenSourcePath = asset.absolutePath.replace(/\.[^.]+$/, ".svg");
|
|
77
|
-
try {
|
|
78
|
-
await fs.access(forbiddenSourcePath);
|
|
79
|
-
throw new Error(`Found sibling SVG source file ${forbiddenSourcePath}. This asset appears to be a generated SVG/chart converted to PNG, not a host image-generation result.`);
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
if (error.code !== "ENOENT")
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
const stat = await fs.stat(asset.absolutePath);
|
|
86
|
-
const metadata = await sharp(asset.absolutePath).metadata();
|
|
87
|
-
if (!metadata.width || !metadata.height) {
|
|
88
|
-
throw new Error("Image dimensions could not be read");
|
|
89
|
-
}
|
|
90
|
-
if (metadata.width < MIN_ASSET_WIDTH || metadata.height < MIN_ASSET_HEIGHT) {
|
|
91
|
-
throw new Error(`Image is too small: ${metadata.width}x${metadata.height}; expected at least ${MIN_ASSET_WIDTH}x${MIN_ASSET_HEIGHT}`);
|
|
92
|
-
}
|
|
93
|
-
const aspectRatio = metadata.width / metadata.height;
|
|
94
|
-
if (Math.abs(aspectRatio - TARGET_ASPECT_RATIO) > ASPECT_RATIO_TOLERANCE) {
|
|
95
|
-
throw new Error(`Image aspect ratio is ${metadata.width}:${metadata.height}; expected 9:16 vertical imagery`);
|
|
96
|
-
}
|
|
97
|
-
const minimumBytes = minAssetBytes();
|
|
98
|
-
if (stat.size < minimumBytes) {
|
|
99
|
-
throw new Error(`Image file is suspiciously small: ${stat.size} bytes; expected at least ${minimumBytes} bytes. This often means a placeholder graphic was saved instead of a host-generated image.`);
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
kind: asset.kind,
|
|
103
|
-
sceneId: asset.sceneId,
|
|
104
|
-
assetPath: asset.assetPath,
|
|
105
|
-
absolutePath: asset.absolutePath,
|
|
106
|
-
ok: true,
|
|
107
|
-
width: metadata.width,
|
|
108
|
-
height: metadata.height,
|
|
109
|
-
bytes: stat.size,
|
|
110
|
-
format: metadata.format
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
return {
|
|
115
|
-
kind: asset.kind,
|
|
116
|
-
sceneId: asset.sceneId,
|
|
117
|
-
assetPath: asset.assetPath,
|
|
118
|
-
absolutePath: asset.absolutePath,
|
|
119
|
-
ok: false,
|
|
120
|
-
error: error instanceof Error ? error.message : String(error)
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
}));
|
|
164
|
+
const assets = await Promise.all(required.map(validateRequiredAsset));
|
|
124
165
|
const ok = assets.every((asset) => asset.ok);
|
|
125
166
|
if (ok) {
|
|
126
167
|
const cover = assets.find((asset) => asset.ok && asset.kind === "cover");
|
|
@@ -128,6 +169,116 @@ async function verifyProjectAssets(projectId, options) {
|
|
|
128
169
|
}
|
|
129
170
|
return { ok, assets };
|
|
130
171
|
}
|
|
172
|
+
async function validateRequiredAsset(asset) {
|
|
173
|
+
try {
|
|
174
|
+
await fs.access(asset.absolutePath);
|
|
175
|
+
const forbiddenSourcePath = asset.absolutePath.replace(/\.[^.]+$/, ".svg");
|
|
176
|
+
try {
|
|
177
|
+
await fs.access(forbiddenSourcePath);
|
|
178
|
+
throw new Error(`Found sibling SVG source file ${forbiddenSourcePath}. This asset appears to be a generated SVG/chart converted to PNG, not a host image-generation result.`);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (error.code !== "ENOENT")
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
const stat = await fs.stat(asset.absolutePath);
|
|
185
|
+
const metadata = await sharp(asset.absolutePath).metadata();
|
|
186
|
+
if (!metadata.width || !metadata.height) {
|
|
187
|
+
throw new Error("Image dimensions could not be read");
|
|
188
|
+
}
|
|
189
|
+
if (metadata.width < MIN_ASSET_WIDTH || metadata.height < MIN_ASSET_HEIGHT) {
|
|
190
|
+
throw new Error(`Image is too small: ${metadata.width}x${metadata.height}; expected at least ${MIN_ASSET_WIDTH}x${MIN_ASSET_HEIGHT}`);
|
|
191
|
+
}
|
|
192
|
+
const aspectRatio = metadata.width / metadata.height;
|
|
193
|
+
if (Math.abs(aspectRatio - TARGET_ASPECT_RATIO) > ASPECT_RATIO_TOLERANCE) {
|
|
194
|
+
throw new Error(`Image aspect ratio is ${metadata.width}:${metadata.height}; expected 9:16 vertical imagery`);
|
|
195
|
+
}
|
|
196
|
+
const minimumBytes = minAssetBytes();
|
|
197
|
+
if (stat.size < minimumBytes) {
|
|
198
|
+
throw new Error(`Image file is suspiciously small: ${stat.size} bytes; expected at least ${minimumBytes} bytes. This often means a placeholder graphic was saved instead of a host-generated image.`);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
kind: asset.kind,
|
|
202
|
+
sceneId: asset.sceneId,
|
|
203
|
+
assetPath: asset.assetPath,
|
|
204
|
+
absolutePath: asset.absolutePath,
|
|
205
|
+
ok: true,
|
|
206
|
+
width: metadata.width,
|
|
207
|
+
height: metadata.height,
|
|
208
|
+
bytes: stat.size,
|
|
209
|
+
format: metadata.format
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
return {
|
|
214
|
+
kind: asset.kind,
|
|
215
|
+
sceneId: asset.sceneId,
|
|
216
|
+
assetPath: asset.assetPath,
|
|
217
|
+
absolutePath: asset.absolutePath,
|
|
218
|
+
ok: false,
|
|
219
|
+
error: error instanceof Error ? error.message : String(error)
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export async function saveGeneratedImage(projectId, assetPath, input) {
|
|
224
|
+
const required = (await listRequiredAssets(projectId)).find((asset) => asset.assetPath === assetPath);
|
|
225
|
+
if (!required) {
|
|
226
|
+
throw new Error(`assetPath is not required by this project: ${assetPath}`);
|
|
227
|
+
}
|
|
228
|
+
if ((input.sourcePath ? 1 : 0) + (input.imageBase64 ? 1 : 0) !== 1) {
|
|
229
|
+
throw new Error("Provide exactly one of sourcePath or imageBase64.");
|
|
230
|
+
}
|
|
231
|
+
const source = input.sourcePath ? "sourcePath" : "imageBase64";
|
|
232
|
+
const bytes = input.sourcePath ? await readSourceImage(input.sourcePath) : decodeImageBase64(input.imageBase64 ?? "");
|
|
233
|
+
const metadata = await sharp(bytes).metadata();
|
|
234
|
+
if (metadata.format === "svg") {
|
|
235
|
+
throw new Error("SVG input is not accepted. Provide a real bitmap generated by an image model.");
|
|
236
|
+
}
|
|
237
|
+
await fs.mkdir(path.dirname(required.absolutePath), { recursive: true });
|
|
238
|
+
await sharp(bytes)
|
|
239
|
+
.rotate()
|
|
240
|
+
.toFormat(outputFormat(required.assetPath))
|
|
241
|
+
.toFile(required.absolutePath);
|
|
242
|
+
const asset = await validateRequiredAsset(required);
|
|
243
|
+
if (!asset.ok) {
|
|
244
|
+
throw new Error(asset.error);
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
projectId,
|
|
248
|
+
assetPath,
|
|
249
|
+
absolutePath: required.absolutePath,
|
|
250
|
+
source,
|
|
251
|
+
asset
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
async function readSourceImage(sourcePath) {
|
|
255
|
+
const resolved = resolveUserPath(sourcePath);
|
|
256
|
+
if (/\.svg$/i.test(resolved)) {
|
|
257
|
+
throw new Error("SVG sourcePath is not accepted. Provide a real generated bitmap file.");
|
|
258
|
+
}
|
|
259
|
+
return fs.readFile(resolved);
|
|
260
|
+
}
|
|
261
|
+
function decodeImageBase64(value) {
|
|
262
|
+
const trimmed = value.trim();
|
|
263
|
+
if (trimmed.startsWith("data:")) {
|
|
264
|
+
const match = /^data:([^;,]+)(?:;[^,]*)?;base64,(.*)$/s.exec(trimmed);
|
|
265
|
+
if (!match)
|
|
266
|
+
throw new Error("Invalid data URL. Expected data:image/...;base64,...");
|
|
267
|
+
if (match[1].includes("svg")) {
|
|
268
|
+
throw new Error("SVG data URL is not accepted. Provide a real generated bitmap.");
|
|
269
|
+
}
|
|
270
|
+
return Buffer.from(match[2], "base64");
|
|
271
|
+
}
|
|
272
|
+
return Buffer.from(trimmed, "base64");
|
|
273
|
+
}
|
|
274
|
+
function outputFormat(assetPath) {
|
|
275
|
+
const ext = path.extname(assetPath).toLowerCase();
|
|
276
|
+
if (ext === ".jpg" || ext === ".jpeg")
|
|
277
|
+
return "jpeg";
|
|
278
|
+
if (ext === ".webp")
|
|
279
|
+
return "webp";
|
|
280
|
+
return "png";
|
|
281
|
+
}
|
|
131
282
|
export async function createAssetContactSheet(projectId) {
|
|
132
283
|
const required = await listRequiredAssets(projectId);
|
|
133
284
|
if (required.length === 0) {
|
package/dist/core/assets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/core/assets.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/core/assets.ts"],"names":[],"mappings":"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"}
|
package/dist/core/env.d.ts
CHANGED
|
@@ -9,6 +9,13 @@ export interface TtsCheck {
|
|
|
9
9
|
configured: boolean;
|
|
10
10
|
missingEnv: string[];
|
|
11
11
|
}
|
|
12
|
+
export interface ImageCheck {
|
|
13
|
+
configured: boolean;
|
|
14
|
+
missingEnv: string[];
|
|
15
|
+
provider: "seedream";
|
|
16
|
+
model: string;
|
|
17
|
+
endpoint: string;
|
|
18
|
+
}
|
|
12
19
|
export interface EnvironmentCheck {
|
|
13
20
|
ok: boolean;
|
|
14
21
|
node: {
|
|
@@ -18,6 +25,7 @@ export interface EnvironmentCheck {
|
|
|
18
25
|
ffmpeg: BinaryCheck;
|
|
19
26
|
codex: BinaryCheck;
|
|
20
27
|
tts: TtsCheck;
|
|
28
|
+
image: ImageCheck;
|
|
21
29
|
workspaceDir: string;
|
|
22
30
|
defaultExportDir: string;
|
|
23
31
|
nextActions: string[];
|
package/dist/core/env.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import { execa } from "execa";
|
|
3
3
|
import which from "which";
|
|
4
|
+
import { DEFAULT_SEEDREAM_IMAGE_ENDPOINT, DEFAULT_SEEDREAM_IMAGE_MODEL, missingSeedreamImageEnv } from "../providers/image/seedream.js";
|
|
4
5
|
import { exportDir, workspaceDir } from "./paths.js";
|
|
5
6
|
function missingTtsEnv(env = process.env) {
|
|
6
7
|
const missing = [];
|
|
@@ -56,6 +57,7 @@ export async function checkEnvironment() {
|
|
|
56
57
|
resolveBinary("codex", ["--version"])
|
|
57
58
|
]);
|
|
58
59
|
const missingEnv = missingTtsEnv();
|
|
60
|
+
const missingImageEnv = missingSeedreamImageEnv();
|
|
59
61
|
const nextActions = [];
|
|
60
62
|
if (!ffmpeg.installed) {
|
|
61
63
|
nextActions.push(`Install ffmpeg: ${ffmpeg.installCommand ?? ffmpegInstallCommand()}`);
|
|
@@ -66,11 +68,14 @@ export async function checkEnvironment() {
|
|
|
66
68
|
if (missingEnv.length > 0) {
|
|
67
69
|
nextActions.push(`Configure TTS credentials: npx -y video-maker-mcp@latest configure-tts (missing: ${missingEnv.join(", ")})`);
|
|
68
70
|
}
|
|
71
|
+
if (missingImageEnv.length > 0) {
|
|
72
|
+
nextActions.push(`Configure Seedream image credentials: set VIDEO_MAKER_IMAGE_API_KEY in .env or ~/.video-maker/.env (missing: ${missingImageEnv.join(", ")})`);
|
|
73
|
+
}
|
|
69
74
|
if (nodeMajor < 20) {
|
|
70
75
|
nextActions.push("Install Node.js 20 or newer.");
|
|
71
76
|
}
|
|
72
77
|
return {
|
|
73
|
-
ok: nodeMajor >= 20 && ffmpeg.installed && missingEnv.length === 0,
|
|
78
|
+
ok: nodeMajor >= 20 && ffmpeg.installed && missingEnv.length === 0 && missingImageEnv.length === 0,
|
|
74
79
|
node: {
|
|
75
80
|
version: process.versions.node,
|
|
76
81
|
ok: nodeMajor >= 20
|
|
@@ -81,6 +86,13 @@ export async function checkEnvironment() {
|
|
|
81
86
|
configured: missingEnv.length === 0,
|
|
82
87
|
missingEnv
|
|
83
88
|
},
|
|
89
|
+
image: {
|
|
90
|
+
configured: missingImageEnv.length === 0,
|
|
91
|
+
missingEnv: missingImageEnv,
|
|
92
|
+
provider: "seedream",
|
|
93
|
+
model: process.env.VIDEO_MAKER_IMAGE_MODEL ?? DEFAULT_SEEDREAM_IMAGE_MODEL,
|
|
94
|
+
endpoint: process.env.VIDEO_MAKER_IMAGE_ENDPOINT ?? DEFAULT_SEEDREAM_IMAGE_ENDPOINT
|
|
95
|
+
},
|
|
84
96
|
workspaceDir: workspaceDir(),
|
|
85
97
|
defaultExportDir: exportDir(),
|
|
86
98
|
nextActions
|
package/dist/core/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -2,7 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
4
|
import { checkEnvironment } from "../core/env.js";
|
|
5
|
-
import { createAssetContactSheet, listRequiredAssets, verifyAssets } from "../core/assets.js";
|
|
5
|
+
import { createAssetContactSheet, generateAssets, imageGenerationContract, listRequiredAssets, saveGeneratedImage, verifyAssets } from "../core/assets.js";
|
|
6
6
|
import { createVideoProject, saveVideoPlan } from "../core/project.js";
|
|
7
7
|
import { videoPlanJsonSchema } from "../core/plan-schema.js";
|
|
8
8
|
import { generateProjectAudio } from "../providers/tts/volcengine.js";
|
|
@@ -10,11 +10,14 @@ import { renderProjectVideo } from "../core/render.js";
|
|
|
10
10
|
import { exportProjectVideo } from "../core/export.js";
|
|
11
11
|
const SERVER_INSTRUCTIONS = [
|
|
12
12
|
"video-maker-mcp turns Codex-authored storyboards into local vertical MP4 videos.",
|
|
13
|
-
"Workflow: call create_video_project, get_video_plan_schema, save_video_plan, list_required_assets,
|
|
14
|
-
"
|
|
13
|
+
"Workflow: call check_environment, create_video_project, get_video_plan_schema, save_video_plan, list_required_assets, generate_assets, verify_assets, optionally create_asset_contact_sheet for visual confirmation, generate_audio, then render_video.",
|
|
14
|
+
"Default image generation is internal: generate_assets calls Doubao Seedream with VIDEO_MAKER_IMAGE_API_KEY and writes the generated bitmaps into the exact project asset paths.",
|
|
15
|
+
"Only if Seedream image credentials are unavailable and the user explicitly agrees, use the host fallback: assert_image_generation_contract, then host generate_image_to_file(prompt, absolutePath), or save_generated_image(projectId, assetPath, sourcePath|imageBase64).",
|
|
16
|
+
"Do not call ad-hoc external image URLs/APIs from the host to bypass generate_assets. Do not substitute SVGs, charts, screenshots, HTML/CSS/canvas drawings, sharp/Jimp/canvas scripted graphics, preview strips, manually created placeholder graphics, first-frame extractions, or SVG-to-PNG conversions.",
|
|
15
17
|
"Videos are 9:16, 1080x1920, zh-CN subtitles, one image per scene. Requested duration is a target; render_video uses the real narration audio duration and scales scene/subtitle timing to match it.",
|
|
18
|
+
"Duration targets are soft: for a 60s request, roughly 50-70s is acceptable unless the user explicitly asks for exact duration. Do not regenerate narration only because it is a few seconds over or under target.",
|
|
16
19
|
"Rendered project files stay in ~/.video-maker. If the user wants an easy-to-find copy, pass outputDir to render_video or call export_video; default export location is ~/Downloads/video-maker/<projectId>.",
|
|
17
|
-
"Run check_environment first when setup is uncertain. If TTS credentials are missing, tell the user to run: npx -y video-maker-mcp@latest configure-tts."
|
|
20
|
+
"Run check_environment first when setup is uncertain. If image credentials are missing, tell the user to run: npx -y video-maker-mcp@latest configure-image. If TTS credentials are missing, tell the user to run: npx -y video-maker-mcp@latest configure-tts."
|
|
18
21
|
].join("\n");
|
|
19
22
|
function result(structuredContent) {
|
|
20
23
|
return {
|
|
@@ -33,6 +36,10 @@ export function createMcpServer() {
|
|
|
33
36
|
title: "Check local video-maker environment",
|
|
34
37
|
description: "Checks Node, ffmpeg, Codex CLI, workspace path, and Volcengine/Doubao TTS environment variables."
|
|
35
38
|
}, async () => result(await checkEnvironment()));
|
|
39
|
+
server.registerTool("assert_image_generation_contract", {
|
|
40
|
+
title: "Assert host image generation contract",
|
|
41
|
+
description: "Returns the required host capability: generate real image-model output and save it directly to the requested absolutePath. If unsupported, the host must stop instead of creating fallback graphics."
|
|
42
|
+
}, async () => result(imageGenerationContract()));
|
|
36
43
|
server.registerTool("create_video_project", {
|
|
37
44
|
title: "Create video project",
|
|
38
45
|
description: "Creates a local project directory for a Codex-driven storyboard video.",
|
|
@@ -76,8 +83,28 @@ export function createMcpServer() {
|
|
|
76
83
|
}, async ({ projectId }) => result({
|
|
77
84
|
projectId,
|
|
78
85
|
assets: await listRequiredAssets(projectId),
|
|
79
|
-
|
|
86
|
+
imageGenerationContract: imageGenerationContract().contract,
|
|
87
|
+
instruction: "Default next step: call generate_assets so MCP uses Doubao Seedream and saves all assets to these exact paths. Host image generation is only a fallback when Seedream credentials are unavailable and the user explicitly agrees. Do not call temporary external image URLs/APIs from the host to bypass generate_assets."
|
|
80
88
|
}));
|
|
89
|
+
server.registerTool("generate_assets", {
|
|
90
|
+
title: "Generate required video assets with Seedream",
|
|
91
|
+
description: "Generates the dedicated cover and all scene images with Doubao Seedream, writes them to the required project asset paths, and validates each bitmap.",
|
|
92
|
+
inputSchema: {
|
|
93
|
+
projectId: z.string().min(1),
|
|
94
|
+
overwrite: z.boolean().optional().describe("Regenerate assets even if valid files already exist. Defaults to false."),
|
|
95
|
+
includeCover: z.boolean().optional().describe("Generate cover.png as well as scene images. Defaults to true.")
|
|
96
|
+
}
|
|
97
|
+
}, async ({ projectId, overwrite, includeCover }) => result(await generateAssets(projectId, { overwrite, includeCover })));
|
|
98
|
+
server.registerTool("save_generated_image", {
|
|
99
|
+
title: "Save generated image asset",
|
|
100
|
+
description: "Fallback bridge: saves a real host-generated image from a local sourcePath or base64/data URL into a required project assetPath, then validates it.",
|
|
101
|
+
inputSchema: {
|
|
102
|
+
projectId: z.string().min(1),
|
|
103
|
+
assetPath: z.string().min(1).describe("One of the assetPath values returned by list_required_assets, e.g. assets/scene_001.png or assets/cover.png."),
|
|
104
|
+
sourcePath: z.string().min(1).optional().describe("Local path to a real generated bitmap file exposed by the host image tool."),
|
|
105
|
+
imageBase64: z.string().min(1).optional().describe("Generated image bytes as base64 or data:image/...;base64,...")
|
|
106
|
+
}
|
|
107
|
+
}, async ({ projectId, assetPath, sourcePath, imageBase64 }) => result(await saveGeneratedImage(projectId, assetPath, { sourcePath, imageBase64 })));
|
|
81
108
|
server.registerTool("verify_assets", {
|
|
82
109
|
title: "Verify scene assets",
|
|
83
110
|
description: "Checks that all required scene images exist and can be decoded.",
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SeedreamImageConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
endpoint: string;
|
|
4
|
+
model: string;
|
|
5
|
+
size: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SeedreamGeneratedImage {
|
|
8
|
+
bytes: Buffer;
|
|
9
|
+
source: "url" | "b64_json";
|
|
10
|
+
revisedPrompt?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_SEEDREAM_IMAGE_ENDPOINT = "https://ark.cn-beijing.volces.com/api/v3/images/generations";
|
|
13
|
+
export declare const DEFAULT_SEEDREAM_IMAGE_MODEL = "doubao-seedream-5-0-260128";
|
|
14
|
+
export declare const DEFAULT_SEEDREAM_IMAGE_SIZE = "2K";
|
|
15
|
+
export declare function seedreamImageConfigFromEnv(env?: NodeJS.ProcessEnv): SeedreamImageConfig;
|
|
16
|
+
export declare function missingSeedreamImageEnv(env?: NodeJS.ProcessEnv): string[];
|
|
17
|
+
export declare function generateSeedreamImage(prompt: string, config?: SeedreamImageConfig): Promise<SeedreamGeneratedImage>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
export const DEFAULT_SEEDREAM_IMAGE_ENDPOINT = "https://ark.cn-beijing.volces.com/api/v3/images/generations";
|
|
3
|
+
export const DEFAULT_SEEDREAM_IMAGE_MODEL = "doubao-seedream-5-0-260128";
|
|
4
|
+
export const DEFAULT_SEEDREAM_IMAGE_SIZE = "2K";
|
|
5
|
+
export function seedreamImageConfigFromEnv(env = process.env) {
|
|
6
|
+
const apiKey = env.VIDEO_MAKER_IMAGE_API_KEY ?? env.ARK_API_KEY ?? env.VOLCENGINE_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error("Missing Seedream image configuration: VIDEO_MAKER_IMAGE_API_KEY");
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
apiKey,
|
|
12
|
+
endpoint: env.VIDEO_MAKER_IMAGE_ENDPOINT ?? DEFAULT_SEEDREAM_IMAGE_ENDPOINT,
|
|
13
|
+
model: env.VIDEO_MAKER_IMAGE_MODEL ?? DEFAULT_SEEDREAM_IMAGE_MODEL,
|
|
14
|
+
size: env.VIDEO_MAKER_IMAGE_SIZE ?? DEFAULT_SEEDREAM_IMAGE_SIZE
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function missingSeedreamImageEnv(env = process.env) {
|
|
18
|
+
return env.VIDEO_MAKER_IMAGE_API_KEY || env.ARK_API_KEY || env.VOLCENGINE_API_KEY
|
|
19
|
+
? []
|
|
20
|
+
: ["VIDEO_MAKER_IMAGE_API_KEY"];
|
|
21
|
+
}
|
|
22
|
+
export async function generateSeedreamImage(prompt, config = seedreamImageConfigFromEnv()) {
|
|
23
|
+
const response = await fetch(config.endpoint, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Authorization": `Bearer ${config.apiKey}`,
|
|
27
|
+
"Content-Type": "application/json"
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
model: config.model,
|
|
31
|
+
prompt,
|
|
32
|
+
size: config.size,
|
|
33
|
+
response_format: "url",
|
|
34
|
+
output_format: "png",
|
|
35
|
+
sequential_image_generation: "disabled"
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
const raw = await response.text();
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw new Error(`Seedream image HTTP ${response.status}: ${raw}`);
|
|
41
|
+
}
|
|
42
|
+
let payload;
|
|
43
|
+
try {
|
|
44
|
+
payload = JSON.parse(raw);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
throw new Error(`Seedream image returned non-JSON response: ${raw.slice(0, 500)}`);
|
|
48
|
+
}
|
|
49
|
+
const item = payload.data?.[0];
|
|
50
|
+
if (!item) {
|
|
51
|
+
throw new Error(`Seedream image returned no image data: ${raw.slice(0, 500)}`);
|
|
52
|
+
}
|
|
53
|
+
if (typeof item.b64_json === "string" && item.b64_json.length > 0) {
|
|
54
|
+
return {
|
|
55
|
+
bytes: Buffer.from(item.b64_json, "base64"),
|
|
56
|
+
source: "b64_json",
|
|
57
|
+
revisedPrompt: item.revised_prompt
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (typeof item.url === "string" && item.url.length > 0) {
|
|
61
|
+
return {
|
|
62
|
+
bytes: await downloadImage(item.url),
|
|
63
|
+
source: "url",
|
|
64
|
+
revisedPrompt: item.revised_prompt
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Seedream image response did not contain url or b64_json: ${raw.slice(0, 500)}`);
|
|
68
|
+
}
|
|
69
|
+
async function downloadImage(url) {
|
|
70
|
+
if (url.startsWith("file://")) {
|
|
71
|
+
return fs.readFile(new URL(url));
|
|
72
|
+
}
|
|
73
|
+
const response = await fetch(url, {
|
|
74
|
+
headers: {
|
|
75
|
+
"Accept": "image/png,image/jpeg,image/webp,image/*,*/*"
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
throw new Error(`Seedream image download HTTP ${response.status}: ${await response.text()}`);
|
|
80
|
+
}
|
|
81
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
82
|
+
if (!contentType.startsWith("image/")) {
|
|
83
|
+
throw new Error(`Seedream image download returned ${contentType || "unknown content type"}`);
|
|
84
|
+
}
|
|
85
|
+
return Buffer.from(await response.arrayBuffer());
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=seedream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seedream.js","sourceRoot":"","sources":["../../../src/providers/image/seedream.ts"],"names":[],"mappings":"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"}
|