using DeepDrftModels.Enums; using DeepDrftPublic.Client.Clients; using DeepDrftPublic.Client.Common; using Microsoft.Extensions.Logging; namespace DeepDrftPublic.Client.Services; /// /// The production player that honours the listener's streaming-quality preference (Phase 18 wave 18.6). /// Extends through the single deliberately-overridable seam, /// , so the rest of the streaming stack /// (seek, telemetry, the seek-beyond-buffer format reuse) is inherited verbatim. /// /// The override is one branch: a preference returns /// immediately; anything else falls through to base, which keeps /// the 18.5 invariants intact — the capability gate (AC7: a browser that can't decode Ogg Opus gets lossless) /// and the sidecar-absent → lossless fallback (C2: a legacy / un-backfilled / failed-transcode track gets /// lossless). So a Lossless pick always yields lossless; a Low-data pick yields Opus only when it can /// actually play, and lossless otherwise. No path produces an unplayable stream. /// /// public class PreferenceAwareStreamingPlayerService : StreamingAudioPlayerService { private readonly PublicSiteSettings _settings; public PreferenceAwareStreamingPlayerService( AudioInteropService audioInterop, TrackMediaClient trackMediaClient, ILogger logger, PublicSiteSettings settings) : base(audioInterop, trackMediaClient, logger) { _settings = settings; } protected override async Task ResolveStreamFormatAsync(string entryKey, CancellationToken cancellationToken) { // Listener explicitly chose lossless — request it directly, no Opus probe / sidecar fetch needed. if (_settings.StreamQuality == StreamQuality.Lossless) { return AudioFormat.Lossless; } // Low-data preference: defer to the base capability-gated resolution, which probes Opus support and // the sidecar's presence and degrades to lossless when either is missing. Both 18.5 invariants are // inherited here, not re-implemented. return await base.ResolveStreamFormatAsync(entryKey, cancellationToken); } }