50 lines
2.4 KiB
C#
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);
|
|
}
|
|
}
|