reelme 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/assets/audio/PROVENANCE.md +18 -11
- package/assets/audio/generate-sfx.mjs +128 -0
- package/assets/audio/light-steps.mp3 +0 -0
- package/assets/audio/lofi-dusk.mp3 +0 -0
- package/assets/audio/manifest.json +56 -63
- package/assets/audio/neon-pulse.mp3 +0 -0
- package/assets/audio/night-drive.mp3 +0 -0
- package/assets/audio/sfx/SOURCES.md +16 -0
- package/assets/audio/sfx/pop.mp3 +0 -0
- package/assets/audio/sfx/rise.mp3 +0 -0
- package/assets/audio/sfx/whoosh.mp3 +0 -0
- package/assets/audio/sunny-bounce.mp3 +0 -0
- package/assets/audio/warm-memories.mp3 +0 -0
- package/package.json +8 -2
- package/src/cache.mjs +246 -16
- package/src/cli.mjs +20 -11
- package/src/render.mjs +98 -19
- package/template/package.json +6 -6
- package/template/pnpm-lock.yaml +177 -122
- package/template/pnpm-workspace.yaml +2 -0
- package/template/src/Root.tsx +101 -21
- package/template/src/brief.json +6 -6
- package/template/src/brief.ts +39 -6
- package/template/src/cinematic/Atmosphere.tsx +176 -30
- package/template/src/cinematic/Camera.tsx +22 -10
- package/template/src/cinematic/look.ts +51 -10
- package/template/src/cinematic/transitions.tsx +29 -9
- package/template/src/components/primitives/Arrow.tsx +8 -5
- package/template/src/components/primitives/Bar.tsx +6 -2
- package/template/src/components/primitives/Caption.tsx +2 -2
- package/template/src/components/primitives/CodeBlock.tsx +21 -7
- package/template/src/components/primitives/Icon.tsx +7 -0
- package/template/src/components/primitives/KeyPill.tsx +1 -1
- package/template/src/components/primitives/Label.tsx +4 -1
- package/template/src/components/primitives/Loop.tsx +65 -0
- package/template/src/components/primitives/RevealText.tsx +35 -7
- package/template/src/components/primitives/Stage.tsx +62 -0
- package/template/src/components/primitives/Terminal.tsx +24 -7
- package/template/src/components/scenes/BrowserFrame.tsx +13 -6
- package/template/src/components/scenes/CTA.tsx +47 -82
- package/template/src/components/scenes/Clip.tsx +31 -12
- package/template/src/components/scenes/CodeReveal.tsx +12 -13
- package/template/src/components/scenes/DataFlow.tsx +47 -19
- package/template/src/components/scenes/FeatureList.tsx +74 -77
- package/template/src/components/scenes/FileTree.tsx +23 -7
- package/template/src/components/scenes/Hook.tsx +4 -3
- package/template/src/components/scenes/HotkeyScene.tsx +4 -3
- package/template/src/components/scenes/MobileScreen.tsx +225 -118
- package/template/src/components/scenes/OSWindowScene.tsx +5 -5
- package/template/src/components/scenes/Problem.tsx +1 -1
- package/template/src/components/scenes/SplitComparison.tsx +41 -14
- package/template/src/components/scenes/StatCallout.tsx +123 -68
- package/template/src/components/scenes/TerminalScene.tsx +12 -11
- package/template/src/custom-scenes.ts +19 -0
- package/template/src/duration.ts +54 -5
- package/template/src/index.ts +16 -10
- package/template/src/theme.ts +10 -1
- package/template/src/timing.ts +49 -0
- package/assets/audio/bright-sparks.mp3 +0 -0
- package/assets/audio/calm-keys.mp3 +0 -0
- package/assets/audio/circuit-pulse.mp3 +0 -0
- package/assets/audio/clean-horizon.mp3 +0 -0
- package/assets/audio/generate-tracks.mjs +0 -213
- package/assets/audio/midnight-protocol.mp3 +0 -0
- package/assets/audio/pixel-bounce.mp3 +0 -0
- package/assets/audio/steady-launch.mp3 +0 -0
- package/assets/audio/sunny-loop.mp3 +0 -0
- package/assets/audio/vector-grid.mp3 +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# reelme
|
|
2
2
|
|
|
3
|
-
Turn your repo into launch videos for social platforms — rendered
|
|
3
|
+
Turn your repo into launch videos for social platforms — rendered on your machine with [Remotion](https://www.remotion.dev). No accounts, no API keys, nothing uploaded.
|
|
4
4
|
|
|
5
5
|
`reelme` is the rendering engine behind the [reelme agent skill](https://github.com/RubenGlez/reelme). The skill does the thinking (it reads your repo, interviews you, and writes a `reelme.json` brief at your repo root); this CLI does the work: it scaffolds a Remotion project in a global cache and renders one video variant per publishing platform.
|
|
6
6
|
|
|
@@ -24,12 +24,13 @@ npx skills add RubenGlez/reelme
|
|
|
24
24
|
|---|---|
|
|
25
25
|
| `npx reelme render` | Renders every platform selected in `reelme.json` to `./reelme-out/` |
|
|
26
26
|
| `npx reelme studio` | Opens Remotion Studio against the cached project, for previewing and tweaking |
|
|
27
|
-
| `npx reelme
|
|
27
|
+
| `npx reelme validate` | Checks `reelme.json` (schema, platforms, scene types and fields) without rendering |
|
|
28
|
+
| `npx reelme clean` | Removes this project's cache (add `--all` to wipe every project's cache in `~/.reelme/cache`) |
|
|
28
29
|
|
|
29
30
|
## How it works
|
|
30
31
|
|
|
31
32
|
- Your repo keeps only two things: `reelme.json` (the brief — commit it, it's your video's source of truth across releases) and `reelme-out/` (rendered videos; add it to `.gitignore`).
|
|
32
|
-
- The heavy Remotion project lives in `~/.reelme/cache/<project-hash>/`, scaffolded on first render and reused afterwards. Re-renders don't reinstall anything; upgrading the CLI rebuilds the scaffold automatically.
|
|
33
|
+
- The heavy Remotion project lives in `~/.reelme/cache/<project-hash>/`, scaffolded on first render and reused afterwards. Re-renders don't reinstall anything; upgrading the CLI (or changing the template's dependencies) rebuilds the scaffold automatically.
|
|
33
34
|
- Each platform you select (X, LinkedIn, YouTube, TikTok, Instagram Reel/Story/Feed, GitHub README) maps to a preset that resolves dimensions, duration ceilings, and safe areas internally — you never deal with aspect ratios. GitHub README outputs a GIF; everything else is MP4. Briefs with a `teaser` cut also get a short `<platform>-teaser.mp4` per social platform.
|
|
34
35
|
|
|
35
36
|
## Requirements
|
|
@@ -37,6 +38,12 @@ npx skills add RubenGlez/reelme
|
|
|
37
38
|
- Node.js >= 18
|
|
38
39
|
- [pnpm](https://pnpm.io) (used to install render dependencies inside the cache)
|
|
39
40
|
|
|
41
|
+
The first render needs network access: it installs the Remotion project into the
|
|
42
|
+
cache (npm registry), downloads a headless Chrome build (hundreds of MB, once),
|
|
43
|
+
and fetches the on-screen fonts from Google Fonts. After the first successful
|
|
44
|
+
render most of this is cached, but font loading still runs per render — nothing
|
|
45
|
+
you author is ever uploaded.
|
|
46
|
+
|
|
40
47
|
## License
|
|
41
48
|
|
|
42
49
|
MIT
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
# ReelMe Bundled Audio Provenance
|
|
2
2
|
|
|
3
|
-
The bundled
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The bundled music beds in this directory are curated **CC0 (public domain)**
|
|
4
|
+
loops from [Freesound](https://freesound.org). Each `manifest.json` entry lists
|
|
5
|
+
the uploader (`artist`) and the sound's Freesound page (`source`); CC0 requires
|
|
6
|
+
no attribution, but the credits are kept as a courtesy. The files were loudness-
|
|
7
|
+
normalized (`loudnorm I=-16:TP=-1.5`) to sit under the mix and re-encoded as MP3;
|
|
8
|
+
they are otherwise unedited.
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
| file | Freesound | uploader |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `lofi-dusk.mp3` | https://freesound.org/s/852231/ | holizna |
|
|
13
|
+
| `warm-memories.mp3` | https://freesound.org/s/826622/ | xkeril |
|
|
14
|
+
| `neon-pulse.mp3` | https://freesound.org/s/415922/ | newagesoup |
|
|
15
|
+
| `night-drive.mp3` | https://freesound.org/s/211555/ | waveplaySFX |
|
|
16
|
+
| `sunny-bounce.mp3` | https://freesound.org/s/512340/ | mistermender |
|
|
17
|
+
| `light-steps.mp3` | https://freesound.org/s/410520/ | Jamessi |
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
**Beat sync.** Each bed is an exact whole-beat loop at the `bpm` recorded in
|
|
20
|
+
`manifest.json`, so the CLI can quantize scene cuts to the beat and the loop
|
|
21
|
+
stays locked when Remotion repeats it (`sunny-bounce` is within ~0.1 beat).
|
|
14
22
|
|
|
15
|
-
Each
|
|
16
|
-
size.
|
|
23
|
+
Each file is kept below 2 MB for package size.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Procedural SFX generator — FALLBACK ONLY. The shipped cues in sfx/ are
|
|
2
|
+
// curated ElevenLabs sound effects (see sfx/SOURCES.md); this script exists so
|
|
3
|
+
// the cues can be regenerated from nothing if those files are ever removed.
|
|
4
|
+
// It REFUSES to overwrite existing files unless run with --force.
|
|
5
|
+
//
|
|
6
|
+
// whoosh.mp3 — air sweep for fast lateral cuts (whip/wipe/flip)
|
|
7
|
+
// pop.mp3 — soft low knock for settle cuts (zoom/punch/rise/fade)
|
|
8
|
+
// rise.mp3 — swell into the end card (CTA), peak at 0.6s
|
|
9
|
+
//
|
|
10
|
+
// node cli/assets/audio/generate-sfx.mjs --force (requires ffmpeg on PATH)
|
|
11
|
+
import { writeFileSync, rmSync, existsSync } from "node:fs";
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { dirname, join } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
const SAMPLE_RATE = 44100;
|
|
17
|
+
const TWO_PI = Math.PI * 2;
|
|
18
|
+
|
|
19
|
+
// Deterministic noise so regeneration is reproducible.
|
|
20
|
+
function makeNoise() {
|
|
21
|
+
let seed = 0x9e3779b9;
|
|
22
|
+
return () => {
|
|
23
|
+
seed ^= seed << 13;
|
|
24
|
+
seed ^= seed >>> 17;
|
|
25
|
+
seed ^= seed << 5;
|
|
26
|
+
seed >>>= 0;
|
|
27
|
+
return (seed / 0xffffffff) * 2 - 1;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// One-pole band-ish filter state per render call.
|
|
32
|
+
function renderWhoosh(t, dur, noise, state) {
|
|
33
|
+
// Noise through a swept low-pass: dark → bright → gone. Reads as air, not tape hiss.
|
|
34
|
+
const p = t / dur;
|
|
35
|
+
const cutoff = 400 + 5200 * Math.sin(Math.PI * p) ** 2;
|
|
36
|
+
const alpha = Math.min(1, cutoff / (SAMPLE_RATE / 2 / Math.PI));
|
|
37
|
+
state.lp += alpha * (noise() - state.lp);
|
|
38
|
+
const body = state.lp - state.lp2;
|
|
39
|
+
state.lp2 += 0.02 * (state.lp - state.lp2); // high-pass against rumble
|
|
40
|
+
const envelope = Math.sin(Math.PI * p) ** 1.6;
|
|
41
|
+
return body * envelope * 2.2;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function renderPop(t, dur) {
|
|
45
|
+
// A soft knock: quickly decaying low sine with a faint click transient.
|
|
46
|
+
const knock = Math.sin(TWO_PI * 130 * t * (1 - t * 1.6)) * Math.exp(-t * 42);
|
|
47
|
+
const click = Math.sin(TWO_PI * 1900 * t) * Math.exp(-t * 300) * 0.25;
|
|
48
|
+
return (knock + click) * 0.9;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function renderRise(t, dur, noise, state) {
|
|
52
|
+
// Swell: filtered noise + a fifth dyad crescendo that stops just before the
|
|
53
|
+
// peak — the visual landing supplies the actual accent.
|
|
54
|
+
const p = t / dur;
|
|
55
|
+
const cutoff = 250 + 2600 * p * p;
|
|
56
|
+
const alpha = Math.min(1, cutoff / (SAMPLE_RATE / 2 / Math.PI));
|
|
57
|
+
state.lp += alpha * (noise() - state.lp);
|
|
58
|
+
const air = state.lp * 0.7;
|
|
59
|
+
const dyad = (Math.sin(TWO_PI * 220 * t) + Math.sin(TWO_PI * 330 * t) * 0.6) * 0.18;
|
|
60
|
+
const envelope = p * p * (p < 0.92 ? 1 : (1 - p) / 0.08);
|
|
61
|
+
return (air + dyad) * envelope * 1.4;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const SFX = [
|
|
65
|
+
{ file: "whoosh.mp3", dur: 0.42, render: renderWhoosh },
|
|
66
|
+
{ file: "pop.mp3", dur: 0.18, render: renderPop },
|
|
67
|
+
{ file: "rise.mp3", dur: 0.85, render: renderRise },
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
function writeWav(path, sfx) {
|
|
71
|
+
const frames = Math.round(SAMPLE_RATE * sfx.dur);
|
|
72
|
+
const dataSize = frames * 2;
|
|
73
|
+
const buffer = Buffer.alloc(44 + dataSize);
|
|
74
|
+
buffer.write("RIFF", 0);
|
|
75
|
+
buffer.writeUInt32LE(36 + dataSize, 4);
|
|
76
|
+
buffer.write("WAVE", 8);
|
|
77
|
+
buffer.write("fmt ", 12);
|
|
78
|
+
buffer.writeUInt32LE(16, 16);
|
|
79
|
+
buffer.writeUInt16LE(1, 20);
|
|
80
|
+
buffer.writeUInt16LE(1, 22);
|
|
81
|
+
buffer.writeUInt32LE(SAMPLE_RATE, 24);
|
|
82
|
+
buffer.writeUInt32LE(SAMPLE_RATE * 2, 28);
|
|
83
|
+
buffer.writeUInt16LE(2, 32);
|
|
84
|
+
buffer.writeUInt16LE(16, 34);
|
|
85
|
+
buffer.write("data", 36);
|
|
86
|
+
buffer.writeUInt32LE(dataSize, 40);
|
|
87
|
+
|
|
88
|
+
const noise = makeNoise();
|
|
89
|
+
const state = { lp: 0, lp2: 0 };
|
|
90
|
+
for (let i = 0; i < frames; i += 1) {
|
|
91
|
+
const t = i / SAMPLE_RATE;
|
|
92
|
+
const s = Math.max(-0.98, Math.min(0.98, sfx.render(t, sfx.dur, noise, state)));
|
|
93
|
+
buffer.writeInt16LE(Math.round(s * 32767), 44 + i * 2);
|
|
94
|
+
}
|
|
95
|
+
writeFileSync(path, buffer);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const outDir = join(dirname(fileURLToPath(import.meta.url)), "sfx");
|
|
99
|
+
spawnSync("mkdir", ["-p", outDir]);
|
|
100
|
+
|
|
101
|
+
const force = process.argv.includes("--force");
|
|
102
|
+
const existing = SFX.filter((s) => existsSync(join(outDir, s.file)));
|
|
103
|
+
if (existing.length > 0 && !force) {
|
|
104
|
+
console.error(
|
|
105
|
+
`refusing to overwrite curated SFX (${existing.map((s) => s.file).join(", ")}). ` +
|
|
106
|
+
`These are hand-picked ElevenLabs cues (sfx/SOURCES.md); rerun with --force to replace them with the procedural fallback.`
|
|
107
|
+
);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const sfx of SFX) {
|
|
112
|
+
const wavPath = join(outDir, sfx.file.replace(".mp3", ".wav"));
|
|
113
|
+
const mp3Path = join(outDir, sfx.file);
|
|
114
|
+
writeWav(wavPath, sfx);
|
|
115
|
+
const result = spawnSync(
|
|
116
|
+
"ffmpeg",
|
|
117
|
+
["-y", "-hide_banner", "-loglevel", "error", "-i", wavPath, "-af", "loudnorm=I=-23:TP=-2", "-codec:a", "libmp3lame", "-b:a", "96k", mp3Path],
|
|
118
|
+
{ stdio: "inherit" }
|
|
119
|
+
);
|
|
120
|
+
if (result.error || result.status !== 0) {
|
|
121
|
+
rmSync(wavPath, { force: true });
|
|
122
|
+
rmSync(mp3Path, { force: true });
|
|
123
|
+
process.exitCode = result.status || 1;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
rmSync(wavPath, { force: true });
|
|
127
|
+
console.log(`wrote ${mp3Path}`);
|
|
128
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -1,83 +1,76 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
|
-
"file": "
|
|
4
|
-
"title": "
|
|
5
|
-
"artist": "
|
|
6
|
-
"source": "https://
|
|
3
|
+
"file": "lofi-dusk.mp3",
|
|
4
|
+
"title": "Lofi Dusk",
|
|
5
|
+
"artist": "holizna",
|
|
6
|
+
"source": "https://freesound.org/s/852231/",
|
|
7
7
|
"license": "CC0",
|
|
8
|
-
"tones": [
|
|
9
|
-
|
|
8
|
+
"tones": [
|
|
9
|
+
"professional"
|
|
10
|
+
],
|
|
11
|
+
"duration": 35,
|
|
12
|
+
"bpm": 82
|
|
10
13
|
},
|
|
11
14
|
{
|
|
12
|
-
"file": "
|
|
13
|
-
"title": "
|
|
14
|
-
"artist": "
|
|
15
|
-
"source": "https://
|
|
15
|
+
"file": "warm-memories.mp3",
|
|
16
|
+
"title": "Warm Memories",
|
|
17
|
+
"artist": "xkeril",
|
|
18
|
+
"source": "https://freesound.org/s/826622/",
|
|
16
19
|
"license": "CC0",
|
|
17
|
-
"tones": [
|
|
18
|
-
|
|
20
|
+
"tones": [
|
|
21
|
+
"professional"
|
|
22
|
+
],
|
|
23
|
+
"duration": 20,
|
|
24
|
+
"bpm": 108
|
|
19
25
|
},
|
|
20
26
|
{
|
|
21
|
-
"file": "
|
|
22
|
-
"title": "
|
|
23
|
-
"artist": "
|
|
24
|
-
"source": "https://
|
|
27
|
+
"file": "neon-pulse.mp3",
|
|
28
|
+
"title": "Neon Pulse",
|
|
29
|
+
"artist": "newagesoup",
|
|
30
|
+
"source": "https://freesound.org/s/415922/",
|
|
25
31
|
"license": "CC0",
|
|
26
|
-
"tones": [
|
|
27
|
-
|
|
32
|
+
"tones": [
|
|
33
|
+
"technical",
|
|
34
|
+
"playful"
|
|
35
|
+
],
|
|
36
|
+
"duration": 17,
|
|
37
|
+
"bpm": 112
|
|
28
38
|
},
|
|
29
39
|
{
|
|
30
|
-
"file": "
|
|
31
|
-
"title": "
|
|
32
|
-
"artist": "
|
|
33
|
-
"source": "https://
|
|
40
|
+
"file": "night-drive.mp3",
|
|
41
|
+
"title": "Night Drive",
|
|
42
|
+
"artist": "waveplaySFX",
|
|
43
|
+
"source": "https://freesound.org/s/211555/",
|
|
34
44
|
"license": "CC0",
|
|
35
|
-
"tones": [
|
|
36
|
-
|
|
45
|
+
"tones": [
|
|
46
|
+
"technical"
|
|
47
|
+
],
|
|
48
|
+
"duration": 30,
|
|
49
|
+
"bpm": 128
|
|
37
50
|
},
|
|
38
51
|
{
|
|
39
|
-
"file": "
|
|
40
|
-
"title": "
|
|
41
|
-
"artist": "
|
|
42
|
-
"source": "https://
|
|
52
|
+
"file": "sunny-bounce.mp3",
|
|
53
|
+
"title": "Sunny Bounce",
|
|
54
|
+
"artist": "mistermender",
|
|
55
|
+
"source": "https://freesound.org/s/512340/",
|
|
43
56
|
"license": "CC0",
|
|
44
|
-
"tones": [
|
|
45
|
-
|
|
57
|
+
"tones": [
|
|
58
|
+
"playful"
|
|
59
|
+
],
|
|
60
|
+
"duration": 58,
|
|
61
|
+
"bpm": 126
|
|
46
62
|
},
|
|
47
63
|
{
|
|
48
|
-
"file": "
|
|
49
|
-
"title": "
|
|
50
|
-
"artist": "
|
|
51
|
-
"source": "https://
|
|
64
|
+
"file": "light-steps.mp3",
|
|
65
|
+
"title": "Light Steps",
|
|
66
|
+
"artist": "Jamessi",
|
|
67
|
+
"source": "https://freesound.org/s/410520/",
|
|
52
68
|
"license": "CC0",
|
|
53
|
-
"tones": [
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"artist": "ReelMe procedural audio generator",
|
|
60
|
-
"source": "https://github.com/RubenGlez/reelme/blob/main/cli/assets/audio/generate-tracks.mjs#circuit-pulse",
|
|
61
|
-
"license": "CC0",
|
|
62
|
-
"tones": ["technical"],
|
|
63
|
-
"duration": 32
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"file": "vector-grid.mp3",
|
|
67
|
-
"title": "Vector Grid",
|
|
68
|
-
"artist": "ReelMe procedural audio generator",
|
|
69
|
-
"source": "https://github.com/RubenGlez/reelme/blob/main/cli/assets/audio/generate-tracks.mjs#vector-grid",
|
|
70
|
-
"license": "CC0",
|
|
71
|
-
"tones": ["technical"],
|
|
72
|
-
"duration": 32
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"file": "midnight-protocol.mp3",
|
|
76
|
-
"title": "Midnight Protocol",
|
|
77
|
-
"artist": "ReelMe procedural audio generator",
|
|
78
|
-
"source": "https://github.com/RubenGlez/reelme/blob/main/cli/assets/audio/generate-tracks.mjs#midnight-protocol",
|
|
79
|
-
"license": "CC0",
|
|
80
|
-
"tones": ["technical", "professional"],
|
|
81
|
-
"duration": 32
|
|
69
|
+
"tones": [
|
|
70
|
+
"playful",
|
|
71
|
+
"professional"
|
|
72
|
+
],
|
|
73
|
+
"duration": 35,
|
|
74
|
+
"bpm": 110
|
|
82
75
|
}
|
|
83
76
|
]
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# SFX provenance
|
|
2
|
+
|
|
3
|
+
The three cue files in this directory are curated **CC0 (public domain)** cues
|
|
4
|
+
from [Freesound](https://freesound.org), loudness-normalized (`loudnorm
|
|
5
|
+
I=-23:TP=-2`) to sit under the bundled music beds. CC0 requires no attribution;
|
|
6
|
+
the uploader credits are kept as a courtesy.
|
|
7
|
+
|
|
8
|
+
| file | Freesound | uploader | role |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| `whoosh.mp3` | https://freesound.org/s/60013/ | qubodup | fast lateral cut (soft air whoosh) |
|
|
11
|
+
| `pop.mp3` | https://freesound.org/s/245645/ | unfa | settle cut (clean pop) |
|
|
12
|
+
| `rise.mp3` | https://freesound.org/s/523057/ | magnuswaker | CTA swell (played from 18 frames before the cut) |
|
|
13
|
+
|
|
14
|
+
The peaks land where `template/src/Root.tsx` schedules each cue. If these ever
|
|
15
|
+
need regenerating without Freesound, `node cli/assets/audio/generate-sfx.mjs
|
|
16
|
+
--force` produces synthetic CC0 stand-ins.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reelme",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Turn your repo into launch videos for social platforms.
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Turn your repo into launch videos for social platforms. Rendered on your machine with Remotion — no accounts, no uploads.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"reelme": "src/cli.mjs"
|
|
8
8
|
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node test/smoke.mjs"
|
|
11
|
+
},
|
|
9
12
|
"files": [
|
|
10
13
|
"src",
|
|
11
14
|
"assets",
|
|
@@ -19,6 +22,9 @@
|
|
|
19
22
|
"engines": {
|
|
20
23
|
"node": ">=18"
|
|
21
24
|
},
|
|
25
|
+
"optionalDependencies": {
|
|
26
|
+
"gifsicle": "^7.0.1"
|
|
27
|
+
},
|
|
22
28
|
"keywords": [
|
|
23
29
|
"launch-video",
|
|
24
30
|
"remotion",
|