A drawing is a first-class :type :drawing entity (normalized strokes + seed), bound to a mark via mark :drawings [gid] — same referrer-pointer model as notes. It renders as a boiling SVG overlay on the video whenever the playhead is in the bound mark's span (the same hook that lights an annotation active), including when that annotation is the pushed context. - Author in an overlay on the video monitor: pencil, eraser (deletes a whole stroke), undo; the 🖼 button on each mark row enters draw mode and seeks to the mark's frame. - Boil is procedural: 3 seeded jitter variants of the base paths cycled at ~7fps; only the strokes persist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| scenes | ||
| server | ||
| tl | ||
| .dockerignore | ||
| .gitignore | ||
| DEPLOY.md | ||
| Dockerfile | ||
| fly.toml | ||
| manage.py | ||
| README.md | ||
| requirements.txt | ||
scene_analysis
tl/— the lumet frontend (ClojureScript / reagent / re-frame). Seetl/.- Django backend (this folder) — users, admin, and persistence of OTIO + the timeline scene.
Backend
The backend stores one Project per editing session: the uploaded OTIO
source file, the playback fps, and the live scene (the {:tracks :groups} mark-group map the frontend keeps in app-db) as a JSON dump.
Run
python -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python manage.py migrate
DJANGO_SUPERUSER_PASSWORD=admin .venv/bin/python manage.py createsuperuser --noinput --username admin --email admin@example.com
.venv/bin/python manage.py seed_demo # demo project from tl/.../one_two_three.otio
.venv/bin/python manage.py runserver 0.0.0.0:9001 # 0.0.0.0 so it's reachable over Tailscale/LAN
Admin: http://127.0.0.1:9001/admin/ (admin / admin). Upload OTIO and inspect the scene JSON there.
API (session auth; 401 if not logged in)
| Method | Path | Purpose |
|---|---|---|
| GET | /api/projects/ |
the current user's projects |
| GET | /api/projects/<id>/scene/ |
{fps, scene} |
| PUT | /api/projects/<id>/scene/ |
replace scene and/or fps (JSON body) |
| GET | /api/projects/<id>/otio/ |
serve the uploaded OTIO file |
| GET | /api/projects/<id>/revisions/ |
save history (who / when / summary) |
Attribution
Annotations are the authored unit, so that's what's attributed — and the server
is the authority (client-sent stamps are ignored, so authorship can't be
forged). On each scene PUT the server diffs incoming annotation groups against
the stored ones and stamps createdBy/editedBy (+ timestamps) from
request.user; it also writes a Revision (user, time, +N ~N −N summary,
snapshot of the annotation layer). A project is editable by its owner and any
collaborators (managed in the admin), so different users get distinct stamps.
The frontend currently loads /one_two_three.otio and persists annotations to
localStorage; pointing it at /api/projects/<id>/otio/ and the scene endpoints
is the next wiring step (CORS/credentials needed across the dev ports).