namespace VideoDownloader.Server; /// 다운로드 큐 항목 스냅shot (모바일/웹 컴패니언용). public sealed record QueueItemDto(string Id, string Title, string Url, string Status, double Percent); /// 라이브러리(저장 폴더) 미디어 항목. public sealed record LibraryItemDto(string Id, string FileName, long SizeBytes, DateTime Modified, string? Resolution = null); /// 이어보기 위치(U3 동기화). 초 단위. public sealed record PositionDto(double PositionSec); /// 서버 구성. public sealed class ServerOptions { /// 0 이면 사용 가능한 포트 자동 할당. public int Port { get; init; } /// 페어링 토큰(Bearer). 비면 자동 생성. public string Token { get; init; } = ""; /// 라이브러리로 노출할 폴더. public string LibraryFolder { get; init; } = ""; /// 다운로드 큐 어댑터(호스트 앱이 구현 주입). public IQueueAdapter Queue { get; init; } = new EmptyQueueAdapter(); /// 기기 표시명(웹 컴패니언 헤더용). public string DeviceName { get; init; } = Environment.MachineName; /// 썸네일/해상도 생성기(기본: DesktopProcessRunner 기반 ffmpeg). 테스트 주입 가능. public Thumbnailer? Thumbnailer { get; init; } /// mDNS 광고(_videodl._tcp) 켜기 — MOBILE_PLAN §3. 실패해도 서버는 뜬다(MdnsError 로 노출). public bool EnableMdns { get; init; } /// ffmpeg 경로 오버라이드(기본: 설정→PATH 탐색). 호스트 ffmpeg 없는 환경 테스트용. public string? FfmpegPath { get; init; } } /// 기본 썸네일러 팩토리. public static class ServerOptionsDefaults { public static Thumbnailer DefaultThumbnailer() => new(VideoDownloader.Core.Platform.DesktopProcessRunner.Default); } /// 호스트 앱의 다운로드 큐와 서버를 잇는 어댑터(UI 스레드 마샬링은 구현측 담당). public interface IQueueAdapter { Task> GetItemsAsync(); Task AddAsync(string url, string? title); Task PauseAsync(string id); Task ResumeAsync(string id); Task CancelAsync(string id); event Action? Changed; } /// 큐 없이 서버만 띄울 때의 기본 구현. public sealed class EmptyQueueAdapter : IQueueAdapter { public Task> GetItemsAsync() => Task.FromResult>(Array.Empty()); public Task AddAsync(string url, string? title) => Task.FromResult(""); public Task PauseAsync(string id) => Task.CompletedTask; public Task ResumeAsync(string id) => Task.CompletedTask; public Task CancelAsync(string id) => Task.CompletedTask; public event Action? Changed { add { } remove { } } }