A web application simplifying coordination between the director and camera operators. Inspired by available commercial solutions, Ready2Take2 tries to help the team produce a tightly timed, planned show without taking away control. The director can plan shots and cues based on an earlier recording, then they can step through the cues while all camera operators can follow along the progression of the show on mobile devices and screens. Countdowns provide information on length of the shot.
Progression through the cues is manual triggered by the director or by reacting to transitions happening in the switcher.
Easiest way to get going is to use Docker Compose. Create docker-compose.yaml file:
services:
ready2take2:
image: jstarpl/ready2take2:latest
container_name: ready2take2
restart: unless-stopped
ports:
- "3000:3000"
- "8000:8000/udp"
volumes:
- ./data:/app/dataRun
docker-compose up -dOpen the app at http://localhost:3000 and sign in with the default credentials:
- Username:
admin - Password:
admin123!
Ready2Take2 listens for incoming OSC messages over UDP on port 8000 by default.
You can change this with the OSC_PORT environment variable.
Supported incoming OSC addresses:
/production/take- Executes a Take for the show with a current cue.
/production/moveNext/forward- Moves the next cue one cue forward.
/production/moveNext/backward- Moves the next cue one cue backward.
Example (oscsend):
oscsend localhost 8000 /production/take
oscsend localhost 8000 /production/moveNext/forward
oscsend localhost 8000 /production/moveNext/backward- Install dependencies:
pnpm install
- Start client + server in one command:
pnpm dev
- Open the app:
- Client:
http://localhost:5173 - Server:
http://localhost:3000
- Client:
pnpm buildbuilds the client and compiles the serverpnpm typecheckruns TypeScript checks for client and serverpnpm startstarts the compiled server (dist/server/index.js)
- Vite + React
- Express + tRPC
- SQLite + TypeORM
- Zod
- Tailwind + shadcn-style UI foundation
- Auth
- Username/password login with server-side session cookie
- Seeded admin account for local development
- Projects and shows
- Create projects and shows
- Show creation automatically creates a default
Cameratrack
- Show workspace
- Create, update, delete, and reorder cues
- Set
currentandnextcue pointers Takeaction (andF12shortcut) to advance cue pointers- Edit per-track technical identifiers for each cue
- Create/remove tracks with automatic cue-track value backfill/integrity handling
- Collaboration and refresh
- Show-scoped realtime events over WebSockets/tRPC subscriptions
- Client refresh through query invalidation on mutation success and subscription events
- Media
- Upload and delete show-scoped media files
- Select media for the workspace and control playback in the bottom media player
- Cue List View route for a focused cue display/filter workflow
- Project
- Top-level container for shows.
- Show
- Production workspace holding tracks, cues, media files, and two pointers:
currentCueId,nextCueId.
- Production workspace holding tracks, cues, media files, and two pointers:
- Track
- Column-like dimension (for example: camera, audio, graphics) shared across all cues in a show.
- Cue
- Ordered show event with
cueId,comment, and optionalcueOffsetMs.
- Ordered show event with
- CueTrackValue
- Per-cue/per-track technical identifier value.
- Every cue should have one value row for every track in the same show.
- Show-scoped realtime
- Mutations publish events for a single show, and clients viewing that show refresh from those events.
The server seeds a default user on first start:
- username:
admin - password:
admin123!
- SQLite data is stored under
data/ready2take2.sqlite - Uploaded media is stored under
data/uploads - Import alias
@/resolves tosrc/ - This is a scaffold, not a finished production app