Jump to content

HLS & DASH Streaming Implementation

HLS and DASH streaming are fully working in all modern browsers!

VidPly TYPO3 Extension Logo

Browser Support

HLS

BrowserImplementationStatus
Chrome / Edgehls.js 1.7.3 (vendored locally)Working
Firefoxhls.js 1.7.3Working
Desktop macOS Safarihls.js 1.7.3 (for parity with Chrome/Firefox: full quality menu, advanced caption styling)Working
iOS / iPadOS SafariNative HLS (<video> MSE is unavailable on iOS) — VidPly bridges native TextTrack API into the captions / transcript / quality UIWorking

DASH

BrowserImplementationStatus
Chrome / Edgedash.js 5.2.1 (modern UMD)Working
Firefoxdash.js 5.2.1Working
Safaridash.js 5.2.1Working

Technical Setup

HLS

1. hls.js Library

Loaded locally by mpc-vidply via Resources/Private/Partials/VidPly/Assets.html when an .m3u8 source is detected by the VidPlyProcessor:

Vendored fileResources/Public/JavaScript/hls.min.js
Pinned versionhls.js 1.7.3 (release build)
 

The vendored file is the published 1.7.3 release, not a local master-branch checkout of hls.js. When upgrading, copy the release artifact (npm / GitHub tag) into Resources/Public/JavaScript/hls.min.js.

 

VidPly's CDN fallback (used only when hls.js is not already on the page, e.g. standalone embeds):

 
cdn.jsdelivr.net/npm/hls.js@1.7.3/dist/hls.min.js
 

2. VidPly HLS Renderer

File: .libs/vidply/src/renderers/HLSRenderer.ts (standalone player source; shipped build is vendored under Resources/Public/JavaScript/vidply/)

The renderer self-decides whether to use hls.js or the browser's native HLS support:

  • On iOS / iPadOS (/iPad|iPhone|iPod/ UA, or iPad in desktop mode: MacIntel + maxTouchPoints > 1) MSE is unavailable, so the renderer uses native <video> HLS playback through HTML5Renderer.
  • On everything else (Chrome, Firefox, Edge, and desktop macOS Safari) it uses hls.js for full feature parity — quality menu, advanced caption styling and a consistent UX across browsers.

Native HLS bridge for iOS / iPadOS

When the native path is taken, the renderer attaches listeners to HTMLMediaElement.textTracks so that VidPly's caption menu, interactive transcript and quality menu still work:

 
this.media.textTracks.addEventListener('addtrack', checkTracks);
this.media.textTracks.addEventListener('removetrack', checkTracks);
this.media.addEventListener('loadedmetadata', checkTracks);
 

Each addtrack burst (one per subtitle rendition in the manifest) is debounced (~150 ms) before VidPly recalculates the visible captions UI, so the menu is built in a single render pass even for multi-language streams.

Live transcript / caption updates

The renderer listens for Hls.Events.SUBTITLE_FRAG_PROCESSED and re-emits a generic textcuesupdate event so the interactive transcript and live captions stay in sync as new subtitle fragments are loaded for long / live streams. The same event is emitted by the native iOS path on cuechange.

Live stream UI

With liveStream: 'auto' (the default in the bundled player), VidPly detects HLS live playlists and adjusts the control bar:

  • LIVE badge instead of total duration
  • Restart and playback speed hidden
  • Skip-forward and Go live only when the viewer is more than a few seconds behind the live edge
  • VOD HLS sources (finite playlists) keep normal seek controls — detection uses the level playlist's live flag, not transient Infinity duration during startup

Import live TV streams as Video media records so the HLS renderer is used even when the URL also matches audio domain allow-lists.

DASH

1. dash.js Library

Loaded locally by mpc-vidply via Resources/Private/Partials/VidPly/Assets.html when an .mpd source is detected:

Vendored fileResources/Public/JavaScript/dash.all.min.js
Pinned versiondash.js 5.2.1 (modern UMD build)

VidPly's CDN fallback (used only when dash.js is not already on the page):

 
cdn.jsdelivr.net/npm/dashjs@5.2.1/dist/modern/umd/dash.all.min.js
 

2. VidPly DASH Renderer

File: .libs/vidply/src/renderers/DASHRenderer.ts (standalone player source; shipped build is vendored under Resources/Public/JavaScript/vidply/)

