# HANDOFF — 2026-09-10 (afternoon) ## Branch / Commit State `main` HEAD currently = `5e78065` (slice 11, committed). **Slice 12 (audio diagnostics) is uncommitted** in the working tree. **Ahead of origin by 17, NOT pushing** — user ruling (2026-09-10): do not push until the web-overlay **transparency AND audio-silence** issues are addressed. Milestone tag `milestone-recording-timing` (annotated) on `c45cbc9` — rollback point: `git reset --hard milestone-recording-timing`. ## Timing saga — CLOSED (verified) Slices 9 (`bd396e4`) + 10 (`c45cbc9`) committed. Takes `0949`/`0957` verified: counter +1/frame, zero gaps/dups. User confirmed → **timing CLOSED.** ## Slice 11 (web capture cadence) — committed `5e78065` 10Hz capture → ~30Hz target with de-throttle flags + `CaptureScheduler` (latest-wins in-flight drop). First verification take (`ty-20260910-1038-0000-2.mp4`, 1423 frames 23.7s) results: - **Capture cost: 35-117ms per frame** (not the hoped 10-30ms). Effective cadence is ~10-14Hz, NOT 30Hz — the scheduler's in-flight drop silently collapsed the target back to roughly the old rate. The in-flight drop works (no stacking), but the decode path (BitmapImage → FormatConvertedBitmap → FindContentBounds full-scan) is too expensive to reach 30Hz. Web animation speed will not have improved meaningfully. Next: the capture cost decides — either optimize the decode path (crop-only, cached bounds) or drop the target to ~15Hz. - FramePump: healthy (300/300 frames, 0 dropped, 6 stalls worst 166ms). - Camera: initialized (YUY2 640×480) but "MJPG negotiation refused (being used by another process)" logged at startup — the webcam source was contested. - Audio: **full-length silent AAC** (−91dB, 1124 frames). User reported: no transparency in web-uri, no webcam video, no audio. The three symptoms are separate threads. ## Slice 12 (audio diagnostics) — uncommitted, in-tree The silence is capture-side: the pipe ran for 23.95s, ffmpeg connected and read ~9.1MB of zeros. Sources started (`Audio: using system default mic...` logged at 10:38:01.296), no failure callbacks fired. The mixer's existing integration test (`Mix_WithFiltersDuckAndGain_Lands_On_AudioPipe`) proves the loop→pipe path carries real audio when fed. Two remaining capture-side suspects: (1) default render device mismatch — audio played on a non-default endpoint (common); (2) both endpoints held exclusive by another process. **Changes in tree:** - `Services/Audio/AudioMixer.cs`: `FillAndMix` now returns `(MicRms, MicDrained, LoopDrained)`; LiveLoopAsync accumulates per-5s telemetry → startup.log: `Audio live: pipe connected=, dropped writes=, micLevel=, loopLevel=, drained, peakMix`; StartLive/StopLive log start/stop lines. - `Services/Audio/NamedPipeAudioWriter.cs`: new `DroppedWrites` counter — nonzero means audio was dropped before ffmpeg connected (names "pipe never connected" stage). - Docs: `ai.md` slice 12 entry. Suite: 290/291 pass — same sole pre-existing compositor pixel failure. ## NEXT STEP 1. Commit slice 12 (scope-check passed on the three source/doc files). 2. User runs a recording with DESKTOP AUDIO ACTIVE (music/game playing → verify the "Desktop Audio" footer bar moves during the take). Send startup.log lines containing `Audio live:`. The log names the stage: - `loopLevel > 0` + `peakMix > 0` + file silent → pipe-side (impossible per integration test; should not appear) - `loopLevel ≈ 0` + `drained 0/0` → capture delivered nothing (default device mismatch or exclusive hold) - `dropped writes > 0` → encoder pipe never connected (timing/ordering bug) 3. If capture-side: add explicit loopback-device selection (enumerate active render endpoints, log the chosen one, allow user to pick) — the fix that makes the mismatch impossible. 4. Then return to web transparency (post-paint dump) and webcam. ## Still Open - **Audio silence** — push gate reason #2. Diagnostic committed pending take (see above). - **Web transparency UNVERIFIED** — instrument blind (about:blank). Needs post-paint re-point. Push gate reason #1. - **Web capture speed** — 30Hz target not achievable with current decode path; capture cost 35-117ms/frame → effective ~10-14Hz. Open question whether to optimize path or accept ~15Hz. - **Webcam missing** in take-1038 — "MJPG negotiation refused (being used by another process)" at startup; camera initialized but possibly contested. Separate thread, queued. - Pre-existing compositor pixel test failure (never in scope). ## Landmines - testhost shares startup.log with app — filter by time when triaging. - Locked DLLs: `taskkill //F //IM testhost.exe //IM ytLive.exe` before rebuild. - Build/tests via `/mnt/c/Program Files/dotnet/dotnet.exe build …` / `… vstest "C:\Users\gramp\Documents\Code\projects\ytLive\ytLive.Tests\bin\Debug\net8.0-windows10.0.19041.0\ytLive.Tests.dll"`. - Probing recordings: `/mnt/c/Program Files/Krita (x64)/bin/ffmpeg.exe` / `ffprobe.exe`. - `tools/ticker`: constant ~+982ms offset on the FIRST line is cosmetic. - WebView2 capture cost: 35-117ms per full-HD PNG encode+decode — the hard ceiling on web animation capture rate. Slice 13 candidate if the user wants to pursue 30Hz. - WASAPI loopback: captures the DEFAULT render endpoint only — if the user plays audio through a non-default device, the recording is silently silent. This is likely the root cause of the audio-silence issue. The fix requires device enumeration + selection.