Commit Graph

8 Commits

Author SHA1 Message Date
daniel-c-harvey d686fe48ce 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.
2026-06-24 22:55:03 -04:00
daniel-c-harvey 2b42e01cd0 feat(player): add IQueueService orchestrating album playback above the single-slot player (P11 11.F)
Queue owns ordered tracks, current index, skip-fwd/back, and auto-advance via the player's TrackEnded hook; binds through Attach (no ctor growth, no service-locator). Player-bar skip controls; empty-queue play unchanged. Adds QueueService unit tests.
2026-06-16 00:04:44 -04:00
daniel-c-harvey 0d4ef369b9 feat: Stream Now instant-play of a random track from the nav button 2026-06-07 18:33:08 -04:00
daniel-c-harvey c83b132522 feature: Embed Frame Player 2026-06-06 15:43:09 -04:00
daniel-c-harvey 8de7342352 Replace MudSlider seekbar with WaveformSeeker loudness-waveform control
DOM bar chart with clip-overlay progress split; pointer-capture drag;
WaveformProfile fetched on load (fire-and-forget, cancellable); flat
fallback when no profile; small lazily-loaded waveformSeeker.js for
getBoundingClientRect and setPointerCapture.
2026-06-05 17:35:11 -04:00
daniel-c-harvey 7d49c64a5d fix: enable player controls on load, clear track selection on stop and end-of-track
Add StateChanged multicast event to IPlayerService so AudioPlayerBar and TracksView
re-render themselves without relying on the IsFixed cascade re-render path. Clear
_selectedTrack in TracksView when IsLoaded drops (stop, unload, end-of-track). Set
IsLoaded=false in OnPlaybackEndCallback so end-of-track triggers the same clear path.
Add JS-module readiness probe in AudioInteropService; delete dead TS and buffered C#
path; consolidate GetPlayIcon/FormatTime helpers; fix misleading minimize dock icon.
2026-06-03 14:30:15 -04:00
Daniel Harvey 4351302a25 Flip ITrackService/TrackManager to DTO output; TrackConverter is the sole entity<->DTO path across all consumers 2026-05-25 11:35:04 -04:00
Daniel Harvey e5b4a79727 refactor(split): rename DeepDrftWeb -> DeepDrftPublic and DeepDrftWeb.Client -> DeepDrftPublic.Client (Phase 4) 2026-05-19 23:06:16 -04:00