
Browser Support
HLS
| Browser | Implementation | Status |
|---|---|---|
| Chrome / Edge | hls.js 1.7.3 (vendored locally) | Working |
| Firefox | hls.js 1.7.3 | Working |
| Desktop macOS Safari | hls.js 1.7.3 (for parity with Chrome/Firefox: full quality menu, advanced caption styling) | Working |
| iOS / iPadOS Safari | Native HLS (<video> MSE is unavailable on iOS) — VidPly bridges native TextTrack API into the captions / transcript / quality UI | Working |
DASH
| Browser | Implementation | Status |
|---|---|---|
| Chrome / Edge | dash.js 5.2.1 (modern UMD) | Working |
| Firefox | dash.js 5.2.1 | Working |
| Safari | dash.js 5.2.1 | Working |
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 file | Resources/Public/JavaScript/hls.min.js |
| Pinned version | hls.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) intoResources/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 throughHTML5Renderer. - On everything else (Chrome, Firefox, Edge, and desktop macOS Safari) it uses
hls.jsfor 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
liveflag, not transientInfinityduration 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 file | Resources/Public/JavaScript/dash.all.min.js |
| Pinned version | dash.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()thendash.destroy()) to avoidSourceBuffererrors 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-vidplyships 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 whitelistscdn.jsdelivr.netfor scripts by default.
Why these directives are needed:
media-src 'blob:'—hls.js/dash.jsset ablob:URL on<video>.srcwhile playing.media-src 'data:'— some HLS variants embed init segments / WebVTT inline asdata:URIs.worker-src 'blob:'—hls.js/dash.jsspawn workers fromblob:URLs for demuxing.connect-src 'https:'— fetching segments and manifests from arbitrary CDNs.script-src-elem 'self'— vendoredhls.min.js/dash.all.min.jsfrom 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:
- Create VidPly media record with type Video
- Add a
.m3u8(HLS) or.mpd(DASH) file as a media source - Optionally add progressive fallbacks (MP4, WebM) — the player will prefer DASH → HLS → progressive
- Optionally add local VTT files to override embedded captions/subtitles
- Add poster image (allowed formats:
png,jpg,jpeg,webp,svg) - Save
Adding HLS/DASH to an Audio record:
- Create VidPly media record with type Audio
- Add a
.m3u8(HLS) or.mpd(DASH) file as a media source - Optionally add progressive fallbacks (MP3, OGG)
- Save
Frontend
- Auto-detects stream type by MIME type or URL extension (
.m3u8for HLS,.mpdfor 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 usedash.jsfor 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
Testing
ddev typo3 cache:flush
HLS test URLs:
- Apple Demo:
devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8 - Akamai Demo:
cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8
DASH test URLs:
Troubleshooting
Stream not playing:
- Check URL is publicly accessible
- Verify CORS headers on stream server (incl.
Access-Control-Allow-OriginforRangerequests) - 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.jsloads correctly (Network tab) - On iOS: quality renditions only show up if the manifest exposes them through native
TextTracks — VidPly auto-picks them up viaaddtrack
Captions / transcript not showing on iOS HLS:
- Verify the manifest contains
#EXT-X-MEDIA:TYPE=SUBTITLESrenditions - Captions appear shortly after
loadedmetadata(debounced ~150 ms) — give the player a moment after pressing play
CSP errors:
- Check
ContentSecurityPolicies.phpexists and is registered - Clear all caches
- Verify
blob:anddata:are allowed for bothmedia-srcandconnect-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-vidplyships hls.js 1.7.3 and dash.js 5.2.1 locally - Minimal overhead —
hls.js/dash.jsonly load when an.m3u8/.mpdsource is actually used - Conditional loading —
hls.jsanddash.jsare loaded independently based on detected source formats by theVidPlyProcessor - Native HLS on iOS — Avoids the cost of running
hls.json devices where it cannot run anyway, while still keeping the full VidPly UI through the nativeTextTrackbridge