Compress the export: WebCodecs in the browser, muxing here - #48
Merged
Conversation
The web export was 13 MB of raw PCM. It now encodes in the browser through WebCodecs — FLAC where a browser offers it, Opus at 256 kb/s otherwise, and the engine's WAV only where neither is available. WebCodecs hands back chunks and no container, so the FLAC concatenation and the Ogg Opus muxer are here, with a node test that demuxes the stream back out against the framing spec. Web-only by choice: Engine/ is untouched and s&box still writes WAV. Also: the playlist's per-row seek and export addressed a song by its index in its own station, which is 0 for every row of a shuffled line. They take the timeline position now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes PLAN row 99.
songToWavre-rendered the song and wrapped it raw, so one save was ~13 MB of 16-bit stereo. The web export now encodes in the browser.What it does
web/encode.js(new, DOM-free): probesAudioEncoder.isConfigSupportedonce per realm and picks FLAC if the browser encodes it, else Opus at 256 kb/s (application: audio,signal: music, complexity 10). Neither → the engine's WAV, so the button always does something. The probe also labels the button (⬇ .flac/⬇ .opus/⬇ .wav), rather than promising an extension the browser may not produce.description(fLaC+ STREAMINFO) followed by the frames; Opus gets a real page-by-page Ogg stream — OpusHead/OpusTags, lacing, granule positions at 48 kHz starting at the pre-skip, and Ogg's non-reflected CRC. The resolved seed rides along as aTITLEtag.OfflineAudioContextrather than a hand-rolled resampler.Web-only by choice:
Engine/is untouched, s&box keeps writing WAV throughWav.cs, and no wasm re-stage is involved (tools/bundle-stamp.sh checkis clean).Drive-by fix
The playlist's per-row seek and export passed
row.n— the song's index in its station, which under shuffle is0for every row. Both takerow.positionnow.Testing
test/encode.mjs(new, inmake test) demuxes the Ogg stream back out page by page against the framing spec: CRC checked against an independent bit-at-a-time implementation, headers, lacing (including the 255-multiple0terminator), the 255-segment page limit, packets byte-for-byte, granule monotonicity and pre-skip. FLAC's missing/bogus header is an error rather than a guess.test/{queue,palette,player,element}.mjsandtest/{smoke,page}.mjspass; the single-file bundler was rebuilt andtest/dist-single.mjspasses.Spec citations in
web/encode.jsare dated 2026-08-13 (WebCodecs + its FLAC/Opus registrations, RFC 7845, Ogg framing).