TASK 18: local (record-only) recording pipeline + top-bar pills/light/Start-End button UX
Encoder dual-output: StreamEnabled/RecordEnabled/RecordPath options; per-output ffmpeg block (stream ->flv, record ->mp4); throw unless at least one output. RecordingFile: auto-name ty-<yyyymmdd>-<start hhmm>-0000.mp4, rename-on-stop to ty-...-<len hhmmss>.mp4 with numeric-suffix on collision. LayoutStore persists record folder. MainViewModel: REC/ON-AIR pills, status light, single Start<->End button (replaces Start/Stop variants), StopStream no longer signs out, explicit session timer. About overlay widened. Sign In label + spacing before Start. Tests: 244 passed / 246 (2 pre-existing: AudioPipeline gains-mute, RoundClip). Build 0 warnings. Scope check clean. Memory-map correction (derived-solution rule, 2026-08-29): image-shrink recipe was never recorded when first done, so it was re-derived. Added Derived-solution/recipes rule to AGENTS.md; MyMistakes.md now a permanent recipes registry (records the verified WPF-imaging shrink recipe); schema.md rows MyMistakes as registry; ai.md points to the rule. README hero image replaced: 3.2MB screenshot -> 1400x794 -> 188KB docs/ytLlive-preview.jpg (JPEG q82).
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
namespace ytLive.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Pure filename logic for local recordings (TASK 18). The user-requested naming
|
||||
/// is <c>ty-yyyymmdd-hhmm-hh2mm2.mp4</c>: <c>ty</c> is the brand marker, the first
|
||||
/// <c>hhmm</c> is the hour+minute the recording STARTED (saved), and the second
|
||||
/// <c>hh2mm2</c> is the hour+minute of the recording's LENGTH. Length is only known
|
||||
/// when recording ends, so the file is created with a <c>0000</c> length and renamed
|
||||
/// on stop (see <see cref="FinalizeFileName"/>).
|
||||
/// </summary>
|
||||
public static class RecordingFile
|
||||
{
|
||||
/// <summary>A start placeholder — the length is filled in on stop.</summary>
|
||||
public const string StartLengthSuffix = "0000";
|
||||
|
||||
public static string BuildStartName(DateTime start)
|
||||
=> $"ty-{start:yyyyMMdd}-{start:HHmm}-{StartLengthSuffix}";
|
||||
|
||||
/// <summary>Final name with the real recording length (fractional hour+minute),
|
||||
/// e.g. 75 minutes → <c>ty-20260829-1405-0115.mp4</c>.</summary>
|
||||
public static string BuildFinalName(DateTime start, TimeSpan length)
|
||||
{
|
||||
var hh2 = (int)length.TotalHours;
|
||||
var mm2 = length.Minutes;
|
||||
return $"ty-{start:yyyyMMdd}-{start:HHmm}-{hh2:00}{mm2:00}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user