Using Project Elm

A tour of the selection UI, saved reels, and the live OBS overlay. Screenshots below use fabricated demo clips — your own grid will show your channel's real clips.

The selection grid

Once you're logged in, every clip Twitch has for your channel shows up as a card with a status badge:

✓ DownloadedAlready pulled locally — click the card (or its + Add to reel button) to include/exclude it.
not downloadedClick ⬇ Download (or the card) to pull it via the official Twitch endpoint — it's auto-included once it lands.
⚠ Removed from TwitchTwitch no longer lists this clip, but you still have it downloaded — it keeps its title/thumbnail and keeps playing in your reel.

Use Search (title or game), Period/Max/Load all, and Show hidden to filter a large clip list — all instant, no re-fetch.

The clip grid with a mix of downloaded, not-downloaded, and removed-from-Twitch cards, next to the “Your reel” panel showing 4 included clips in a custom order.
The grid (left) and the always-visible “Your reel” panel (right).

Card actions

Each card keeps its fast actions up front and tucks the rare/destructive ones away:

A card's ⋯ menu open, showing Hide and Delete download options.
The ⋯ menu — rare and destructive actions only.
A clip preview popup playing a downloaded clip in-page.
Previewing a clip without leaving the grid.

Building "Your reel"

The panel on the right always shows your included clips, with a running clip count and total duration. Pick a play Order:

The On overlay toggles (Title card / Channel / Game) control what's burned into the live lower-third — independent from what's shown in the grid.

Saved configurations

A configuration is a named, reusable reel: its clip selection, order, and toggles. Save as many as you like — "Highlights", "Fails", a per-game reel — each keeps its own stable overlay URL, so renaming or editing one never breaks an OBS source already pointed at it.

The configurations flyout, listing saved reels with Load, Duplicate, Open, and Delete actions.
Manage all configurations: search, Load, Duplicate, Open, Delete.

The topbar's quick-switch shows the currently loaded configuration and a dot when it has unsaved changes. Click Save to update it in place, New to start a fresh draft, or open the flyout to manage the full list.

The live overlay in OBS

  1. Open the overlay URL

    Click Open overlay ↗ (or a saved configuration's own Open ↗) to get its stable URL: /overlay/?config=<id>.

  2. Add it as a Browser Source

    In OBS, add a Browser Source pointed at that URL. Add as many sources as you like, each pointed at a different saved configuration, to run more than one reel at once.

    ⚠️

    In the source's Properties, leave “Shutdown source when not visible” unchecked. That setting makes OBS reload the page on every scene switch — the exact hard refresh the live-reload design avoids. Left unchecked, the overlay also auto-detects when its scene goes off program and pauses + rewinds to clip 1, so it always resumes clean.

  3. Edit live — no refresh needed

    Adding/removing clips, re-ordering, toggling Title/Channel/Game, even downloading or deleting a clip the reel uses — all push to any overlay already open on that configuration, instantly, over SSE.

The overlay playing a clip full-screen with its lower-third title card visible.
The overlay as OBS sees it — full-bleed video, crossfade transitions, optional lower-third.

Alternative: render a fixed MP4

Prefer a file you can upload instead of a live source? Build a manifest.json (the CLI below can generate one for you) and render it:

node render/render-reel.mjs render/realclips/manifest.json   # → render/realclips/reel.mp4

Each clip is normalized (letterboxed, constant fps), loudness-evened (loudnorm), optionally titled, then chained with a crossfade — the output plays anywhere, including as an OBS Media Source.

Optional CLI

The web UI covers everything, but the same fetch/select is available from the terminal:

node render/cli/fetch-clips.mjs login              # one-time browser authorization
node render/cli/fetch-clips.mjs list [--days N] [--first N]
node render/cli/fetch-clips.mjs pull <all|1,3,5>   # download + write manifest.json
← Back to install Full README ↗