diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-24 21:08:34 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-24 21:08:34 +0200 |
| commit | f4ed927fa873133c5fed73fb7dd60e7747fc3dc2 (patch) | |
| tree | d126c5e505c342ee6b02aadc1e46b1a026c2a027 /docs | |
| parent | 75d1f8b93dfa0bffda3a59a6d143b06dcc3ca67f (diff) | |
| download | meshbay-f4ed927fa873133c5fed73fb7dd60e7747fc3dc2.tar.gz | |
feat(music): transcode WMA/Musepack to AAC so they actually play
Tagging and covers for these two formats landed already, but neither one
decodes in any mainstream browser's <audio> element at all — a real
library scan turned up 273 such files that would show up correctly in the
Music app and then simply fail on click. This closes that gap: the node
transcodes to AAC/M4A on request (a one-shot whole-file conversion, not
live-piped like video's fMP4 segments — an audio file is small enough that
streaming it buys nothing), caches the result under its own content hash
the same way a TMDB poster or a MusicBrainz cover is cached, and serves it
back through the ordinary file_req/chunk path. That path used to assume
anything in the media cache was thumbnail-sized (single chunk, always);
generalized it to slice a cached blob the same way a real file on disk
gets sliced, since a transcoded track can be several MB.
New MNP pair (`audio_transcode_req`/`_resp`, version bump to 0.9), shares
its concurrency cap with video's transcode pool rather than getting its
own — both are real ffmpeg processes on the same node. Every other audio
format is untouched: this only fires for .wma/.mpc, the two extensions
that need it.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/musicbay.md | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/docs/musicbay.md b/docs/musicbay.md index 2524948..20e391e 100644 --- a/docs/musicbay.md +++ b/docs/musicbay.md @@ -104,6 +104,23 @@ queued track so pressing "next" doesn't visibly wait — client-side only, a small in-memory blob cache keyed by file id, evicted once it falls off the front of the queue. +**Amendment (2026-08-24), one exception found against a real library:** WMA +and Musepack (.mpc) tag and cover perfectly well (enrich_audio.py reads +their real keys directly, since neither has mutagen's generic "easy" +wrapper), but decode in **no** mainstream browser's `<audio>` element at +all, no matter how the file is tagged — this is a codec-support gap, not a +metadata one. For these two extensions only, the player asks the node to +transcode to AAC/M4A first (`audio_transcode_req`/`_resp`, MNP 0.9), a +one-shot whole-file conversion (not live-piped like video's fMP4 segments — +an audio file is small enough that there is nothing to gain from streaming +it), cached under its own content hash the same way a TMDB poster or a +MusicBrainz cover is cached, and served back through the ordinary +file_req/chunk path (`_try_serve_thumbnail`, generalized to slice a +multi-chunk cached blob rather than assuming everything cached is +thumbnail-sized). Every other format still plays exactly as described +above — this is a narrow, extension-gated exception, not a reopening of the +simplification. + ### 2.3 The player is persistent across tabs — a shell-level addition Closing the Music tab must not stop the music, the same way switching to @@ -286,6 +303,21 @@ already covers most files, so building a correction UI before measuring whether it's needed would repeat the "designed and not needed" pattern this project's own history warns against. +### 4.3b New request/response: audio transcode (amendment, §2.2) + +``` +audio_transcode_req { file_id } +audio_transcode_resp { file_id, hash, size, mime } +``` + +`hash` is a cache key, not the file's own id — the client downloads it +through the ordinary `file_req`/chunk path exactly like a TMDB poster or +MusicBrainz cover, never a new download mechanism. Sent only for WMA and +Musepack (`.wma`/`.mpc`); every other format still downloads its own +`entry.id` directly, unchanged. Shares its concurrency cap with video's +transcode pool (`MAX_CONCURRENT_TRANSCODES`) rather than getting its own — +both are real ffmpeg processes on the same node. + ### 4.4 `ALLOWED_APPS` Add `"music"` to the frozenset in `webrtc_server.py`. `DEFAULT_APPS` stays |