Skip to content

Getting started

Havik Player plays Oddin's live esports streams — low-latency HLS with DRM — in any modern browser. You can integrate it three ways:

ModeBest forYou provideThe SDK owns
Iframe embedFastest drop-in, CMS pages, no build stepan iframe sloteverything, behind a postMessage API
Managed playerFull control of look & behavior in your appa <video> elementhls.js, LL-HLS tuning, DRM/EME, retries, controls
Bring your own playerExisting player stacks (hls.js, Shaka, wrapper)the player + <video>auth → catalog → playback resolution + DRM helpers

Whichever mode you pick, you need the same two things:

  • a match URN — identifies the stream, e.g. od:match:1234
  • a publishable api-keypk_live_… / pk_test_…, safe to ship in browser JavaScript because it only works from allow-listed origins

1. Get a key and a match

Onboarding is handled by Oddin: email havik-support@oddin.gg to get an api-key scoped to the tournaments you serve. Match URNs come from your odds-feed integration or from the SDK's catalog helpers.

2. Get your origins allow-listed

The api-key is publishable — its only guardrail is a server-side origin allow-list. Until your origins are onboarded, every request fails its CORS preflight and nothing plays. Send havik-support the exact origins you serve from, for both of:

  1. the key's AllowedOrigins — every origin the player runs on (and AllowedIframeParents for iframe embeds: the parent page's origin)
  2. the DRM service's CORS allow-list — same origins, or the license request dies in preflight and you get silent black video

Never ship a wildcard

A ["*"] allow-list disables the only guardrail on a publishable key. Don't ask for one in production.

Allow a few minutes for propagation. Include http://localhost:5173 (or your dev port) if you want local development to work.

3. Point at the right environment

baseUrl selects the Havik environment. Don't hard-code it deeper than a config value — serve it from your backend and keep the backend current from the endpoint directory:

EnvironmentAPI baseUrlHosted embed page
Integration (this site)https://feed-dev.oddin-video.gghttps://player-dev.oddin-video.gg/embed/
Productionpublished in the endpoint directoryannounced at onboarding

Test keys (pk_test_…) work against integration; production keys against production. A key on the wrong environment fails with UNAUTHORIZED.

Live service health for every Havik component is published at status-dev.oddin-video.gg (integration) and status.oddin-video.gg (production).

4. Install

For the iframe embed there is nothing to install. For the SDK modes:

bash
npm install @oddin-gg/havik-player
html
<!-- Exposes window.HavikPlayer. Pin an exact version in production. -->
<script src="https://cdn.jsdelivr.net/npm/@oddin-gg/havik-player@1/dist/havik-player.global.js"></script>

TypeScript definitions ship with the package — the types are the source of truth for the API surface.

5. First playback

ts
import { createPlayer } from '@oddin-gg/havik-player';

const player = await createPlayer({
  video: document.querySelector('video')!,
  baseUrl: 'https://feed-dev.oddin-video.gg',
  matchUrn: 'od:match:1234',
  credential: { apiKey: 'pk_test_…' },
  autoplay: true,
  muted: true, // required for reliable autoplay under browser sound policies
  waitForLive: true, // arm on an upcoming match, auto-play at go-live
});

player.on('statechange', (s) => console.log('state:', s));
player.on('error', (e) => console.error(e.code, e.httpStatus, e.message));

If the match hasn't started, waitForLive arms the player and it attaches the moment the stream goes live — see the managed player guide.

Browser support

Chrome, Firefox, and Edge play via hls.js + Widevine. Safari and iOS play via hls.js (ManagedMediaSource) or native HLS with FairPlay. Use detectDrmSupport() to check a browser before rendering the player — see the DRM guide.

Next steps

ISC licensed. Bundles hls.js (Apache-2.0).