@vibeo/cli 0.1.1 → 0.2.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/dist/commands/create.d.ts +6 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +232 -130
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/list.d.ts +9 -5
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +2 -77
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/preview.d.ts +1 -4
- package/dist/commands/preview.d.ts.map +1 -1
- package/dist/commands/preview.js +1 -57
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/render.d.ts +17 -4
- package/dist/commands/render.d.ts.map +1 -1
- package/dist/commands/render.js +22 -154
- package/dist/commands/render.js.map +1 -1
- package/dist/index.js +103 -57
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/src/commands/create.ts +228 -134
- package/src/commands/list.ts +2 -98
- package/src/commands/preview.ts +1 -66
- package/src/commands/render.ts +26 -149
- package/src/index.ts +104 -57
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare const TEMPLATE_NAMES: string[];
|
|
2
|
+
export declare function createProject(name: string, template: string): Promise<{
|
|
3
|
+
project: string;
|
|
4
|
+
template: string;
|
|
5
|
+
files: string[];
|
|
6
|
+
}>;
|
|
2
7
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AA8NA,eAAO,MAAM,cAAc,UAAyB,CAAC;AAErD,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA+DjE"}
|
package/dist/commands/create.js
CHANGED
|
@@ -1,127 +1,247 @@
|
|
|
1
1
|
import { resolve, join } from "node:path";
|
|
2
|
-
import { mkdir,
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Embedded templates
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
const TEMPLATE_BASIC = `import React from "react";
|
|
8
|
+
import {
|
|
9
|
+
Composition, Sequence, VibeoRoot,
|
|
10
|
+
useCurrentFrame, useVideoConfig, interpolate, easeInOut,
|
|
11
|
+
} from "@vibeo/core";
|
|
12
|
+
|
|
13
|
+
function TitleScene() {
|
|
14
|
+
const frame = useCurrentFrame();
|
|
15
|
+
const { width, height } = useVideoConfig();
|
|
16
|
+
const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" });
|
|
17
|
+
const y = interpolate(frame, [0, 30], [40, 0], { easing: easeInOut, extrapolateRight: "clamp" });
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div style={{ width, height, display: "flex", justifyContent: "center", alignItems: "center", background: "linear-gradient(135deg, #0f0c29, #302b63, #24243e)" }}>
|
|
21
|
+
<h1 style={{ color: "white", fontSize: 72, fontFamily: "sans-serif", opacity, transform: \`translateY(\${y}px)\` }}>Hello, Vibeo!</h1>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function ContentScene() {
|
|
27
|
+
const frame = useCurrentFrame();
|
|
28
|
+
const { width, height, fps } = useVideoConfig();
|
|
29
|
+
const seconds = (frame / fps).toFixed(1);
|
|
30
|
+
const scale = interpolate(frame, [0, 20], [0.8, 1], { easing: easeInOut, extrapolateRight: "clamp" });
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div style={{ width, height, display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", background: "#24243e" }}>
|
|
34
|
+
<div style={{ transform: \`scale(\${scale})\`, color: "white", fontSize: 48, fontFamily: "sans-serif", textAlign: "center" }}>
|
|
35
|
+
<p>Scene 2</p>
|
|
36
|
+
<p style={{ fontSize: 32, opacity: 0.7 }}>{seconds}s elapsed</p>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function MyVideo() {
|
|
43
|
+
return (
|
|
44
|
+
<>
|
|
45
|
+
<Sequence from={0} durationInFrames={75} name="Title"><TitleScene /></Sequence>
|
|
46
|
+
<Sequence from={75} durationInFrames={75} name="Content"><ContentScene /></Sequence>
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function Root() {
|
|
52
|
+
return (
|
|
53
|
+
<VibeoRoot>
|
|
54
|
+
<Composition id="BasicComposition" component={MyVideo} width={1920} height={1080} fps={30} durationInFrames={150} />
|
|
55
|
+
</VibeoRoot>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
const TEMPLATE_AUDIO_REACTIVE = `import React from "react";
|
|
60
|
+
import { Composition, VibeoRoot, useCurrentFrame, useVideoConfig, interpolate } from "@vibeo/core";
|
|
61
|
+
import { Audio } from "@vibeo/audio";
|
|
62
|
+
import { useAudioData } from "@vibeo/effects";
|
|
63
|
+
|
|
64
|
+
const AUDIO_SRC = "/music.mp3";
|
|
65
|
+
|
|
66
|
+
function FrequencyBars() {
|
|
67
|
+
const { width, height } = useVideoConfig();
|
|
68
|
+
const audio = useAudioData(AUDIO_SRC, { fftSize: 1024 });
|
|
69
|
+
if (!audio) return <div style={{ width, height }} />;
|
|
70
|
+
|
|
71
|
+
const barCount = 48;
|
|
72
|
+
const step = Math.floor(audio.frequencies.length / barCount);
|
|
73
|
+
const barWidth = (width * 0.8) / barCount;
|
|
74
|
+
const maxBarHeight = height * 0.6;
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div style={{ position: "absolute", bottom: 60, left: width * 0.1, display: "flex", alignItems: "flex-end", gap: 2 }}>
|
|
78
|
+
{Array.from({ length: barCount }, (_, i) => {
|
|
79
|
+
const db = audio.frequencies[i * step];
|
|
80
|
+
const normalized = Math.max(0, (db + 100) / 100);
|
|
81
|
+
const hue = interpolate(i, [0, barCount - 1], [220, 340]);
|
|
82
|
+
return (
|
|
83
|
+
<div key={i} style={{ width: barWidth - 2, height: Math.max(2, normalized * maxBarHeight), background: \`hsl(\${hue}, 80%, 60%)\`, borderRadius: 2 }} />
|
|
84
|
+
);
|
|
85
|
+
})}
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
43
88
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
vibeo create music-viz --template audio-reactive
|
|
63
|
-
vibeo create intro --template transitions
|
|
64
|
-
`);
|
|
89
|
+
|
|
90
|
+
function AudioViz() {
|
|
91
|
+
const frame = useCurrentFrame();
|
|
92
|
+
const { width, height, fps } = useVideoConfig();
|
|
93
|
+
const audio = useAudioData(AUDIO_SRC);
|
|
94
|
+
const hue = 240 + (audio ? audio.amplitude * 60 : 0);
|
|
95
|
+
const lightness = audio ? 8 + audio.amplitude * 12 : 8;
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div style={{ width, height, background: \`radial-gradient(ellipse at center, hsl(\${hue}, 40%, \${lightness + 5}%), hsl(\${hue}, 30%, \${lightness}%))\`, position: "relative", overflow: "hidden" }}>
|
|
99
|
+
<div style={{ position: "absolute", top: 40, left: 40, color: "white", fontFamily: "sans-serif" }}>
|
|
100
|
+
<h1 style={{ fontSize: 36, margin: 0, opacity: 0.9 }}>Audio Visualizer</h1>
|
|
101
|
+
<p style={{ fontSize: 18, margin: "8px 0 0", opacity: 0.5 }}>{(frame / fps).toFixed(1)}s</p>
|
|
102
|
+
</div>
|
|
103
|
+
<FrequencyBars />
|
|
104
|
+
<Audio src={AUDIO_SRC} volume={0.8} />
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
65
107
|
}
|
|
66
|
-
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return candidate;
|
|
74
|
-
dir = resolve(dir, "..");
|
|
75
|
-
}
|
|
76
|
-
throw new Error("Could not find examples directory");
|
|
108
|
+
|
|
109
|
+
export function Root() {
|
|
110
|
+
return (
|
|
111
|
+
<VibeoRoot>
|
|
112
|
+
<Composition id="AudioReactiveViz" component={AudioViz} width={1920} height={1080} fps={30} durationInFrames={900} />
|
|
113
|
+
</VibeoRoot>
|
|
114
|
+
);
|
|
77
115
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
116
|
+
`;
|
|
117
|
+
const TEMPLATE_TRANSITIONS = `import React from "react";
|
|
118
|
+
import { Composition, Sequence, VibeoRoot, useCurrentFrame, useVideoConfig, interpolate, easeOut } from "@vibeo/core";
|
|
119
|
+
import { Transition } from "@vibeo/effects";
|
|
120
|
+
|
|
121
|
+
function ColorScene({ title, color }: { title: string; color: string }) {
|
|
122
|
+
const frame = useCurrentFrame();
|
|
123
|
+
const { width, height } = useVideoConfig();
|
|
124
|
+
const opacity = interpolate(frame, [0, 20], [0, 1], { easing: easeOut, extrapolateRight: "clamp" });
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<div style={{ width, height, background: color, display: "flex", justifyContent: "center", alignItems: "center" }}>
|
|
128
|
+
<h1 style={{ color: "white", fontSize: 80, fontFamily: "sans-serif", opacity }}>{title}</h1>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function SceneA() { return <ColorScene title="Scene One" color="linear-gradient(135deg, #667eea, #764ba2)" />; }
|
|
134
|
+
function SceneB() { return <ColorScene title="Scene Two" color="linear-gradient(135deg, #f093fb, #f5576c)" />; }
|
|
135
|
+
function SceneC() { return <ColorScene title="Scene Three" color="linear-gradient(135deg, #4facfe, #00f2fe)" />; }
|
|
136
|
+
|
|
137
|
+
function TransitionDemo() {
|
|
138
|
+
return (
|
|
139
|
+
<>
|
|
140
|
+
<Sequence from={0} durationInFrames={85}><SceneA /></Sequence>
|
|
141
|
+
<Sequence from={65} durationInFrames={20}>
|
|
142
|
+
<Transition type="fade" durationInFrames={20}><SceneA /><SceneB /></Transition>
|
|
143
|
+
</Sequence>
|
|
144
|
+
<Sequence from={85} durationInFrames={85}><SceneB /></Sequence>
|
|
145
|
+
<Sequence from={150} durationInFrames={20}>
|
|
146
|
+
<Transition type="slide" durationInFrames={20} direction="left"><SceneB /><SceneC /></Transition>
|
|
147
|
+
</Sequence>
|
|
148
|
+
<Sequence from={170} durationInFrames={70}><SceneC /></Sequence>
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function Root() {
|
|
154
|
+
return (
|
|
155
|
+
<VibeoRoot>
|
|
156
|
+
<Composition id="TransitionDemo" component={TransitionDemo} width={1920} height={1080} fps={30} durationInFrames={240} />
|
|
157
|
+
</VibeoRoot>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
`;
|
|
161
|
+
const TEMPLATE_SUBTITLES = `import React from "react";
|
|
162
|
+
import { Composition, Sequence, VibeoRoot, useCurrentFrame, useVideoConfig, interpolate } from "@vibeo/core";
|
|
163
|
+
import { Subtitle } from "@vibeo/extras";
|
|
164
|
+
|
|
165
|
+
const SUBTITLES_SRT = \`1
|
|
166
|
+
00:00:00,500 --> 00:00:03,000
|
|
167
|
+
Welcome to the Vibeo demo.
|
|
168
|
+
|
|
169
|
+
2
|
|
170
|
+
00:00:03,500 --> 00:00:06,000
|
|
171
|
+
This shows subtitle overlays.
|
|
172
|
+
|
|
173
|
+
3
|
|
174
|
+
00:00:06,500 --> 00:00:09,000
|
|
175
|
+
Subtitles are synced to the frame timeline.
|
|
176
|
+
|
|
177
|
+
4
|
|
178
|
+
00:00:09,500 --> 00:00:12,000
|
|
179
|
+
You can use <b>bold</b> and <i>italic</i> text.
|
|
180
|
+
|
|
181
|
+
5
|
|
182
|
+
00:00:13,000 --> 00:00:16,000
|
|
183
|
+
The end. Thanks for watching!\`;
|
|
184
|
+
|
|
185
|
+
function SubtitleVideo() {
|
|
186
|
+
const frame = useCurrentFrame();
|
|
187
|
+
const { width, height } = useVideoConfig();
|
|
188
|
+
const hue = interpolate(frame, [0, 480], [200, 280]);
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<div style={{ width, height, position: "relative" }}>
|
|
192
|
+
<div style={{ width, height, background: \`linear-gradient(135deg, hsl(\${hue}, 50%, 15%), hsl(\${hue + 40}, 40%, 10%))\` }} />
|
|
193
|
+
<div style={{ position: "absolute", top: 0, left: 0, width, height }}>
|
|
194
|
+
<Subtitle src={SUBTITLES_SRT} format="srt" position="bottom" fontSize={36} color="white" outlineColor="black" outlineWidth={2} style={{ padding: "0 80px 60px" }} />
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function Root() {
|
|
201
|
+
return (
|
|
202
|
+
<VibeoRoot>
|
|
203
|
+
<Composition id="SubtitleOverlay" component={SubtitleVideo} width={1920} height={1080} fps={30} durationInFrames={480} />
|
|
204
|
+
</VibeoRoot>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
`;
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
const TEMPLATES = {
|
|
210
|
+
basic: { description: "Minimal composition with text animation and two scenes", source: TEMPLATE_BASIC },
|
|
211
|
+
"audio-reactive": { description: "Audio visualization with frequency bars", source: TEMPLATE_AUDIO_REACTIVE },
|
|
212
|
+
transitions: { description: "Scene transitions (fade, slide)", source: TEMPLATE_TRANSITIONS },
|
|
213
|
+
subtitles: { description: "Video with SRT subtitle overlay", source: TEMPLATE_SUBTITLES },
|
|
214
|
+
};
|
|
215
|
+
export const TEMPLATE_NAMES = Object.keys(TEMPLATES);
|
|
216
|
+
export async function createProject(name, template) {
|
|
217
|
+
const tmpl = TEMPLATES[template];
|
|
218
|
+
if (!tmpl)
|
|
219
|
+
throw new Error(`Unknown template: ${template}`);
|
|
220
|
+
const projectDir = resolve(name);
|
|
221
|
+
if (existsSync(projectDir))
|
|
222
|
+
throw new Error(`Directory "${name}" already exists`);
|
|
99
223
|
await mkdir(join(projectDir, "src"), { recursive: true });
|
|
100
224
|
await mkdir(join(projectDir, "public"), { recursive: true });
|
|
101
|
-
|
|
102
|
-
const examplesDir = findExamplesDir();
|
|
103
|
-
const exampleSrc = await readFile(join(examplesDir, template.example), "utf-8");
|
|
104
|
-
await writeFile(join(projectDir, "src", "index.tsx"), exampleSrc);
|
|
105
|
-
// Write package.json
|
|
225
|
+
await writeFile(join(projectDir, "src", "index.tsx"), tmpl.source);
|
|
106
226
|
const pkg = {
|
|
107
|
-
name
|
|
227
|
+
name,
|
|
108
228
|
version: "0.0.1",
|
|
109
229
|
private: true,
|
|
110
230
|
type: "module",
|
|
111
231
|
scripts: {
|
|
112
|
-
dev: "vibeo preview --entry src/index.tsx",
|
|
113
|
-
build: "vibeo render --entry src/index.tsx",
|
|
114
|
-
list: "vibeo list --entry src/index.tsx",
|
|
232
|
+
dev: "bunx @vibeo/cli preview --entry src/index.tsx",
|
|
233
|
+
build: "bunx @vibeo/cli render --entry src/index.tsx",
|
|
234
|
+
list: "bunx @vibeo/cli list --entry src/index.tsx",
|
|
115
235
|
typecheck: "bunx tsc --noEmit",
|
|
116
236
|
},
|
|
117
237
|
dependencies: {
|
|
118
|
-
"@vibeo/core": "
|
|
119
|
-
"@vibeo/audio": "
|
|
120
|
-
"@vibeo/effects": "
|
|
121
|
-
"@vibeo/extras": "
|
|
122
|
-
"@vibeo/player": "
|
|
123
|
-
"@vibeo/renderer": "
|
|
124
|
-
"@vibeo/cli": "
|
|
238
|
+
"@vibeo/core": "^0.1.0",
|
|
239
|
+
"@vibeo/audio": "^0.1.0",
|
|
240
|
+
"@vibeo/effects": "^0.1.0",
|
|
241
|
+
"@vibeo/extras": "^0.1.0",
|
|
242
|
+
"@vibeo/player": "^0.1.0",
|
|
243
|
+
"@vibeo/renderer": "^0.1.0",
|
|
244
|
+
"@vibeo/cli": "^0.1.0",
|
|
125
245
|
react: "^19.0.0",
|
|
126
246
|
"react-dom": "^19.0.0",
|
|
127
247
|
},
|
|
@@ -131,7 +251,6 @@ export async function createCommand(args) {
|
|
|
131
251
|
},
|
|
132
252
|
};
|
|
133
253
|
await writeFile(join(projectDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
134
|
-
// Write tsconfig.json
|
|
135
254
|
const tsconfig = {
|
|
136
255
|
compilerOptions: {
|
|
137
256
|
target: "ES2022",
|
|
@@ -149,25 +268,8 @@ export async function createCommand(args) {
|
|
|
149
268
|
include: ["src"],
|
|
150
269
|
};
|
|
151
270
|
await writeFile(join(projectDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n");
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
out/
|
|
156
|
-
*.tmp
|
|
157
|
-
.DS_Store
|
|
158
|
-
`);
|
|
159
|
-
console.log(` Created ${parsed.name}/`);
|
|
160
|
-
console.log(` ├── src/index.tsx`);
|
|
161
|
-
console.log(` ├── public/`);
|
|
162
|
-
console.log(` ├── package.json`);
|
|
163
|
-
console.log(` ├── tsconfig.json`);
|
|
164
|
-
console.log(` └── .gitignore`);
|
|
165
|
-
console.log(`
|
|
166
|
-
Next steps:
|
|
167
|
-
cd ${parsed.name}
|
|
168
|
-
bun install
|
|
169
|
-
bun run dev # preview in browser
|
|
170
|
-
bun run build # render to video
|
|
171
|
-
`);
|
|
271
|
+
await writeFile(join(projectDir, ".gitignore"), "node_modules/\ndist/\nout/\n*.tmp\n.DS_Store\n");
|
|
272
|
+
const files = ["src/index.tsx", "package.json", "tsconfig.json", ".gitignore", "public/"];
|
|
273
|
+
return { project: name, template, files };
|
|
172
274
|
}
|
|
173
275
|
//# sourceMappingURL=create.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/list.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
interface CompositionMeta {
|
|
2
|
+
id: string;
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
fps: number;
|
|
6
|
+
durationInFrames: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function listCompositions(entry: string): Promise<CompositionMeta[]>;
|
|
9
|
+
export {};
|
|
6
10
|
//# sourceMappingURL=list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA4BhF"}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,62 +1,13 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
1
|
import { bundle } from "@vibeo/renderer";
|
|
3
2
|
import { launchBrowser, createPage, closeBrowser } from "@vibeo/renderer";
|
|
4
|
-
function
|
|
5
|
-
const result = {
|
|
6
|
-
entry: "",
|
|
7
|
-
};
|
|
8
|
-
for (let i = 0; i < args.length; i++) {
|
|
9
|
-
const arg = args[i];
|
|
10
|
-
const next = args[i + 1];
|
|
11
|
-
if (arg === "--entry" && next) {
|
|
12
|
-
result.entry = next;
|
|
13
|
-
i++;
|
|
14
|
-
}
|
|
15
|
-
else if (arg.startsWith("--entry=")) {
|
|
16
|
-
result.entry = arg.slice("--entry=".length);
|
|
17
|
-
}
|
|
18
|
-
else if (arg === "--help" || arg === "-h") {
|
|
19
|
-
printHelp();
|
|
20
|
-
process.exit(0);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return result;
|
|
24
|
-
}
|
|
25
|
-
function printHelp() {
|
|
26
|
-
console.log(`
|
|
27
|
-
vibeo list - List registered compositions
|
|
28
|
-
|
|
29
|
-
Usage:
|
|
30
|
-
vibeo list --entry <path>
|
|
31
|
-
|
|
32
|
-
Required:
|
|
33
|
-
--entry <path> Path to the root file with compositions
|
|
34
|
-
|
|
35
|
-
Options:
|
|
36
|
-
--help Show this help
|
|
37
|
-
`);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Bundle the entry, launch a browser to evaluate it,
|
|
41
|
-
* extract registered compositions, and print a table.
|
|
42
|
-
*/
|
|
43
|
-
export async function listCommand(args) {
|
|
44
|
-
const parsed = parseArgs(args);
|
|
45
|
-
if (!parsed.entry) {
|
|
46
|
-
console.error("Error: --entry is required");
|
|
47
|
-
printHelp();
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
const entry = resolve(parsed.entry);
|
|
3
|
+
export async function listCompositions(entry) {
|
|
51
4
|
console.log(`Bundling ${entry}...`);
|
|
52
5
|
const bundleResult = await bundle(entry);
|
|
53
6
|
try {
|
|
54
7
|
const browser = await launchBrowser();
|
|
55
8
|
const page = await createPage(browser, 1920, 1080);
|
|
56
9
|
await page.goto(bundleResult.url, { waitUntil: "networkidle" });
|
|
57
|
-
// Wait briefly for React to register compositions
|
|
58
10
|
await page.waitForTimeout(2000);
|
|
59
|
-
// Extract composition data from the page
|
|
60
11
|
const compositions = await page.evaluate(() => {
|
|
61
12
|
const win = window;
|
|
62
13
|
if (typeof win.vibeo_getCompositions === "function") {
|
|
@@ -66,36 +17,10 @@ export async function listCommand(args) {
|
|
|
66
17
|
});
|
|
67
18
|
await page.close();
|
|
68
19
|
await closeBrowser();
|
|
69
|
-
|
|
70
|
-
console.log("\nNo compositions found.");
|
|
71
|
-
console.log("Make sure your entry file exports compositions via <Composition /> components.");
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
// Print table
|
|
75
|
-
console.log("\nRegistered compositions:\n");
|
|
76
|
-
console.log(padRight("ID", 25) +
|
|
77
|
-
padRight("Width", 8) +
|
|
78
|
-
padRight("Height", 8) +
|
|
79
|
-
padRight("FPS", 6) +
|
|
80
|
-
padRight("Frames", 8) +
|
|
81
|
-
"Duration");
|
|
82
|
-
console.log("-".repeat(70));
|
|
83
|
-
for (const comp of compositions) {
|
|
84
|
-
const duration = (comp.durationInFrames / comp.fps).toFixed(1) + "s";
|
|
85
|
-
console.log(padRight(comp.id, 25) +
|
|
86
|
-
padRight(String(comp.width), 8) +
|
|
87
|
-
padRight(String(comp.height), 8) +
|
|
88
|
-
padRight(String(comp.fps), 6) +
|
|
89
|
-
padRight(String(comp.durationInFrames), 8) +
|
|
90
|
-
duration);
|
|
91
|
-
}
|
|
92
|
-
console.log();
|
|
20
|
+
return compositions;
|
|
93
21
|
}
|
|
94
22
|
finally {
|
|
95
23
|
await bundleResult.cleanup();
|
|
96
24
|
}
|
|
97
25
|
}
|
|
98
|
-
function padRight(str, len) {
|
|
99
|
-
return str.length >= len ? str : str + " ".repeat(len - str.length);
|
|
100
|
-
}
|
|
101
26
|
//# sourceMappingURL=list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAU1E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAa;IAClD,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC;IACpC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAEnD,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAEhC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;YAC5C,MAAM,GAAG,GAAG,MAEX,CAAC;YACF,IAAI,OAAO,GAAG,CAAC,qBAAqB,KAAK,UAAU,EAAE,CAAC;gBACpD,OAAO,GAAG,CAAC,qBAAqB,EAAE,CAAC;YACrC,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,YAAY,EAAE,CAAC;QAErB,OAAO,YAAY,CAAC;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"AAEA,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9E"}
|