Apply stream-quality change live by reloading at current position
Finish the Settings "Apply" behavior so changing streaming quality mid-track
switches format immediately instead of only persisting the cookie for the next
play.
- SettingsMenu reads the AudioPlayerProvider cascade and threads the player into
StreamQualitySetting as an explicit parameter (the MudMenu panel portals to
MudPopoverProvider, outside the cascade scope, so a [CascadingParameter] there
lands null). StreamQualitySetting's Apply persists the cookie, then asks the
player to reload preserving position.
- Add a "load at timestamp" path to the player rather than restart-from-0-then-
seek (which audibly played the start and raced the just-started scheduler into
a crash). ReloadPreservingPositionAsync loads the track in the newly-resolved
format beginning DIRECTLY at the saved position:
* new JS resolveStreamOffset(position) resolves the file-absolute byte offset
with no playback/buffer state (Opus from its sidecar immediately; WAV after
a header probe),
* StartFromPositionAsync converges onto the existing seek/refill loop
(RunSegmentedStreamAsync with a non-null seekPosition) so the decoder
reinitializes for a header-less Range continuation and starts playback at
the target,
* ProbeHeaderAsync feeds the byte-0 segment to the decoder WITHOUT starting
playback until the WAV header parses (bounded by 256 KB); the probe buffers
are dropped by the continuation's clearForSeek, so nothing is audible.
- IStreamingPlayerService gains ReloadPreservingPositionAsync; the QueueService
test fake implements it.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
@using DeepDrftPublic.Client.Common
|
||||
@using DeepDrftPublic.Client.Controls.Settings
|
||||
@using DeepDrftPublic.Client.Services
|
||||
|
||||
@*
|
||||
The public-site Settings menu (Phase 18 wave 18.6, §4a). An app-bar trigger opening a MudMenu that renders
|
||||
@@ -31,10 +32,24 @@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
// The active player, cascaded by AudioPlayerProvider. SettingsMenu sits in the app bar inside the
|
||||
// provider, so it receives the cascade here — but the MudMenu PANEL content below is portaled to
|
||||
// <MudPopoverProvider> (outside the provider), so a cascade cannot reach it. We thread the player into
|
||||
// the setting as an explicit parameter instead: an explicit value captured in the item fragment flows
|
||||
// into portaled content fine, where a [CascadingParameter] would land null.
|
||||
[CascadingParameter] public IStreamingPlayerService? Player { get; set; }
|
||||
|
||||
// The settings-item list. Built once; adding a preference is appending one SettingsItem with its control
|
||||
// fragment — the menu body above renders whatever is here without knowing what each item is.
|
||||
private readonly List<SettingsItem> _items =
|
||||
[
|
||||
new SettingsItem("Streaming quality", @<StreamQualitySetting />)
|
||||
];
|
||||
// fragment — the menu body above renders whatever is here without knowing what each item is. The item
|
||||
// fragment reads Player at render time (when the menu opens), so it picks up the cascaded instance even
|
||||
// though the list itself is initialized before the cascade is set.
|
||||
private readonly List<SettingsItem> _items;
|
||||
|
||||
public SettingsMenu()
|
||||
{
|
||||
_items =
|
||||
[
|
||||
new SettingsItem("Streaming quality", @<StreamQualitySetting Player="@Player" />)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user