ogplayer
v1.6.0
Published
OGPlayer video player SDK for the web and smart TVs — an <og-player> web component for browsers plus the ogplayer/tv bundle for Samsung Tizen and LG webOS: HLS, DRM (Widevine, PlayReady, FairPlay), Google IMA ads, playlists, a remote-control chrome and th
Maintainers
Readme
OGPlayer — web SDK
OGPlayer for the browser — built on web standards.
Release notes: https://ogplayer.tv/docs/reference/changelog/
OGPlayer is a product of Inverse DOO.
Under the hood
- Playback: the browser's
<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.mpdURL, ormimeType: "application/dash+xml") goes through dash.js, also on MSE — same API, events, menus and DRM config as HLS. Progressive MP4 plays directly. - UI: a custom element
<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). - Types: written in TypeScript — full type declarations ship with the package.
- License: signed
OGP2.…offline keys, verified with the browser's built-in WebCrypto.appspatterns bind to the page hostname.
Quick start
<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() },
],
};Keyboard shortcuts
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" } }.
Localisation
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.
Picture-in-picture
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.
How it ships
- npm (the web's Maven Central):
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, anddist/ogplayer.dash.global.jsis the same engine for<script>pages. A host that bundles its own dash.js can pass it asnew OGPlayer({ dashjs }). Publishing is onescripts/release.sh <version>run (build, tests, tarball guard,npm publish). - CDN script tag for no-build websites:
dist/ogplayer.global.jsis a single self-contained file (hls.js included) exposingwindow.OGPlayerSDK. Served straight from the npm package via unpkg (or any CDN mirror of npm). Pages that play DASH adddist/ogplayer.dash.global.js(the DASH engine) with a second<script>tag — the TV global bundle takes the same file. - Smart-TV bundle —
ogplayer/tv(dist/ogplayer.tv.jsESM,dist/ogplayer.tv.global.jsglobal): 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) andlicenseAppId(packaged apps run fromfile://).npm run buildgates the source against that ceiling (tsconfig.tv.json,scripts/tv-compat-check.mjs).
<script src="https://unpkg.com/[email protected]/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>Browser support
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.
