Skip to content

redlamp/video-wall

Repository files navigation

Video Wall

A browser-based video wall for playing many local videos at once. Drop in files or whole folders and the wall lays them out into rows, plays everything automatically, and swaps in fresh clips from your session catalog as videos finish.

Live demo: https://redlamp.github.io/video-wall/

Everything runs in the browser. Videos never leave your machine — files are read locally, played from in-memory object URLs, and your session is cached in IndexedDB. There is no server and no upload.

Features

  • Drag-and-drop ingest — drop individual video files or entire folders onto the window. Supports .mp4, .mov, .webm, .m4v, .mkv, .avi.
  • Self-filling wall — videos are packed into a configurable number of rows; when a clip ends it is replaced from the catalog so the wall keeps playing.
  • Letterbox / crop detection — auto-detects black bars per video; choose fit, fill, or detected crop modes.
  • Aspect filtering — show a mixed wall, or restrict to landscape / portrait clips.
  • Per-tile controls — pin, mute, seek, step to next/previous, zoom, remove.
  • Multi-select — shift-drag a marquee or ctrl/cmd-click to act on many tiles at once.
  • Reorder by drag — drop tiles between others to rearrange the wall.
  • Scroll modes — scroll the whole wall horizontally, or scroll each row independently.
  • Global playback — play/pause all, seek, master volume, playback rate, shuffle.
  • Preference persistence — playback settings (rows, sort, volume, speed, crop, shuffle) and theme are restored on reload via IndexedDB / localStorage. Video files must be re-added — browsers don't retain access to local files across reloads — but per-file metadata (duration, dimensions, detected crop) is cached so re-adding is fast.
  • Light / dark theme and a draggable, auto-hiding control panel.

Keyboard shortcuts

Key Action
Space Play / pause targets
/ Seek selected (or zoomed: previous / next video)
/ Master volume up / down
` / ~ Toggle control panel
Esc Close zoom → close panel → clear selection

Tech stack

  • Next.js 16 (App Router, static output: "export")
  • React 19, TypeScript
  • Tailwind CSS v4 + shadcn/ui (base-ui) components
  • GSAP for layout/FLIP animations
  • idb for IndexedDB session storage

Getting started

npm install
npm run dev

Open http://localhost:3000 and drop some videos onto the page.

Scripts

Script Purpose
npm run dev Start the dev server
npm run build Static export to out/
npm run lint ESLint
npm run smoke Playwright smoke test (scripts/smoke-video-wall.mjs)

Branching & deploys

This repo follows a main ← dev ← feature/* model:

  • feature/* / fix/* — branch off dev, open a PR into dev. Merged with squash (clean, linear dev history).
  • dev — integration branch; promoted to main via PR merged with a merge commit (not squash). This keeps main containing dev's history, so the two branches never diverge. Squash-promoting devmain would put an unrelated commit on main each time and eventually cause conflicts.
  • main — production. Pushes trigger the Deploy GitHub Pages workflow (.github/workflows/deploy-pages.yml), which builds the static export and publishes to GitHub Pages.

Both main and dev are protected: PRs required, no force-push or deletion, and the CI workflow (.github/workflows/ci.yml — lint + build + smoke) must pass before merge.

The Pages build sets GITHUB_PAGES=true so next.config.ts applies the /video-wall base path and asset prefix.

About

Browser-based video wall — drop in local videos or folders and they auto-play, pack into rows, and self-refill. 100% client-side, nothing uploaded.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors