namespace ytLive.Services; /// /// TASK 21: a media file decoder exposed to . /// Mirrors IScreenCaptureSource/ICameraFrameSource so the manager /// (and tests) treat a local video file like any other frame source: start/stop /// and a per-frame event consumers coalesce. /// public interface IMediaFrameSource : IDisposable { string Key { get; } /// Raised (on a worker thread) for each decoded frame. event Action? FrameAvailable; /// Raised when the file finishes decoding (natural EOF). event Action? Completed; Task StartAsync(CancellationToken cancellationToken = default); Task StopAsync(); }