lib: remux and tag DASH (m4a) downloads - #176
Conversation
FLAC downloads are tagged in-flight by the FlacStreamTagger, but DASH downloads are written to disk as a raw concatenation of the CMAF segments: a fragmented MP4 with no tags, which most taggers and some players cannot handle. After a DASH download finishes, remux it into a standard progressive MP4 using mediabunny (packets are copied bit-identical, no re-encode) and write the same tags makeTags already builds (title, artists, album, cover art, etc.) with node-taglib-sharp. Both are pure JS, no ffmpeg or native binaries. The remux preserves the AAC encoder delay: the source edit list is replicated in the output (media_time + presentation duration), so the decoded audio stays sample-identical to the original stream. An empty udta/meta/ilst skeleton is also written because node-taglib-sharp crashes saving MP4 files that have no Apple ilst box. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Does finalizeDash need so many helpers, could it rely on another lib? And could you please post two mediainfo dumps of two different tracks showing the Metadata embed? Thanks |
The remux itself is fully delegated to mediabunny. The helpers only cover two things no current JS library does:
Alternatives I considered: mp4box.js can parse but can't write this either and is a much heavier dependency; ffmpeg is a binary. Both issues are upstreamable (an
Both downloaded in-client with SongDownloader (quality Low = AAC 320 → DASH), tagged by this PR's code path (lyrics tag embedded too, contents omitted from the dumps): mediainfo — Track 1 (Si Yo Fuera)mediainfo — Track 4 (Historia de Taxi) |
|
LGTM could you please bump patch version, I'll then merge |
|
Done - bumped to 1.14.2-beta. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Oops, sorry I meant minor version not patch version. Bump minor and I'll merge thx |
|
Done - 1.15.0-beta. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Flake Review Results for #176Available systems: aarch64-darwin, aarch64-linux, armv6l-linux, armv7l-linux, i686-linux, powerpc64le-linux, riscv64-linux, x86_64-darwin, x86_64-freebsd, x86_64-linux 🔄 Modified (2)
Note: Report truncated to fit GitHub's 65536 character comment limit. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-up to Inrixia/luna-plugins#239, integrating the functionality into the Luna lib as requested — this time validated end to end.
Problem
FLAC downloads are tagged in-flight by the FlacStreamTagger, but DASH downloads are written to disk as a raw concatenation of the CMAF segments: a fragmented MP4 with no metadata. Fragmented MP4s can't be tagged by common taggers (node-taglib-sharp crashes on them) and some players/DJ software handle them poorly.
Change
After a DASH download finishes,
MediaItem.download.native.tsnow calls a newfinalizeDashDownload()which:udta/meta/ilstskeleton — node-taglib-sharp (<= 6.0.3) crashes saving MP4s that have no Apple ilst box (Mpeg4File.savedereferences an emptyIsoUserDataBox's parentTree).makeTagsalready builds (title, artists, album, dates, cover art, ISRC, MusicBrainz ids, etc.) with node-taglib-sharp.Both dependencies are pure JS — no ffmpeg, no native binaries. The remux writes to a
.tmpand renames on success, so a failure never loses the raw download. The FLAC path is untouched.Validation
Offline, against real TIDAL DASH downloads (AAC 320):
ffmpeg -c copy -f hash).ffmpeg -c copyreference remux (encoder delay preserved, gapless intact).Live, in the client with the SongDownloader plugin set to High quality: downloads come out as standard
isom/mp41files with full tags and embedded 1280x1280 cover art.Generated with Claude Code