Files
ytLlive/HANDOFF.md
T

2.8 KiB

HANDOFF — session state

Current operational state, read right after TASKS.md. Trust this file as the truth of what is in flight — do not re-derive from git/fs unless it points at a problem. Conventions: schema.md. Rewrite this file at session end, compaction, or any interruption.

Session state (last updated: 2026-08-12)

  • Branch: main. TASK 4 ship step 3 (encoder + RTMP push) is built and tested but NOT committed — the working tree is dirty with the encoder (10 new files in Services/Encoder/ + ytLive.Tests/FfmpegEncoderTests.cs) and its memory updates (TASKS.md, ai.md, Services/index.md). Ready to commit when the user says so.

  • Finished this session: TASK 4 ship step 3 — the FFmpeg subprocess encoder: EncoderOptions + IFfmpegEncoder/FfmpegEncoder + IEncoderProcess/ FfmpegEncoderProcess + pure FfmpegArgs/FfmpegProgressParser/ FfmpegEncoderPicker in Services/Encoder/. StartAsync (locate → probe -encoders → spawn → stderr loop), SubmitFrameAsync (serialized BGRA stdin), StopAsync (stdin EOF → ffmpeg finalizes; 10s kill watchdog), ProcessFailed on unexpected non-zero exit. Not yet constructed by the app (ship step 5 wiring). Build: 0 warnings. Tests: 122 passing (was 112; +10 new).

  • Landmines:

    • ChannelReader.ReadAsync on a completed channel throws ChannelClosedException — it does NOT return null like a StreamReader EOF. The test fake (QueuedReader in FfmpegEncoderTests.cs) catches it and returns null, or the encoder's stderr loop treats it as a fault and ProcessFailed never fires (that's exactly what happened on the first run — see commit history).
    • The probe process (FakeEncoderProcess) must be a separate IEncoderProcess instance from the encoder process in Start_* tests — StartAsync calls the factory twice (probe → encoder), and the fake can't simulate both roles at once.
    • StopAsync waits the full ExitTimeout if the fake's process doesn't signal exit — fakes must call SignalExit() inside StopAsync's stdin-EOF path.
    • Windows-only: FfmpegEncoderProcess sets UseShellExecute=false + RedirectStandardXxx=true — never spawn with a shell.
  • Next step: TASK 4 ship step 4 — WASAPI audio capture (loopback + mic) feeding AudioLevel (req 7). Nothing else queued — do not expand the task queue on your own.

  • Secret/DB/port facts live: OAuth client id/secret in Helpers/OAuthCredentials.cs; OAuth session token in Helpers/TokenStore.cs (DPAPI → %APPDATA%\ytLlive\ytLlive.auth); layout DB %APPDATA%\ytLlive\ytLlive.db (schema v8; SocialEntry.Software column is a column-presence migration like the others, no version bump); OAuth callback http://localhost:8765/oauth2/callback; crash log %APPDATA%\ytLlive\startup.log.