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

6.3 KiB
Raw Permalink Blame History

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.