Features:

  • Adaptive bitrate streaming with automatic quality switching
  • TTML/stpp subtitles (rendered natively by dash.js)
  • WebVTT subtitles (handled by VidPly's caption system + interactive transcript)
  • Quality selection UI integration
  • Robust teardown (dash.reset() then dash.destroy()) to avoid SourceBuffer errors on stream switching
  • Speed control hidden by default for DASH streams (hideSpeedForDash: true)

Content Security Policy

File: Configuration/ContentSecurityPolicies.php

Required CSP directives (shared by HLS and DASH):

 
'media-src'       => ['blob:', 'data:', 'https:'],
'worker-src'      => ['blob:'],
'connect-src'     => ['blob:', 'data:', 'https:'],
'script-src-elem' => ["'self'"],
 

Note: mpc-vidply ships hls.js and dash.js locally (Resources/Public/JavaScript/). The jsDelivr URLs mentioned elsewhere in this file are fallbacks for standalone VidPly embeds only — they are not required when using the TYPO3 extension with vendored scripts. Since v1.2.6 the extension CSP no longer whitelists cdn.jsdelivr.net for scripts by default.

 

Why these directives are needed:

  • media-src 'blob:' — hls.js / dash.js set a blob: URL on <video>.src while playing.
  • media-src 'data:' — some HLS variants embed init segments / WebVTT inline as data: URIs.
  • worker-src 'blob:' — hls.js / dash.js spawn workers from blob: URLs for demuxing.
  • connect-src 'https:' — fetching segments and manifests from arbitrary CDNs.
  • script-src-elem 'self' — vendored hls.min.js / dash.all.min.js from the extension.
  • script-src-elem 'https://cdn.jsdelivr.net' — only required if you rely on VidPly's CDN fallback instead of the vendored files.

Usage

Backend

HLS and DASH are not standalone media types. Instead, streaming sources are added as files within the Video or Audio media type.

Adding HLS/DASH to a Video record:

  1. Create VidPly media record with type Video
  2. Add a .m3u8 (HLS) or .mpd (DASH) file as a media source
  3. Optionally add progressive fallbacks (MP4, WebM) — the player will prefer DASH → HLS → progressive
  4. Optionally add local VTT files to override embedded captions/subtitles
  5. Add poster image (allowed formats: png, jpg, jpeg, webp, svg)
  6. Save

Adding HLS/DASH to an Audio record:

  1. Create VidPly media record with type Audio
  2. Add a .m3u8 (HLS) or .mpd (DASH) file as a media source
  3. Optionally add progressive fallbacks (MP3, OGG)
  4. Save

Frontend

  • Auto-detects stream type by MIME type or URL extension (.m3u8 for HLS, .mpd for DASH)
  • Source priority: DASH → HLS → progressive fallback
  • iOS / iPadOS uses native HLS but still surfaces captions, transcript and quality through VidPly's UI; all other browsers use hls.js. All browsers use dash.js for DASH.
  • Embedded captions/subtitles from HLS/DASH manifests are used by default; local VTT files act as optional overrides
  • Quality switching available (if stream has multiple levels)
  • A centered buffering spinner is shown automatically while the stream is buffering

Troubleshooting

Stream not playing:

  • Check URL is publicly accessible
  • Verify CORS headers on stream server (incl. Access-Control-Allow-Origin for Range requests)
  • Check CSP configuration (incl. blob:, data:, worker-src 'blob:')
  • Look for JavaScript console errors

No quality button:

  • Verify stream has multiple quality levels
  • Check hls.min.js / dash.all.min.js loads correctly (Network tab)
  • On iOS: quality renditions only show up if the manifest exposes them through native TextTracks — VidPly auto-picks them up via addtrack

Captions / transcript not showing on iOS HLS:

  • Verify the manifest contains #EXT-X-MEDIA:TYPE=SUBTITLES renditions
  • Captions appear shortly after loadedmetadata (debounced ~150 ms) — give the player a moment after pressing play

CSP errors:

  • Check ContentSecurityPolicies.php exists and is registered
  • Clear all caches
  • Verify blob: and data: are allowed for both media-src and connect-src

Performance

  • Adaptive bitrate — Automatically adjusts quality (HLS and DASH)
  • Buffer optimization — Smooth playback
  • CDN delivery — Standalone VidPly embeds can load pinned releases from jsDelivr; mpc-vidply ships hls.js 1.7.3 and dash.js 5.2.1 locally
  • Minimal overhead — hls.js / dash.js only load when an .m3u8 / .mpd source is actually used
  • Conditional loading — hls.js and dash.js are loaded independently based on detected source formats by the VidPlyProcessor
  • Native HLS on iOS — Avoids the cost of running hls.js on devices where it cannot run anyway, while still keeping the full VidPly UI through the native TextTrack bridge

Share page