Files
deepdrft/DeepDrftPublic.Client/Services/PreferenceAwareStreamingPlayerService.cs

50 lines
2.4 KiB
C#

using DeepDrftModels.Enums;
using DeepDrftPublic.Client.Clients;
using DeepDrftPublic.Client.Common;
using Microsoft.Extensions.Logging;
namespace DeepDrftPublic.Client.Services;
/// <summary>
/// The production player that honours the listener's streaming-quality preference (Phase 18 wave 18.6).
/// Extends <see cref="StreamingAudioPlayerService"/> through the single deliberately-overridable seam,
/// <see cref="StreamingAudioPlayerService.ResolveStreamFormatAsync"/>, so the rest of the streaming stack
/// (seek, telemetry, the seek-beyond-buffer format reuse) is inherited verbatim.
/// <para>
/// The override is one branch: a <see cref="StreamQuality.Lossless"/> preference returns
/// <see cref="AudioFormat.Lossless"/> immediately; anything else falls through to <c>base</c>, 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.
/// </para>
/// </summary>
public class PreferenceAwareStreamingPlayerService : StreamingAudioPlayerService
{
private readonly PublicSiteSettings _settings;
public PreferenceAwareStreamingPlayerService(
AudioInteropService audioInterop,
TrackMediaClient trackMediaClient,
ILogger<StreamingAudioPlayerService> logger,
PublicSiteSettings settings)
: base(audioInterop, trackMediaClient, logger)
{
_settings = settings;
}
protected override async Task<AudioFormat> 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);
}
}