gramps e3e69d941d recording save dialog: Cancel discards the footage instead of saving the default
The creator reported that clicking Cancel in the post-recording save prompt still
saved the file under the default name: "cancel should cancel the save option,
discarding the recording" — Enter is what accepts the default.

The modal was always correct (Enter -> DialogResult=true, Cancel/Escape/X -> false).
The bug was in the caller: FinalizeRecordingAsync only overwrote `stem` when the
dialog returned true and then ran File.Move UNCONDITIONALLY, so a falsy result fell
straight through into the save. The nullable stem made "I don't want this" look
like "I accept the default".

Extracted the decision into internal MainViewModel.CompleteRecordingSave so it is
testable against real files without a frame pump:
  creatorSaved == false (Cancel/Escape/X) -> delete the temp file, leave the
      videos folder empty; a failed delete returns DiscardFailed and the toast
      names the file + folder (a "discarded" recording still on disk is worse
      than no report).
  creatorSaved == true (Save, or Enter on the pre-filled default) -> File.Move.
      A blank box still means "keep the auto name", but only on an explicit Save.

Test: ytLive.Tests/RecordingSaveDialogTests.cs — 5 facts over real temp files. The
headline asserts Cancel leaves the directory EMPTY, not merely "the stem is
unchanged"; a modal's own test cannot cover the decision it feeds.

Full suite 362/362 (the RealMouseDrag flake passed this run).
2026-09-27 09:25:21 -07:00

ytLlive

LlamaCasty — livestream smarter

A creator-proof live-streaming and recording app for YouTube — native Windows (C# / WPF / .NET 8).

Screenshot

ytLlive — main window with scenes, sources, and live preview

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 one-time license 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.

S
Description
Creator-proof live-streaming and recording app for YouTube — native Windows (C# / WPF / .NET 8). One-click go-live, visual scene building.
Readme 39 MiB
Languages
C# 99.6%
Shell 0.3%