Wire Opus end-to-end playback + Backfill-Opus action (Phase 18.5)

Player picks Opus when the browser can decode it and a sidecar exists (else lossless), injecting the sidecar before stream init; seek reuses the same format. Adds the Backfill-Opus bulk API endpoint + CMS action.
This commit is contained in:
daniel-c-harvey
2026-06-23 12:39:13 -04:00
parent dce5530890
commit 2bde4908d7
12 changed files with 961 additions and 1 deletions
@@ -88,4 +88,23 @@ public sealed class TrackFormatResolver
VaultConstants.TrackOpus, OpusTranscodeService.OpusSidecarKey(entryKey));
return sidecar?.Buffer;
}
/// <summary>
/// Reports whether <paramref name="entryKey"/> already has a complete Opus derive — both the audio bytes
/// AND the seek/setup sidecar present in the <c>track-opus</c> vault. The Backfill-Opus pass (18.5) uses
/// this to enqueue only tracks that are missing or half-derived (audio without sidecar = unseekable, so
/// treated as incomplete and re-derived). Both halves are required because the transcode stores them in
/// sequence and a sidecar-write failure leaves a track the delivery layer must not treat as Opus-ready.
/// </summary>
public async Task<bool> HasOpusAsync(string entryKey)
{
var audio = await _fileDatabase.LoadResourceAsync<AudioBinary>(
VaultConstants.TrackOpus, OpusTranscodeService.OpusAudioKey(entryKey));
if (audio is null)
return false;
var sidecar = await _fileDatabase.LoadResourceAsync<MediaBinary>(
VaultConstants.TrackOpus, OpusTranscodeService.OpusSidecarKey(entryKey));
return sidecar is not null;
}
}