repo/LAST_STATE.md
Ezequiel C. 161464602e multistreaming: fix scene font paths for Alpine, add session state notes
SCENE_FONT defaults in config.js point at Debian's font layout, which does
not exist in the Alpine runtime image; drawtext only rendered via fontconfig
fallback. Pin the Alpine paths in the Dockerfile env.

Also add LAST_STATE.md (E2E test results + approved plan for the OBS-style
panel rework) and the OBS reference screenshot for the redesign.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-02 23:30:21 +02:00

99 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LAST_STATE — 2026-09-02
Session sign-off snapshot. Read this first when resuming the multistreaming work.
## 1. Done: multistreaming E2E test (podman) — all passing
Tested the whole app in rootless podman: built `multistreaming:test` from
`services/multistreaming/Dockerfile`, ran with `--network host`, `AUTH_MODE=local`, volume
`ms-test-data`.
- HTTP API smoke: health, auth config, providers, register/login/session, `/api/me`, `/api/state`.
- RTMP ingest: published 12s `testsrc2` with host ffmpeg → feed went live in state, cleaned up on unpublish.
- Passthrough fanout: `-c copy` child pushed to a local `ffmpeg -listen 1` RTMP sink on :1936;
sink file probed as h264 1280×720, 12.004s — exact copy, 0 restarts.
- Scene composition: grid scene + text overlay activated → passthrough suspended, composed child
ran; sink file h264 1920×1080 + aac program audio; drawtext overlay confirmed rendered
(white-glyph pixel analysis; fanout log shows the correct filter graph).
- Persistence: accounts/rooms/feeds survived container recreation (volume).
Scratch scripts: `/tmp/ms_test/` (passthrough.sh, scene.sh, verify-fix.sh, ids.txt…).
Test recipe in Claude memory: `memory/multistreaming-podman-test.md`.
Test container `ms-test` may still be running (panel :8080); teardown:
`podman rm -f ms-test && podman volume rm -f ms-test-data`.
## 2. Done: Dockerfile font path fix (committed)
`src/config.js` defaults `SCENE_FONT`/`SCENE_FONT_BOLD` to Debian's
`/usr/share/fonts/truetype/dejavu/`, which does not exist in the Alpine image (fonts live in
`/usr/share/fonts/dejavu/`). drawtext only worked via FFmpeg's fontconfig fallback.
Fixed by setting the Alpine paths as ENV in `services/multistreaming/Dockerfile`. Rebuilt,
re-verified (fanout log shows the correct fontfile, overlay still renders).
## 3. In progress: OBS-style rework of the web panel (`services/multistreaming/web`)
Reference image: `reference1.png` (repo root) — an OBS Studio screenshot:
left dock Scenes+Sources, center program canvas, right dock Audio Mixer + Scene Transitions +
Controls, bottom status bar. (Image viewing is broken in this environment; the layout was decoded
via OCR.)
**User-approved target layout — variant B:**
```
┌──────────┬──────────────────────┬───────────────┐
│ SCENES │ │ CONTROLS │
│ │ PROGRAM PREVIEW │ Start/Stop │
│ SOURCES │ (live feed) ├───────────────┤
│ (media) │ │ Rooms/Vaults │
│ ├──────────────────────┤ User/Members │
│ │ MIXER │ TRANSITIONS│ │
└──────────┴──────────────────────┴───────────────┘
```
- **Left dock**: Scenes + Sources (media feeds) + Destinations (output routing) + Images.
- **Center**: simulated 16:9 program canvas; beneath it Audio Mixer + Scene Transitions panels;
OBS-style slim status bar at the bottom.
- **Right sidebar**: Streaming Controls + app nav (rooms/vaults/user, moved from the left) +
Members. The current left `AppSidebar` and right `RoomSidebar` are both absorbed into this one
right sidebar.
- **Simulated program canvas** (no real video pipeline): render from scene data — grid/PiP layout
math mirroring backend `src/compose.js` (grid cell = floor(W/cols) × floor(H/rows), single live
feed promoted fullscreen, PiP main fullscreen + 480×270 window top-right); slot boxes with feed
names + LIVE badges; text/image overlays at their real coordinates scaled to the canvas
(text: x,y,fontSize,color,bold; image: x,y,width,height,opacity, src `/api/images/:id/file`).
Passthrough mode (no active scene): live feeds in a simple grid. Scene activate crossfades the
canvas (CSS transition keyed on `activeSceneId`).
**Design decisions already made:**
1. **Mixer**: active scene → one channel per scene-output with functional audio-routing control
(Program/Silent/Feed via `api.updateSceneOutput`) + animated meter when `runtime.running`.
Passthrough → channels = live feeds, decorative animated meters only (no real levels exist).
2. **Transitions**: "Fade" + duration slider (localStorage, client-side only) controlling the CSS
crossfade of the simulated canvas on scene activate. Real video crossfade = future backend work.
3. **Controls**: Start Streaming (existing `GrantDialog` flow), **Stop Streaming** (wire the
currently unused `api.stopStream` — zero call sites today), per-account grant/live status.
No Studio Mode / Recording / Virtual Camera (no backend equivalents).
4. **Right sidebar**: Controls + NavVaults + NavRooms + NavUser + Members; renders vaults/rooms/user
even without a room open (Controls/Members room-only).
5. **HomeView** unchanged, just rendered in the center column without a left sidebar.
6. Keep prop-drilling + 3s `api.state()` polling (src/lib/use-app.ts); no state rewrite.
7. SceneEditorDialog / ImageUploader / PromptDialogs stay dialogs; only mounting points move.
**Current codebase facts (from exploration):**
- Shell: `src/App.tsx` (SidebarProvider > AppSidebar + SidebarInset{header+RoomView|HomeView} +
RoomSidebar; global dialogs at App level). No router; nav via useApp `screen/roomId`.
- Components: `app-sidebar.tsx`, `room-sidebar.tsx`, `room-view.tsx` (stacked cards), `scene-panel.tsx`,
`scene-editor.tsx` (606-line dialog), `dialogs.tsx` (GrantDialog 428-515), `image-upload.tsx`,
`home-view.tsx`, `nav-*.tsx`, `theme-provider.tsx` (`useTheme` unused in UI).
- shadcn ui/ has sidebar/card/dialog/select/switch/toggle-group/badge/tooltip etc.
**Missing: slider** (build `ui/slider.tsx` from the `radix-ui` unified package already in
dependencies — no new npm deps).
- `lib/api.ts` has every endpoint needed; `lib/types.ts` covers all state shapes.
- Dark theme tokens are neutral gray (`src/index.css`); OBS look is dark blue-gray — subtle token
tint planned.
**What remains:** implement the layout (no code written yet). The full implementation plan
(component-by-component, canvas math, crossfade pattern, styling tokens, order, risks) is in
`~/.claude/plans/starry-tickling-grove.md`.