TOOL · DASH.JS MODULE

Dodge module for dash.js

An opt-in module in dash.js that adds the Dodge defense framework. Ship defended catalogs without forking the player or running anything server-side.

What it is

Dodge is implemented as an opt-in module in dash.jsdash.dodge.js. It is auto-detected at attachView() time, loaded as a separate script, and wired in via overrides registered through mediaPlayer.extend(). Ordinary dash.js playback is unchanged when Dodge is not loaded; when it is, behavior depends on the source URL.

The module is purely client-side. No server or network infrastructure changes are required beyond hosting a JSON configuration file (extended manifest) in place of, or alongside, an ordinary MPD. The extended manifest specifies so-called cycles, Dodge's generalized data unit that is downloaded instead of ordinary segments.

Operating modes

Scripts loadedSource URLResult
dash.all.min.js only Plain MPD Standard DASH, completely unchanged
dash.all.min.js + dash.dodge.min.js Plain MPD Standard DASH, graceful degradation (configurable via strict mode settings, see below)
dash.all.min.js + dash.dodge.min.js Extended manifest Dodge defense active

No API changes are needed. Pass an extended manifest URL instead of an MPD URL; everything else flows through the existing MediaPlayer.initialize() interface.

Quick start

<script src="dash.all.min.js"></script>
<script src="dash.dodge.min.js"></script>
<script>
  var player = dashjs.MediaPlayer().create();
  player.initialize(
    document.querySelector("#videoPlayer"),
    "content.exmfst.json",
    true
  );
</script>

Extended manifests

An extended manifest is a JSON file that wraps the original MPD and adds per-representation download schedules. ManifestLoader detects the JSON format, validates it via the DefenseRegistry singleton, and extracts the embedded MPD for DashParser processing. The defense schedules are stored separately and consulted by the DashHandler override during playback.

Each stream entry's label matches a representation ID from the MPD, and streams can optionally be scoped to a period index. Cycles in the data array specify a segment index, an optional range for partial downloads, and buffer/padding flags that control when pending data is buffered for playback (nothing is ever buffered unless the defense designer explicitly sets the buffer flag) and whether it is discarded as cover traffic, respectively. Padding can also be downloaded after playable content (trailing padding) to extend a video's apparent duration as seen by network observers.

This version of Dodge introduces two features beyond the PoPETS 2026 paper:

  • The buffer field on data cycles can be an array of segment indices (e.g., "buffer": [0, 1]) for selective buffering: pending data is held until the cycle with the buffer array completes, then all listed indices are buffered together.
  • Both data cycles and init cycles may carry a quality field (a representation ID string or numeric index) to fetch from a different representation in the same adaptation set. On data cycles, this lets defenses conceal a segment's true size by substituting a smaller version from an alternate quality level. On init cycles, it selects which representation's init segment is fetched and stored — downloading multiple init segments per representation is often necessary for playback of alternate representations.

For the full format reference, see extended manifest format.

Strict mode

The dodge.strictMode setting prevents accidental undefended playback. The four levels trade safety for flexibility — 'representation' is the default and is suitable for many use cases, while 'manifest' or 'max' is recommended where the presence of a defense is critical. Disabling strict mode entirely is possible but strongly discouraged: representations present in the embedded MPD but not covered in the extended manifest's streams array would be downloaded without any defense.

LevelBehavior
'representation' (default) Blocks undefended fragmented representations when an extended manifest is active; plain DASH still works.
'manifest' Same as 'representation' and refuses to play if the source URL is not an extended manifest (no vanilla MPDs).
'max' Same as 'manifest' and also rejects manifests containing thumbnails, non-fragmented text, or XLink references.
false Always falls back to vanilla dash.js (not recommended for production).

Recognizing their importance in the streaming ecosystem, Dodge does not disable DRM, CMCD, DVB reporting, or content steering. The nor/nrr fields are suppressed in CMCD requests (everything else is preserved); Dodge logs warnings when these features are used in strict mode so the defense designer can verify their behavior in context. Init segment caching should likely not be enabled and is off by default.

For the full validation rules, see extended manifest format → strict mode.

Tests and quality

The module includes 416 unit tests across 7 files plus a REQUIREMENTS.md traceability index mapping requirements to specific test cases. Existing dash.js tests are completely unaffected: the core hooks are no-op stubs by default with no control flow changes and no new dependencies.

Browser-based functional tests use Karma + Mocha + Chai to play real CDN-hosted video through the module in a headless browser and verify end-to-end behavior — defense activation, cycle-by-cycle traffic verification (segment index, byte range, buffer directive, padding flag), trailing phase mock buffer, quality override implementation, strict mode enforcement, multi-period transitions, and seeking during defense.

Bundle impact

dash.all.min.js grows by +3.1 KiB — the only additions to the base player are the small hooks and stubs needed for override registration. The Dodge module itself lives entirely in dash.dodge.min.js (70.0 KiB), which is loaded only when opted into. Build times are effectively unchanged.

Source

The module's source lives in the dash.js repository (src/dodge/), licensed under BSD-3-Clause by the DASH Industry Forum, the same license as the rest of dash.js. Integration is currently being reviewed in pull request #5021; once merged, the module ships with the regular dash.js distribution.

For discussion related to the dash.js module's development, we refer to the dash.js Google Group.