Skip to content

fix: forward parse708captions and captionServices to the mp4 caption parser - #1611

Open
Essk wants to merge 1 commit into
mainfrom
fix/fmp4-caption-parser-options
Open

fix: forward parse708captions and captionServices to the mp4 caption parser#1611
Essk wants to merge 1 commit into
mainfrom
fix/fmp4-caption-parser-options

Conversation

@Essk

@Essk Essk commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

parse708captions and captionServices have never applied to fMP4/CMAF playback.

Both options are passed into the transmuxer worker's init config by SegmentLoader#createTransmuxer_ and are stored on MessageHandlers#options, which is why they work for MPEG-TS. But pushMp4Captions — the fMP4/CMAF caption path — constructed the mux.js mp4 CaptionParser with no options at all:

this.captionParser = new CaptionParser();
this.captionParser.init();

this.options was in scope and simply never forwarded. The practical effect: on a CMAF stream carrying both CEA-608 and CEA-708, parse708captions: false cannot suppress the duplicate cc708_1 text track, and captionServices cannot label or configure 708 services.

The README documents parse708captions unconditionally — "When set to false, 708 captions in the stream are not parsed and will not show up in text track lists or the captions menu" — with no fMP4 caveat, so this is a defect against documented behaviour rather than a feature request.

Dependency on mux.js

This change is a no-op until mux.js is bumped past the currently pinned 7.1.0. mux.js 7.1.0's CaptionParser.init(options) accepts an options argument but only reads isPartial from it, and creates its CaptionStream with no options — so the forwarded values are still discarded one layer down. That is a separate bug in mux.js, and fixed by the companion PR videojs/mux.js#452, which passes the options into new CaptionStream(options).

This PR deliberately does not bump mux.js. It should merge before or alongside the next mux.js bump, at which point the fix becomes effective. Forwarding the options now is safe: verified that mux.js 7.1.0 returns byte-identical caption output whether init() is called with no arguments or with this options object (isPartial is undefined either way, which takes the same flush branch as the previous false).

The combined fix was validated end-to-end in a patched player build against a live CMAF stream carrying both CEA-608 CC1 and CEA-708 Service 1: parse708captions: false suppressed the 708 track, true restored it, and captionServices SERVICE1 labelling was applied.

Specific Changes proposed

  • src/transmuxer-worker.js: forward parse708captions and captionServices from the worker's init options into CaptionParser#init() in pushMp4Captions. No guard is needed on this.options — both construction paths of MessageHandlers run its constructor, which sets this.options = options || {} before any message is dispatched.
  • test/transmuxer-worker.test.js: the local createTransmuxer helper now accepts option overrides, and a new test initialises the worker with parse708captions: false plus a captionServices map and asserts that mp4 caption parsing still yields the expected CEA-608 CC1 captions.

A note on test coverage

There is currently no way to write a test that fails before this change and passes after it, for two reasons:

  1. mux.js 7.1.0 discards the options regardless, so no behavioural difference is observable yet.
  2. test/segments/mp4Captions.mp4 — the only fMP4 caption fixture — contains CEA-608 CC1 data only, no CEA-708. Even with a fixed mux.js, it could not demonstrate 708 suppression.

The added test therefore covers the changed call site rather than the eventual behaviour: it verifies that supplying these options through the worker init does not disturb existing 608 parsing. A proper suppression test needs both the mux.js bump and a new fMP4 fixture containing CEA-708; happy to add that as a follow-up once the mux.js side lands. Flagging this explicitly rather than presenting the test as a regression guard it isn't.

Full suite passes locally: 1428 tests, 0 failures (Chrome Headless).

Requirements Checklist

  • Feature implemented / Bug fixed
  • If necessary, more likely in a feature request than a bug fix
  • Reviewed by Two Core Contributors

🤖 Generated with Claude Code

…parser

Both options reached the transmuxer worker's init config but were dropped
at the fMP4 CaptionParser call site, which was constructed with no options.
As a result parse708captions and captionServices only ever applied to
MPEG-TS streams, never to fMP4/CMAF.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.04%. Comparing base (a9f9d7a) to head (c90b3bc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1611      +/-   ##
==========================================
+ Coverage   84.00%   84.04%   +0.03%     
==========================================
  Files          44       44              
  Lines       11713    11713              
  Branches     2625     2625              
==========================================
+ Hits         9840     9844       +4     
+ Misses       1873     1869       -4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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