Skip to content
open-slidePublic

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

open-slide-marketing

Every marketing asset for open-slide lives here: launch films in films/<id>/ and images (OG cards, README banners, social posts) in images/<id>/. Both are plain HTML/CSS rendered by headless Chromium, and both show up in one workspace.

Setup

pnpm install
pnpm exec playwright install chromium   # unless CHROMIUM_PATH is set

Some features read from a local checkout of the open-slide monorepo: /@repo, /@deck, and image publish targets. It is found at $OPEN_SLIDE_REPO, defaulting to ../../npm/open-slide relative to this repo. Films and images that use none of those work without it.

Workspace

pnpm dev                                  # → http://127.0.0.1:5180

Overview shows every video and image with its latest render. Pick a project in the sidebar to see its Renders, newest first, with the settings each was made with (resolution, render time, git commit; motion blur and encode for films; publish target for images). A render in progress shows live progress. Preview is the live source: the scrubbable film (/film.html?film=<id>), or the image page at every output size.

New project

pnpm new:film comments-launch --feature "Comments" --tagline "Feedback, pinned to the slide."
pnpm new:image comments-og --title "Comments are here"

new:film copies templates/film: a 20-second intro, feature demo, and outro that renders as-is. new:image copies templates/image: a manifest and a page. The create-video and create-image skills (.claude/skills/) walk an agent through a whole film or image from just a feature name. Films and images share one id space, since both render to out/<id>/.

Render

pnpm render <id>                # a film → MP4, an image → one PNG per output

Each render is written to out/<id>/renders/<name>-<timestamp>.{mp4,png}, with a .json sidecar recording how it was made. Nothing is overwritten. The first run downloads Google Fonts into out/fonts/<id>.

Films

1920 × 1080 at 60 fps, with a synthesized soundtrack. Every frame is driven by a deterministic timeline. Scenes are pure functions of time, so frames render out of order across parallel workers, and ffmpeg encodes them.

pnpm render <id> --scale 2      # 3840 × 2160
pnpm render:draft <id>          # 30 fps, 960 × 540, no motion blur
pnpm soundtrack <id>            # just out/<id>/soundtrack.wav
pnpm stills <id> 12.5,30        # PNG stills at the given seconds → out/<id>/stills/
pnpm snapshot [--save]          # guard shared src/ and audio/ changes against every film

With a single film, <id> can be left out. Rendering needs ffmpeg built with libx264 on PATH, or set FFMPEG. It uses Playwright's Chromium, or set CHROMIUM_PATH. The soundtrack is re-synthesized on every render.

Useful flags: --name, --out, --from/--to (seconds), --fps, --samples (motion-blur sub-frames), --shutter, --workers, --scale, --crf, --grain, --no-audio. They override --draft.

Images

images/<id>/image.js lists the outputs. The page (index.html) is rendered once per output at that viewport size, so one layout can serve several aspect ratios.

export default defineImage({
  title: 'Cover',
  outputs: [
    { name: 'og', width: 1200, height: 630, publish: 'apps/web/app/opengraph-image.png' },
    { name: 'readme', width: 1280, height: 640 },
  ],
});

publish copies the render to that path in the monorepo. Flags: --only og,readme, --scale 2 (2× pixel density), --no-publish.

Pages can use:

URL What
/out/fonts/_base/fonts.css Geist and Geist Mono. Extra Google Fonts go in the manifest's fonts, served at /out/fonts/<id>/fonts.css.
/@deck/<deck>/<page>.png A real slide: page <page> of a deck in packages/cli/template/slides or apps/demo/slides, built with the monorepo's core and screenshotted at 1920 × 1080. Cached in out/.cache/decks until the deck's sources change. Run pnpm core build in the monorepo first if core's dist is stale.
/@repo/<path> Any file in the monorepo, such as /@repo/apps/web/public/open-slide.png.

The render waits for fonts and every <img>. A page that builds itself asynchronously sets window.__ready = false up front and true when done.

Layout

Path What
films/<id>/film.js The manifest: title, duration, BPM, poster time, extra fonts, scenes, transitions, hits.
films/<id>/timeline.js Chapters (via sequence), card hand-offs, and the big hits that drive camera shake.
films/<id>/scenes/* One file per chapter. Each exports build(root), update(state, t, T), and its sfx cues.
films/<id>/score.js The film's music, played on the shared kit.
images/<id>/image.js, index.html An image's outputs, and the page they render.
src/engine.js, src/main.js, film.html Mounts a film's scenes, card hand-offs, shake/flash post layer, preview scrubber.
src/lib/* Timing, easing, DOM, text effects, cursor routes, defineScene, defineFilm/sequence, defineImage.
src/ui/* Recreations of the open-slide viewer, editor, home, and export UI, built from core's tokens and Lucide icons.
audio/kit.mjs, audio/sfx.mjs Instruments, the house groove, and the sound-effect library scenes cue by name.
audio/synth.mjs Plays a film's score and cues, then mixes and masters its soundtrack.
scripts/render.mjs Routes render <id> to render-film.mjs (frame capture, motion blur, grain, encode, audio mux) or render-image.mjs.
scripts/decks.mjs Builds and screenshots decks for /@deck.
scripts/serve.mjs, studio.html, src/studio/* The workspace: projects and renders API, byte-range video serving, and the UI.
templates/film, templates/image What new:film and new:image copy.

Film code imports shared modules as #lib/…, #ui/…, and #theme. package.json imports resolves them in Node, and the import maps in film.html and studio.html resolve them in the browser.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages