Skip to content

Save's MP4 writer: hls.js's own code where it was unchanged, a fingerprint test for the rest - #631

Merged
Nawid3333 merged 1 commit into
mainfrom
refactor/mp4-writer-from-hls
Nov 7, 2026
Merged

Nawid3333 merged 1 commit into
mainfrom
refactor/mp4-writer-from-hls

Conversation

@Nawid3333

Copy link
Copy Markdown
Owner

Follow-up to the dependency audit: the one piece of other projects' code that no update workflow watched was the save's MP4 writer. MP4Generator.mjs started as a copy of hls.js's mp4-generator. This PR puts it on the normal hls.js update path instead of a separate watcher.

What changes

Compared function by function with hls.js 1.7.4, 15 of its functions were still hls.js's code, unchanged.

  • Taken from hls.js itself:
    • The video sample entries (avc1, hvc1) come from hls.js's own MP4, exported through one more name in the hls.js patch's single export line. hls2mp4 writes them and hands them over as the track's codecBuffer, the pass-through a DASH track already uses.
    • The fragment boxes (moof, traf, trun, mfhd, mvex, trex, mdat) were used only by the tests' fMP4 helper; it now uses hls.js's.
    • MP4Generator: 966 → 696 lines. hls.js's fixes to these now arrive with each hls.js update PR.
  • Checked against hls.js: mp4WriterUpstream.test.mjs fingerprints each hls.js function FastStream keeps its own version of. That's the containers, sample tables, tkhd, the audio entries and normalizePts, with comments and whitespace ignored. An hls.js update that changes one fails in that update's own PR (twice red → hold + a "Migration" issue), and the message says what to compare.
  • Guards:
    • The patch must export MP4.
    • No DASH save module may import hls.js. Importing it in MP4Generator itself would make every DASH save load hls.js's 1.2 MB, so the sample entry is built in hls2mp4, which has hls.js loaded already.

Why not take over all 15 unchanged functions: hls.js's functions call each other as MP4.x. Its minf or moov would write its own empty sample table and fragment header into a plain MP4 file.

Proof that nothing changes

  • Byte comparison: every box the writer returned across the 49 save unit tests (hls2mp4, dash2mp4, mp4merger, saveDownloadsAhead: H.264, HEVC, AAC, MP3, AC-3, fMP4) was hashed before and after. All 1,745 boxes FastStream's writer produces are byte-identical, including 54 whole file headers and 99 stsd. All 178 boxes now written by hls.js are there again unchanged.
  • Local checks: lint, typecheck, unit (3424) green. Save e2e: save-video, save-fmp4, archive-roundtrip, save-flow, save-transport, save-dialog-regression, all passed.
  • Reviews: glm and I designed this together (option B + fingerprints). glm then reviewed the diff and found no regression path.

🤖 Generated with Claude Code

…t is checked against it

MP4Generator.mjs started as a copy of hls.js's mp4-generator and became FastStream's
writer of a whole MP4 file. Of its functions, 15 were still hls.js 1.7.4's, unchanged.

- The video sample entries (avc1, hvc1) are hls.js's own now: hls2mp4 writes them with
  hls.js's MP4 (one more name in the patch's export line) and hands them over as the
  track's codecBuffer, as a DASH track's already was. The fragment boxes (moof, traf,
  trun, mfhd, mvex, trex, mdat), used only by the tests' fMP4 helper, come from hls.js
  too. MP4Generator: 966 -> 696 lines. Not imported there: a DASH save would load hls.js.
- tests/unit/mp4WriterUpstream.test.mjs fingerprints (comments and whitespace left out)
  each hls.js function FastStream keeps its own version of, and normalizePts: an hls.js
  update that changes one fails in its own pull request, saying what to compare. It also
  checks the export and that no DASH save module imports hls.js.

Saved files are byte for byte the same: every box the writer returned across the 49 save
tests (H.264, HEVC, AAC, MP3, AC-3, fMP4) hashed before and after, 1,745 identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Nawid3333
Nawid3333 merged commit d2ea94b into main Nov 7, 2026
23 checks passed
@Nawid3333
Nawid3333 deleted the refactor/mp4-writer-from-hls branch November 7, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant