OGPlayer for the browser — built on web standards.
Release notes: https://ogplayer.tv/docs/reference/changelog/
OGPlayer is a product of Inverse DOO.
<video> element plays the media. HLS streams
are fed to it through hls.js using
Media Source Extensions; Safari plays HLS natively so hls.js steps aside
there. MPEG-DASH (an .mpd URL, or mimeType: "application/dash+xml")
goes through dash.js, also
on MSE — same API, events, menus and DRM config as HLS. Progressive MP4
plays directly.<og-player> that works identically in plain
HTML, React, Vue and Angular, with all styles isolated in a shadow DOM so
host-page CSS can't break the player (and vice versa).OGP2.… offline keys, verified with the browser's
built-in WebCrypto. apps patterns bind to the page hostname.<script type="module">
import { OGPlayer } from "ogplayer";
const player = new OGPlayer({ licenseKey: "OGP2...." });
document.querySelector("og-player").player = player;
player.addListener({
onStateChanged: (s) => console.log(s),
onProgress: (positionMs, bufferedMs, durationMs) => {},
});
player.load({
url: "https://example.com/stream.m3u8",
title: "My movie",
contentRatings: [{ age: "SIXTEEN" }, { descriptor: "FEAR" }],
sideloadedSubtitles: [{ url: "/subs/en.vtt", language: "en", label: "English", isDefault: true }],
});
</script>
<og-player style="width:100%;aspect-ratio:16/9"></og-player>
Overlays (watermarks, logos) use the nine named OverlaySlots — including the
clearance choreography around the controls and rating icons:
<og-player>
<img slot="top-end" src="/logo.png" width="90">
</og-player>
Custom action icons (max 8, inline in the top-end control row, hide with the controls):
el.config = {
customActions: [
{ svg: shareIconSvg, accessibilityLabel: "Share", onClick: () => share() },
],
};
While the player has focus (it takes focus on any click) the keys viewers
expect just work: Space/K play-pause, ←/→ and J/L seek by the seek
increment, ↑/↓ volume, M mute, F fullscreen, C subtitles, 0–9 jump
to 0–90 % on VOD, Home/End start/end (live edge on live), Esc leaves
fullscreen. Seek keys obey the live rules and stay inert during ads; modifier
chords and unmapped keys reach the page untouched. Turn it off with
el.config = { keyboardShortcuts: false } or change single keys with
el.config = { keymap: { m: null, p: "toggleMute" } }.
Every word of the chrome — labels, menu rows, ARIA labels, ad and error copy —
comes from el.config = { strings: { subtitles: "Ondertiteling", retry: "Opnieuw proberen" } },
a partial map over the English defaults with the same keys as every other
OGPlayer platform (the vertical feed's config takes strings too).
<og-player lang="nl"> or config.locale names language-coded tracks via
Intl.DisplayNames; nothing is taken from the browser's language.
API-only — no PiP button in the chrome; the host decides: await player.enterPip()
from a user gesture (resolves false where the browser offers no PiP or during an ad),
exitPip(), isInPip, and new OGPlayer({ autoEnterPip: true }) to let the browser
auto-enter where it offers that. Transitions: onPipChanged, og-pipchanged, PictureInPictureChanged.
npm install ogplayer — ESM module
with TypeScript types, hls.js pulled in as the npm dependency. dash.js ships
inside the package — nothing extra to install: the ESM bundles import it as
a separate chunk (dist/ogplayer.dash-*.js) on the first DASH item, so
HLS-only pages never download it, and dist/ogplayer.dash.global.js is the
same engine for <script> pages. A host that bundles its own dash.js can
pass it as new OGPlayer({ dashjs }). Publishing is one
scripts/release.sh <version> run (build, tests, tarball guard, npm publish).dist/ogplayer.global.js is a
single self-contained file (hls.js included) exposing window.OGPlayerSDK.
Served straight from the npm package via unpkg (or any CDN mirror of npm).
Pages that play DASH add dist/ogplayer.dash.global.js (the DASH engine)
with a second <script> tag — the TV global bundle takes the same file.ogplayer/tv (dist/ogplayer.tv.js ESM,
dist/ogplayer.tv.global.js global): the same API, compiled for the
Chromium 68/69 engines 2020+ Samsung Tizen and LG webOS TVs are frozen at,
without the vertical feed. TV behaviour is opt-in on either bundle:
<og-player input="remote"> (D-pad/OK/Back/media-key chrome),
platformProfile: "tv" (bounded buffers for set-top SoCs) and
licenseAppId (packaged apps run from file://). npm run build gates
the source against that ceiling (tsconfig.tv.json, scripts/tv-compat-check.mjs).<script src="https://unpkg.com/ogplayer@1.6.0/dist/ogplayer.global.js"></script>
<!-- smart TVs: dist/ogplayer.tv.global.js instead — packaged apps copy it in -->
<!-- DASH items: add dist/ogplayer.dash.global.js here (same folder) -->
<script>
const player = new OGPlayerSDK.OGPlayer();
document.querySelector("og-player").player = player;
player.load({ url: "…" });
</script>
Evergreen Chrome / Edge / Firefox / Safari 16+ (desktop & mobile). Every API used (MSE, custom elements, shadow DOM, WebCrypto, Fullscreen) has been baseline for years; no polyfills.
The TV bundle (ogplayer/tv) deliberately reaches further back: its floor is
the Chromium 68/69 of 2020 Samsung Tizen 5.5 and LG webOS 5 sets — syntax
lowered by esbuild, built-ins held to ES2018, DOM and CSS gated by the compat
check — so it runs on any TV browser of that generation or newer. No
polyfills there either.