Openplayerjs
Lightweight HTML5 video/audio player with smooth controls and ability to play VAST/VMAP/SIMID/non-linear ads
Install / Use
/learn @openplayerjs/OpenplayerjsREADME
OpenPlayer.js

OpenPlayerJS — modular, plugin-first, easier to extend
This is a media player that uses all the goods of HTML5 video/audio elements to play the most popular media in MP4/MP3, HLS and also has the ability to play VMAP / VAST / non linear / companion ads
🎉🎉🎉 OpenPlayerJS v3 is finally here!! 🎉🎉🎉
v3is a radical internal rebuild that keeps most of the player familiar to use, but makes it much easier to extend (controls, plugins, engines) and much easier to maintain.✅ If you use UMD/CDN today, you can keep the classic
new OpenPlayerJS('id', options); player.init();flow with some minor changes — see UMD compatibility section below.
✨ What’s new in v3
- 🧩 Modular packages (install only what you need)
- 🔌 Plugin-first architecture (UI, Ads, Engines are plugins)
- 🎛️ Imperative UI extensions (
addElement,addControlviaextendControls) - 🧱 Cleaner separation of concerns (core vs UI vs engines/plugins)
- 🔥 Ads are no longer using Google IMA SDK: we have built our own with the support using Dailymotion's open source libraries. This was to support ads all around the world and avoid geoblocking
❌ Breaking Changes
- ❌ M(PEG)-DASH / FLV support dropped in favor of just supporting what browsers natively supports; if there is a need for them in the future, they can be added as separate bundles (like the hls one).
- ❌ Core quality/levels support dropped: API (
levels,level) — quality is now engine-specific, and will require to be built inside each one of them. - ❌ Several v2 "mega-config" options (moved to the right package: UI vs engine vs plugin); this approach can work when using UMD files, depending on what plugins are enabled.
To learn more about these changes, read MIGRATION.v3.md
📦 Packages
| Package | Purpose | Docs |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
| @openplayerjs/core | Player lifecycle, plugin system, engines, events | packages/core/README.md |
| @openplayerjs/player | Default UI + built-in controls + UI extension APIs | packages/player/README.md |
| @openplayerjs/hls | HLS engine (powered by hls.js) | packages/hls/README.md |
| @openplayerjs/ads | VAST/VMAP/non-linear/companion ads plugin + extension APIs | packages/ads/README.md |
| @openplayerjs/youtube (new) | YouTube media engine plugin using YouTube player API for iframe embeds | packages/youtube/README.md |
How to use it?
Verify Cross-Origin Resource Sharing (CORS)
When ads, captions, or streaming manifests are loaded from a different domain, the server must allow cross-origin requests. The typical error message looks like:
Access to fetch at 'https://cdn.example.com/video.m3u8' from origin 'https://myapp.com'
has been blocked by CORS policy.
To fix this on your server, add the following response headers:
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Credentials: true
Or, for public assets, allow all origins:
Access-Control-Allow-Origin: *
HTML setup
All you need in your markup is a standard <video> or <audio> element with a src attached to it. Add the controls and playsinline attributes for cross-browser compatibility, and optionally include <source> and <track> children:
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer.css" />
</head>
<body>
<video id="player" class="op-player__media" controls playsinline>
<source src="/path/to/video.mp4" type="video/mp4" />
<track kind="subtitles" src="/path/to/video.vtt" srclang="en" label="English" />
</video>
</body>
</html>
The
op-player__mediaclass applies the base player styles. The player's wrapper and controls are injected into the DOM automatically wheninit()is called.
Bandwidth optimization
To avoid downloading media before the user presses play, set preload="none" on the media element:
<video id="player" class="op-player__media" controls playsinline preload="none">
<source src="/video.mp4" type="video/mp4" />
</video>
Side effect: With
preload="none"the player cannot read the media's duration until playback starts. Provide thedurationoption if you want the UI to show the correct total time before the user presses play:new Core(media, { duration: 315 }); // 5 min 15 s or Infinity for live streamings
JavaScript / TypeScript (ESM — recommended)
Install the packages you need:
# Core + UI (covers MP4, MP3, OGG, and any other natively-supported format)
npm install @openplayerjs/core @openplayerjs/player
# Add HLS support (powered by hls.js)
npm install @openplayerjs/hls hls.js
# Add ads support (VAST / VMAP)
npm install @openplayerjs/ads
Then wire everything up:
import { Core } from '@openplayerjs/core';
import { createUI, buildControls } from '@openplayerjs/player';
import '@openplayerjs/player/style.css';
const media = document.querySelector<HTMLVideoElement>('#player')!;
const player = new Core(media, {
startTime: 0,
startVolume: 1,
startPlaybackRate: 1,
});
const controls = buildControls({
controls: {
top: ['progress'],
'center-left': ['play', 'duration', 'volume'],
'center-right': ['captions', 'fullscreen', 'settings'],
},
});
createUI(player, media, controls);
🌍 UMD compatibility (the “v2 way” still works)
If you prefer loading scripts from a CDN without a build step:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer.css" />
<video id="player" class="op-player__media" controls playsinline>
<source src="/path/to/video.mp4" type="video/mp4" />
</video>
<!-- Core + UI -->
<script src="https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer.js"></script>
<!-- Optional: HLS support -->
<script src="https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer-hls.js"></script>
<!-- Optional: Ads support -->
<script src="https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer-ads.js"></script>
<script>
const player = new OpenPlayerJS('player', {
startTime: 0,
startVolume: 1,
controls: {
top: ['progress'],
'center-left': ['play', 'duration', 'volume'],
'center-right': ['captions', 'fullscreen', 'settings'],
},
});
player.init();
</script>
📚 Legacy docs & changelog
- Old changelog: CHANGELOG.old.md
- Legacy docs folder (v2 style): docs
Built With
- Typescript - The Javascript for Pros.
Authors
- Rafael Miranda - rafa8626
See also the list of contributors who participated in this project.
Contributing
See CONTRIBUTING.md.
License
This project is licensed under the MIT License - see LICENSE for details.
