The creator is DHH and lipreads their own recordings, so a webcam that judders is an accessibility defect, not a polish item. Take ty-20261005-1001-821-0001.mp4 holds 25.6 distinct webcam images/s against the camera's 30fps with 281 gaps of 50-100ms - roughly one hitch in five - in a file that muxes flawlessly. Nothing in the app could see that: rawvideo carries no per-frame timestamps (ffmpeg stamps by ARRIVAL at the declared 60fps), and the stats line divided every average by the number of frames SUBMITTED, which deadline padding always fills to the full target. So the pump reported "300/300 frames, avg render 12.4ms" while producing 60 distinct composites. Helpers/FrameCadence.cs is one pure counter fed from three points: MediaCaptureFrameSource logs the device's own SystemRelativeTime stamps against our arrival times (TryAcquireLatestFrame keeps only the LATEST frame, so falling behind is silent by design), and FramePump logs the distinct webcam Epoch values that reached a composite. Read together they name the culprit - device/USB, our reader, or our compositor - instead of guessing. Render/resolve/wait now divide by the real render count, and "frames per 5s from R renders" is the duplicate-on-lag ratio stated honestly. An out-of-order timestamp counts as a frame but produces no gap and does not become the next interval's reference, so one bad stamp cannot invent a multi-second hitch twice. Also corrects a stale ai.md line (the "webcam renders at ~18fps" figure came from a different session and counted every newly rendered layer) and re-records the background-removal ruling as permanently out. Records the agreed-but-unbuilt Units 1-2, the no-fallback-camera ruling, and the SetFormatAsync dead end found by probing the 19041 projection. Suite 402/402, 0 warnings. The one red, LayerReorderPersistenceTests' RealMouseDrag, fails identically on a stashed clean tree - it needs an interactive desktop session this shell lacks.
ytLlive
A creator-proof live-streaming and recording app for YouTube — native Windows (C# / WPF / .NET 8).
Screenshot
Design Principle
This software is so intuitive that even the most right-brained person can easily intuit and use it.
Every feature is measured against this. One-click go-live, sane YouTube defaults, visual scene building, and no dead ends — every action has a visible outcome.
Why ytLlive
OBS treats YouTube as an afterthought; SLOBS is Twitch-first with YouTube bolted on. ytLlive is designed and dedicated to YouTube livestreaming and recording, and to YouTube's specific quirks.
Account Assumption
ytLlive assumes you already have a YouTube creator account — connecting uses "Sign in with Google" to link that existing account. ytLlive does not create accounts. If you don't have a YouTube channel yet, set one up on YouTube first, then connect it here.
Audio Assumption
ytLlive uses your default microphone and desktop/game output — it never hunts for a device or contends for one. It assumes your audio is already configured and working (default input and output set, not hijacked by another app). Audio issues are a Windows/device matter outside ytLlive's scope: we don't debug, detect, or try to fix them. If it doesn't sound right, fix the system's audio settings first — it's on the OS, not on us.
Run
dotnet build # Windows only — WPF
dotnet run
Version Roadmap
v1 is the finished product (creator ruling, 2026-09-01 — there are no v1.x releases).
Everything still queueing lands in v1; anything not on the feature list is on the closed
"Out of product — permanently" list in TASKS.md — read that page before asking for a feature.
What v1 ships: the five-scene director's control surface, webcam + screen capture, media + web + text sources, chat on-stream, the social bar, mic/desktop audio with auto-duck and TRAX, local recording, variable quality tiers with auto step-down, one-click go-live + scheduling, stream resilience (auto-reconnect inside YouTube's grace, one-click back on air), built-in monetization awareness (reward capture, session reports, YPP journey tracker), Alerts — all free and ungated; the paid tier only removes the branding flash.
Structure
| Path | Role |
|---|---|
Models/ |
Scene, Source, WebcamSceneConfig, SceneElement, SceneCatalog, QualityOption, StreamConfig/Health, chat, Socials, BroadcastMetadata, Music, MicStatus |
ViewModels/ |
MainViewModel (partial classes per area) + dialogs: GoLive, CameraPicker, MicPicker, HotkeyConfig, Socials, LiveBroadcastForm |
Services/ |
YouTube (OAuth, streams/broadcasts, chat polling), LayoutStore (SQLite), capture (camera/screen-capture/media-file via FFmpeg), SceneCompositor + FramePump, FFmpeg encoder + RTMP, audio pipeline (WASAPI loopback + mic, mixer, filters, ducker, limiter, TRAX), SocialValidator, notifications, hotkeys, SceneGraph, ChatOverlayLayer |
Helpers/ |
ViewModelBase, RelayCommand, ImageCache, AppLog, TokenStore (DPAPI), OAuthCredentials, converters |
Themes/ |
Controls.xaml — the dark-theme control styles, merged once in App.xaml |
MainWindow.xaml |
Dark-theme control surface: thumbnails + central preview, two-state left panel (layers/properties ↔ live chat), top bar, footer |
Distribution.md |
GA-time plan: signing, installer, EULA, hardening — executed as TASK 36 |
Docs (memory map)
schema.md defines the conventions; ai.md is the AI/session guide;
TASKS.md is the task queue. Each code directory carries an index.md.

