reelforge 0.4.0 → 0.4.1
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 +0 -4
- package/dist/commands/create.js +1 -3
- package/dist/commands/pipelines.js +1 -78
- package/dist/commands/videos.js +2 -2
- package/dist/commands/workflows.js +1 -1
- package/package.json +52 -52
package/README.md
CHANGED
|
@@ -111,10 +111,6 @@ All `pipelines *` commands submit an **async task** and (by default) poll until
|
|
|
111
111
|
| command | what it does |
|
|
112
112
|
|---|---|
|
|
113
113
|
| `pipelines standard -t <topic\|script>` | Topic / script → narration → frames → final MP4 |
|
|
114
|
-
| `pipelines asset-based --intent ... --assets <file>` | User assets → AI-arranged scene video |
|
|
115
|
-
| `pipelines digital-human -w <wf> -i <portrait> -t <text>` | Digital human speaker |
|
|
116
|
-
| `pipelines i2v -w <wf> -i <image>` | Image-to-video |
|
|
117
|
-
| `pipelines action-transfer -w <wf> --reference-video <v> --character-image <img>` | Action transfer |
|
|
118
114
|
|
|
119
115
|
### Resources
|
|
120
116
|
|
package/dist/commands/create.js
CHANGED
|
@@ -15,12 +15,10 @@ function calcWorkflowUnits(wfKey) {
|
|
|
15
15
|
return 1;
|
|
16
16
|
if (base.startsWith("image_"))
|
|
17
17
|
return 3;
|
|
18
|
-
if (base.startsWith("video_")
|
|
18
|
+
if (base.startsWith("video_"))
|
|
19
19
|
return 15;
|
|
20
20
|
if (base.startsWith("analyse_") || base.startsWith("analyze_"))
|
|
21
21
|
return 2;
|
|
22
|
-
if (base.startsWith("af_") || base.startsWith("digital_"))
|
|
23
|
-
return 15;
|
|
24
22
|
return 3;
|
|
25
23
|
}
|
|
26
24
|
function estimateUnits(body) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
2
|
import { post } from "../client.js";
|
|
4
3
|
import { waitForTask } from "../utils/task-waiter.js";
|
|
5
4
|
import { downloadTo } from "../utils/download.js";
|
|
@@ -35,7 +34,7 @@ export function registerPipelines(program) {
|
|
|
35
34
|
const pl = program
|
|
36
35
|
.command("pipelines")
|
|
37
36
|
.alias("pipeline")
|
|
38
|
-
.description("End-to-end video pipelines (standard
|
|
37
|
+
.description("End-to-end video pipelines (standard)")
|
|
39
38
|
.helpOption("-h, --help", "show help");
|
|
40
39
|
// ---------- standard ----------
|
|
41
40
|
commonOptions(pl
|
|
@@ -79,80 +78,4 @@ export function registerPipelines(program) {
|
|
|
79
78
|
bgm_volume: opts.bgmVolume,
|
|
80
79
|
}, { wait: opts.wait, output: opts.output, pollMs: opts.pollMs, timeoutMs: opts.timeoutMs });
|
|
81
80
|
});
|
|
82
|
-
// ---------- asset-based ----------
|
|
83
|
-
commonOptions(pl
|
|
84
|
-
.command("asset-based")
|
|
85
|
-
.description("User-uploaded assets + intent → AI-arranged scene video")
|
|
86
|
-
.helpOption("-h, --help", "show help")
|
|
87
|
-
.requiredOption("--intent <text>", "video purpose / intent")
|
|
88
|
-
.requiredOption("--assets <file>", "file with one asset path per line")
|
|
89
|
-
.option("--title <text>", "video title")
|
|
90
|
-
.option("--duration <s>", "target duration", parseInt, 30)
|
|
91
|
-
.option("--source <src>", "analysis backend: runninghub | selfhost", "runninghub")
|
|
92
|
-
.option("--voice <id>", "Edge TTS voice", "zh-CN-YunjianNeural")).action(async (opts) => {
|
|
93
|
-
const assetsText = await fs.readFile(opts.assets, "utf-8");
|
|
94
|
-
const assets = assetsText.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
95
|
-
await submitAndMaybeWait("/api/v1/pipelines/asset-based", {
|
|
96
|
-
intent: opts.intent,
|
|
97
|
-
video_title: opts.title,
|
|
98
|
-
duration: opts.duration,
|
|
99
|
-
source: opts.source,
|
|
100
|
-
voice_id: opts.voice,
|
|
101
|
-
assets: assets.map((a) => path.resolve(a)),
|
|
102
|
-
}, { wait: opts.wait, output: opts.output, pollMs: opts.pollMs, timeoutMs: opts.timeoutMs });
|
|
103
|
-
});
|
|
104
|
-
// ---------- digital-human ----------
|
|
105
|
-
commonOptions(pl
|
|
106
|
-
.command("digital-human")
|
|
107
|
-
.description("Portrait image + (text or audio) → digital-human speaker video")
|
|
108
|
-
.helpOption("-h, --help", "show help")
|
|
109
|
-
.requiredOption("-w, --workflow <key>", "workflow, e.g. runninghub/digital_image.json")
|
|
110
|
-
.requiredOption("-i, --image <file>", "portrait image path/URL")
|
|
111
|
-
.option("-t, --text <text>", "speech text (TTS will run if --audio absent)")
|
|
112
|
-
.option("--audio <file>", "pre-existing audio file (skip TTS)")
|
|
113
|
-
.option("--voice <id>", "Edge TTS voice", "zh-CN-YunjianNeural")
|
|
114
|
-
.option("--speed <n>", "TTS speed", parseFloat, 1.0)).action(async (opts) => {
|
|
115
|
-
if (!opts.text && !opts.audio)
|
|
116
|
-
throw new Error("Either --text or --audio is required");
|
|
117
|
-
await submitAndMaybeWait("/api/v1/pipelines/digital-human", {
|
|
118
|
-
workflow: opts.workflow,
|
|
119
|
-
image: opts.image,
|
|
120
|
-
text: opts.text,
|
|
121
|
-
audio: opts.audio,
|
|
122
|
-
voice: opts.voice,
|
|
123
|
-
speed: opts.speed,
|
|
124
|
-
}, { wait: opts.wait, output: opts.output, pollMs: opts.pollMs, timeoutMs: opts.timeoutMs });
|
|
125
|
-
});
|
|
126
|
-
// ---------- i2v ----------
|
|
127
|
-
commonOptions(pl
|
|
128
|
-
.command("i2v")
|
|
129
|
-
.description("Static image → AI-generated dynamic video (image-to-video)")
|
|
130
|
-
.helpOption("-h, --help", "show help")
|
|
131
|
-
.requiredOption("-w, --workflow <key>", "workflow, e.g. runninghub/i2v_LTX2.json")
|
|
132
|
-
.requiredOption("-i, --image <file>", "image path/URL")
|
|
133
|
-
.option("-p, --prompt <text>", "motion description prompt")
|
|
134
|
-
.option("--duration <s>", "target duration", parseInt, 4)).action(async (opts) => {
|
|
135
|
-
await submitAndMaybeWait("/api/v1/pipelines/i2v", {
|
|
136
|
-
workflow: opts.workflow,
|
|
137
|
-
image: opts.image,
|
|
138
|
-
prompt: opts.prompt,
|
|
139
|
-
duration: opts.duration,
|
|
140
|
-
}, { wait: opts.wait, output: opts.output, pollMs: opts.pollMs, timeoutMs: opts.timeoutMs });
|
|
141
|
-
});
|
|
142
|
-
// ---------- action-transfer ----------
|
|
143
|
-
commonOptions(pl
|
|
144
|
-
.command("action-transfer")
|
|
145
|
-
.description("Reference action video + character image → action-mimicking video")
|
|
146
|
-
.helpOption("-h, --help", "show help")
|
|
147
|
-
.requiredOption("-w, --workflow <key>", "workflow, e.g. runninghub/af_scail.json")
|
|
148
|
-
.requiredOption("--reference-video <file>", "reference action video")
|
|
149
|
-
.requiredOption("--character-image <file>", "character image")
|
|
150
|
-
.option("-p, --prompt <text>", "extra prompt")).action(async (opts) => {
|
|
151
|
-
await submitAndMaybeWait("/api/v1/pipelines/action-transfer", {
|
|
152
|
-
workflow: opts.workflow,
|
|
153
|
-
reference_video: opts.referenceVideo,
|
|
154
|
-
character_image: opts.characterImage,
|
|
155
|
-
prompt: opts.prompt,
|
|
156
|
-
}, { wait: opts.wait, output: opts.output, pollMs: opts.pollMs, timeoutMs: opts.timeoutMs });
|
|
157
|
-
});
|
|
158
81
|
}
|
package/dist/commands/videos.js
CHANGED
|
@@ -8,14 +8,14 @@ export function registerVideos(program) {
|
|
|
8
8
|
.helpOption("-h, --help", "show help");
|
|
9
9
|
videos
|
|
10
10
|
.command("generate")
|
|
11
|
-
.description("Generate a video via a video_*
|
|
11
|
+
.description("Generate a video via a video_* workflow")
|
|
12
12
|
.helpOption("-h, --help", "show help")
|
|
13
13
|
.requiredOption("-p, --prompt <text>", "text prompt")
|
|
14
14
|
.requiredOption("-w, --workflow <key>", "workflow key, e.g. runninghub/video_wan2.2.json")
|
|
15
15
|
.option("--width <n>", "video width", parseInt)
|
|
16
16
|
.option("--height <n>", "video height", parseInt)
|
|
17
17
|
.option("--duration <s>", "target duration in seconds", parseFloat)
|
|
18
|
-
.option("--image <pathOrUrl>", "reference image (
|
|
18
|
+
.option("--image <pathOrUrl>", "reference image (when the workflow accepts one)")
|
|
19
19
|
.option("-o, --output <file>", "download first video to this local path")
|
|
20
20
|
.addHelpText("after", [
|
|
21
21
|
"",
|
|
@@ -11,7 +11,7 @@ export function registerWorkflows(program) {
|
|
|
11
11
|
.description("List all available workflows")
|
|
12
12
|
.helpOption("-h, --help", "show help")
|
|
13
13
|
.option("--source <src>", "filter by source: selfhost | runninghub")
|
|
14
|
-
.option("--kind <kind>", "filter by kind: image | video | tts | analyse
|
|
14
|
+
.option("--kind <kind>", "filter by kind: image | video | tts | analyse")
|
|
15
15
|
.action(async (opts) => {
|
|
16
16
|
const qs = new URLSearchParams();
|
|
17
17
|
if (opts.source)
|
package/package.json
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "reelforge",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "CLI for ReelForge Studio — AI video engine. Installs as both `reelforge` and the short alias `rf`. Every REST API exposed as a command, with --help on every level.",
|
|
5
|
-
"license": "Apache-2.0",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"reelforge": "./bin/reelforge.js",
|
|
9
|
-
"rf": "./bin/reelforge.js"
|
|
10
|
-
},
|
|
11
|
-
"files": [
|
|
12
|
-
"bin",
|
|
13
|
-
"dist",
|
|
14
|
-
"README.md"
|
|
15
|
-
],
|
|
16
|
-
"engines": {
|
|
17
|
-
"node": ">=18.17"
|
|
18
|
-
},
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsc -p tsconfig.json",
|
|
21
|
-
"dev": "tsc -p tsconfig.json --watch",
|
|
22
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
23
|
-
"clean": "rimraf dist",
|
|
24
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
25
|
-
},
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"commander": "^12.1.0",
|
|
28
|
-
"kleur": "^4.1.5"
|
|
29
|
-
},
|
|
30
|
-
"devDependencies": {
|
|
31
|
-
"@types/node": "^20.14.0",
|
|
32
|
-
"rimraf": "^6.0.1",
|
|
33
|
-
"typescript": "^5.5.0"
|
|
34
|
-
},
|
|
35
|
-
"keywords": [
|
|
36
|
-
"reelforge",
|
|
37
|
-
"ai-video",
|
|
38
|
-
"comfyui",
|
|
39
|
-
"runninghub",
|
|
40
|
-
"tts",
|
|
41
|
-
"edge-tts",
|
|
42
|
-
"ffmpeg",
|
|
43
|
-
"playwright",
|
|
44
|
-
"cli"
|
|
45
|
-
],
|
|
46
|
-
"repository": {
|
|
47
|
-
"type": "git",
|
|
48
|
-
"url": "https://github.com/puke3615/ReelForge.git",
|
|
49
|
-
"directory": "cli"
|
|
50
|
-
},
|
|
51
|
-
"homepage": "https://github.com/puke3615/ReelForge"
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "reelforge",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "CLI for ReelForge Studio — AI video engine. Installs as both `reelforge` and the short alias `rf`. Every REST API exposed as a command, with --help on every level.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"reelforge": "./bin/reelforge.js",
|
|
9
|
+
"rf": "./bin/reelforge.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.17"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json",
|
|
21
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
22
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
23
|
+
"clean": "rimraf dist",
|
|
24
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"commander": "^12.1.0",
|
|
28
|
+
"kleur": "^4.1.5"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.14.0",
|
|
32
|
+
"rimraf": "^6.0.1",
|
|
33
|
+
"typescript": "^5.5.0"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"reelforge",
|
|
37
|
+
"ai-video",
|
|
38
|
+
"comfyui",
|
|
39
|
+
"runninghub",
|
|
40
|
+
"tts",
|
|
41
|
+
"edge-tts",
|
|
42
|
+
"ffmpeg",
|
|
43
|
+
"playwright",
|
|
44
|
+
"cli"
|
|
45
|
+
],
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/puke3615/ReelForge.git",
|
|
49
|
+
"directory": "cli"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/puke3615/ReelForge"
|
|
52
|
+
}
|