From 097dd0d9bd6e78a4995e562acbc483690cca25a8 Mon Sep 17 00:00:00 2001 From: gramps Date: Mon, 31 Aug 2026 20:17:09 -0700 Subject: [PATCH] docs: hand off TASK 21 UI picker slice (acquisition + loop wiring spec) All headless-testable TASK 21 decoder/mechanism slices shipped; the remaining UI picker slice (AddMedia command + file dialog + Acquire/Release + Source.MediaIsLooping -> IMediaFrameSource.Looping) is a GUI feature and is spec'd in HANDOFF for native Windows build + verification. TASKS status + HANDOFF updated. --- HANDOFF.md | 35 +++++++++++++++++++++++++++++------ TASKS.md | 2 +- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/HANDOFF.md b/HANDOFF.md index 8c46b87..b71d432 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -14,7 +14,7 @@ the full refactor series (Commit F `3107f92`, Commit G `85893ea`). ## What's In Flight -**TASK 21 (media source) — slice 1 step 3 shipped (the session-manager + interface); next open work is the VM wire-in (slice 1 step 4).** +**TASK 21 (media source) — all headless-testable decoder/mechanism slices shipped (slice 1 + 2a + 2b + 3); the remaining UI-picker (acquisition) slice is handed off below — it is a GUI feature to build + verify on native Windows.** Increment A (the `Source` model: `MediaSourceType`, `SourceType.MediaSource`, `MediaPath`/`MediaIsLooping`/`MediaVolume`/`MediaPlaybackState` + LayoutStore @@ -83,11 +83,34 @@ pure tests run in WSL; user verifies the GUI suites on native Windows PowerShell ## Next -1. Commit slice 3 (this unit): loop mechanism + process factory + probe wiring + tests + docs. -2. UI picker slice: acquire/release media sessions on add/remove AND wire `Source.MediaIsLooping` → `IMediaFrameSource.Looping` (manager-level per-path loop provider). -3. Slice 3: loop control (restart decode on `Completed` when `MediaIsLooping`). -4. UI picker slice: acquire/release media sessions on add/remove (the remaining slice-1-step-4 open end). -5. Await user push checkpoint for the pending TASK 22/21 commits. +1. **(Handed off) UI picker slice** — the last TASK 21 work unit. GUI feature; build + verify natively on Windows. +2. Await user push checkpoint for the pending commits (TASK 22 + TASK 21 slices below). + +## UI picker slice — handoff spec (2026-08-31) + +Nothing `AcquireAsync`s a media path yet, so **no frames flow in a running app** — +the decoder, manager, pacing, and loop mechanism are all shipped and unit-tested, +but a media Source has no way to start a session. Deliverables, in order: + +1. **File picker + add/remove commands** (mirror `MainViewModel.Background.cs`/`Trax.cs` + `OpenFileDialog` usage — see `MainViewModel.Trax.cs:68`). A "Media" source action + opens an `OpenFileDialog` filtered to video (mp4/mov/avi); on OK set `Source.MediaPath`, + add to scene, and **`AcquireAsync(MediaPath)`**; on remove **`ReleaseAllAsync(MediaPath)`**. + On `StagedScene` layout loads/teardown, call `ReleaseAllAsync` for every media path no + longer present (and acquire new ones) so sessions track the live scene. +2. **Wire `Source.MediaIsLooping` → `IMediaFrameSource.Looping`** — needs a manager-level + per-**path** loop provider (see ambiguity: sessions are refcounted per `MediaPath` and + shared across scenes, but `MediaIsLooping` is per-`Source`; a scene set → the path's + session `Looping` = any live reference has it on, so one scene turning it on while + another shares the file is shared behaviour — pick a rule and record it). +3. **Loop toggle + volume slider** in the source context menu / inspector (TASKS 11/10). +4. `MediaVolume`/`MediaPlaybackState` wiring (audio path for media is future work). + +**Design notes to preserve:** `ResolveOutputFrame` reads `_mediaManager.GetLatestFrame(MediaPath)`; +`OnMediaPreviewBitmapChanged` adopts the shared `WriteableBitmap` per path; `MediaFailed` → +`OnMediaFailed` (currently `Debug.WriteLine`, surface in UI). Composer scales any frame size. +Tmpl: the real-ffmpeg decode/loop/restart path is only exercised natively on Windows — first +GUI smoke test should add a short mp4, confirm it plays and previews, then crash further. ## The directive (2026-08-31, user) diff --git a/TASKS.md b/TASKS.md index ebb4025..80c6323 100644 --- a/TASKS.md +++ b/TASKS.md @@ -1036,7 +1036,7 @@ The tasks below are ordered by dependency and risk. Each task builds on the prev **Goal:** play video files (MP4, MOV, AVI) into scenes — starting soon videos, BRB loops, intro/outro clips. -### Status: 🔶 In progress — Increment A (model + persistence) + Increment B (decoder) shipped; slice 1 step 3 (manager + `IMediaFrameSource`) shipped; resolver/preview wire-in + pacing + loop open +### Status: 🔶 In progress — Increment A (model + persistence) + Increment B (decoder) + slice 1 (manager + resolver/preview wire-in) + slice 2a/2b (ffprobe probe + native-FPS pacing) + slice 3 (loop mechanism) shipped. **Remaining: the UI picker slice (AddMedia command + file dialog + Acquire/Release wiring + loop-flag wiring) — GUI, handed off to build/verify natively on Windows (see HANDOFF → "UI picker slice — handoff spec").** 1. ✅ `MediaSourceType` enum: `Video`, `Audio` (audio-only files via media source) 2. ✅ `SourceType.MediaSource` addition to the enum