@oddin-gg/havik-player 2.11.1 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -7
- package/dist/havik-player.global.js +18 -18
- package/dist/havik-player.global.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -16
- package/dist/index.d.ts +38 -16
- package/dist/index.js +404 -339
- package/dist/index.js.map +1 -1
- package/docs/API.md +57 -52
- package/embed/index.html +1 -1
- package/examples/vanilla.html +1 -1
- package/package.json +1 -1
package/docs/API.md
CHANGED
|
@@ -219,39 +219,39 @@ player.on('error', (e) => console.error(e.code, e.httpStatus, e.message));
|
|
|
219
219
|
|
|
220
220
|
#### `CreatePlayerOptions`
|
|
221
221
|
|
|
222
|
-
| Option | Type | Default | Description
|
|
223
|
-
| --------------------- | --------------------------------------- | -------------------------------- |
|
|
224
|
-
| `video` | `HTMLVideoElement` | — | **Required.** The element the SDK will control.
|
|
225
|
-
| `env` | `'integration' \| 'production'` | — | **Required unless `baseUrl` is given.** Which Oddin environment to play against. Preferred: the host is correct by construction, and so is everything derived from it (the SSE events host, the QoE beacons host).
|
|
226
|
-
| `baseUrl` | `string` | — | **Required unless `env` is given.** API base URL, e.g. `https://feed-dev.oddin-video.gg`. Use for a deployment the named environments do not cover: your own CDN or gateway fronting the streams API, the CN plane, or a pinned build that must outlive a domain change. Passing both `env` and `baseUrl` — or neither — is a compile error in TypeScript and throws at runtime in JavaScript.
|
|
227
|
-
| `matchUrn` | `string` | — | **Required.** The match to play, e.g. `od:match:1234`.
|
|
228
|
-
| `credential` | [`CredentialSource`](#credentialsource) | — | **Required.** Your api‑key (or a function returning one).
|
|
229
|
-
| `autoplay` | `boolean` | `true` | Start playback once ready. With `false`, the player holds in a pre-play `'paused'` state (poster + play card, no spinner) and fetches no media and no DRM license until the first `play()`. On the hls.js engine the manifest is still parsed pre-play, so `'ready'` and the track lists keep working; the native (Safari) engine defers all fetching and emits `'ready'` at attach instead. Note: if a programmatic `play()` is policy-blocked (`autoplayblocked`), the loader keeps warming the buffer — media and DRM traffic flows from that kick, not from a viewer gesture.
|
|
230
|
-
| `muted` | `boolean` | `false` | Mute the element. Set `true` for reliable autoplay under browser sound policies.
|
|
231
|
-
| `controls` | `'custom' \| 'native' \| 'none'` | `'custom'` | Which controls to render. See [Controls & theming](#controls--theming).
|
|
232
|
-
| `theme` | [`Partial<HavikTheme>`](#haviktheme) | Oddin brand | Re-skin the custom control bar (ignored unless `controls: 'custom'`). See [Controls & theming](#controls--theming).
|
|
233
|
-
| `statusOverlays` | `boolean` | `true` | Branded full-bleed cards for the stopped/pre-play states (ended, fatal error, pre-play, armed-waiting) instead of a frozen frame + a dead play button. Themed via the control-bar tokens + `theme.logoUrl`. Set `false` to render your own UI from the `ended`/`error` events. Ignored unless `controls: 'custom'`.
|
|
234
|
-
| `endedMessage` | `string` | "This stream has ended" | Message on the end-of-stream card.
|
|
235
|
-
| `interruptedMessage` | `string` | "Reconnecting — please stand by" | Message shown **instead of** `endedMessage` when the server reports the stream stopped but the match is still running (`endedReason: 'interrupted'`, an ingest outage that outlived the bridge's hold). The player rejoins automatically when the stream returns **while `rejoinOnLive` is on** (the default); override this wording if you disable auto-rejoin, since nothing will re-attach on its own.
|
|
236
|
-
| `errorMessage` | `string` | the error's message | Message on the fatal-error card (otherwise the error's own message).
|
|
237
|
-
| `waitForLive` | [`WaitForLive`](#waitforlive) | — | Arm on an upcoming match and auto‑attach at go‑live.
|
|
238
|
-
| `lowLatency` | `'auto' \| boolean` | `'auto'` | `'auto'` lets the player decide from the manifest.
|
|
239
|
-
| `engine` | `'auto' \| 'hls' \| 'native'` | `'auto'` | `'auto'` prefers hls.js wherever it is supported, including modern Safari/iOS via ManagedMediaSource, and falls back to native HLS otherwise.
|
|
240
|
-
| `userId` | `string` | — | Optional viewer id (sent as `X-User-Id` on license requests).
|
|
241
|
-
| `debug` | `boolean` | `false` | Turn on hls.js's internal console logging: fragment/part scheduling, ABR switches, EME key sessions and license traffic. For diagnosing a playback problem with Oddin support; leave it off in production (it logs on every fragment, and the EME lines include license request/response metadata). hls.js engine only. `hlsConfig.debug` still wins if you set both.
|
|
242
|
-
| `hlsConfig` | `Partial<HlsConfig>` | — | Escape hatch for advanced hls.js tuning.
|
|
243
|
-
| `statsIntervalMs` | `number` | `2000` | How often `'stats'` is emitted.
|
|
244
|
-
| `licenseRefreshMs` | `number` | `480000` (8 min) | How often to silently re-resolve playback so the signed DRM license URL the player would use next stays inside its signature lifetime (~10 min). Refreshes the URL, not the license: it cannot extend a license the CDM already holds, so a session that outlasts its license still ends with a fatal [`DRM_CLIENT`](#errors) error. `0` disables.
|
|
245
|
-
| `poster` | `string` | — | Poster image shown before playback starts.
|
|
246
|
-
| `startLevel` | `number` | `-1` | Initial rendition index (`-1` = auto). With auto, ABR starts on a conservative, sustainable rendition (~360p) and ramps up as bandwidth allows; see [Low‑latency & adaptive bitrate](#low-latency--adaptive-bitrate).
|
|
247
|
-
| `maxBitrate` | `number` | — | Cap ABR to renditions at/below this bitrate (bps).
|
|
248
|
-
| `liveLatencyTarget` | `number` | `2` | Target live‑edge latency in seconds (hls.js `liveSyncDuration`). The player derives a matching latency **ceiling** internally and catches up at 1.5×, so this is the only live‑latency knob you need. Lower = closer to live but more rebuffer‑prone. Live/LL only.
|
|
249
|
-
| `snapToLiveOnRefocus` | `boolean` | `true` | Snap to the live edge when a backgrounded tab is refocused while far behind. Live/LL only.
|
|
250
|
-
| `mediaDuringKey` | `boolean` | `true` | DRM cold start: download the first init segment and parts while the first key is still being acquired, instead of after it. Bytes reach hls.js only when it asks for them; only the network time moves off the critical path (~0.5 s on Widevine LL-HLS). Ignored on clear streams and when `hlsConfig.fLoader` is set. Pass `false` to opt out.
|
|
251
|
-
| `liveStateEvents` | `boolean` | `true` | Use the push-based **live-state SSE** channel for go-live and end-of-stream (see [Live state](#live-state-sse)). Graceful: falls back to polling if the endpoint is unreachable. Set `false` to disable.
|
|
252
|
-
| `rejoinOnLive` | `boolean` | `true` | Rejoin automatically when a stream that ended comes back live. An ingest outage longer than the bridge's reconnect grace recreates the session under a **new manifest URL** (the old playlist freezes at HTTP 200), so the player keeps the live-state subscription open after `ended` (until `gone`) and re-arms on a pushed `live`. Set `false` to keep `ended` terminal. Needs `liveStateEvents`.
|
|
253
|
-
| `analytics` | `boolean \| { endpoint?: string }` | `true` | QoE beacons. Active only when the playback response carries a server-minted `sid`.
|
|
254
|
-
| `eventsBaseUrl` | `string` | derived | Override the SSE endpoint base. Default: `baseUrl` with the host prefixed by `events.` (e.g. `feed.<d>` → `events.<d>`).
|
|
222
|
+
| Option | Type | Default | Description |
|
|
223
|
+
| --------------------- | --------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
224
|
+
| `video` | `HTMLVideoElement` | — | **Required.** The element the SDK will control. |
|
|
225
|
+
| `env` | `'integration' \| 'production'` | — | **Required unless `baseUrl` is given.** Which Oddin environment to play against. Preferred: the host is correct by construction, and so is everything derived from it (the SSE events host, the QoE beacons host). |
|
|
226
|
+
| `baseUrl` | `string` | — | **Required unless `env` is given.** API base URL, e.g. `https://feed-dev.oddin-video.gg`. Use for a deployment the named environments do not cover: your own CDN or gateway fronting the streams API, the CN plane, or a pinned build that must outlive a domain change. Passing both `env` and `baseUrl` — or neither — is a compile error in TypeScript and throws at runtime in JavaScript. |
|
|
227
|
+
| `matchUrn` | `string` | — | **Required.** The match to play, e.g. `od:match:1234`. |
|
|
228
|
+
| `credential` | [`CredentialSource`](#credentialsource) | — | **Required.** Your api‑key (or a function returning one). |
|
|
229
|
+
| `autoplay` | `boolean` | `true` | Start playback once ready. With `false`, the player holds in a pre-play `'paused'` state (poster + play card, no spinner) and fetches no media and no DRM license until the first `play()`. On the hls.js engine the manifest is still parsed pre-play, so `'ready'` and the track lists keep working; the native (Safari) engine defers all fetching and emits `'ready'` at attach instead. Note: if a programmatic `play()` is policy-blocked (`autoplayblocked`), the loader keeps warming the buffer — media and DRM traffic flows from that kick, not from a viewer gesture. |
|
|
230
|
+
| `muted` | `boolean` | `false` | Mute the element. Set `true` for reliable autoplay under browser sound policies. |
|
|
231
|
+
| `controls` | `'custom' \| 'native' \| 'none'` | `'custom'` | Which controls to render. See [Controls & theming](#controls--theming). |
|
|
232
|
+
| `theme` | [`Partial<HavikTheme>`](#haviktheme) | Oddin brand | Re-skin the custom control bar (ignored unless `controls: 'custom'`). See [Controls & theming](#controls--theming). |
|
|
233
|
+
| `statusOverlays` | `boolean` | `true` | Branded full-bleed cards for the stopped/pre-play states (ended, fatal error, pre-play, armed-waiting) instead of a frozen frame + a dead play button. Themed via the control-bar tokens + `theme.logoUrl`. Set `false` to render your own UI from the `ended`/`error` events. Ignored unless `controls: 'custom'`. |
|
|
234
|
+
| `endedMessage` | `string` | "This stream has ended" | Message on the end-of-stream card. |
|
|
235
|
+
| `interruptedMessage` | `string` | "Reconnecting — please stand by" | Message shown **instead of** `endedMessage` when the server reports the stream stopped but the match is still running (`endedReason: 'interrupted'`, an ingest outage that outlived the bridge's hold). The player rejoins automatically when the stream returns **while `rejoinOnLive` is on** (the default); override this wording if you disable auto-rejoin, since nothing will re-attach on its own. |
|
|
236
|
+
| `errorMessage` | `string` | the error's message | Message on the fatal-error card (otherwise the error's own message). |
|
|
237
|
+
| `waitForLive` | [`WaitForLive`](#waitforlive) | — | Arm on an upcoming match and auto‑attach at go‑live. |
|
|
238
|
+
| `lowLatency` | `'auto' \| boolean` | `'auto'` | `'auto'` lets the player decide from the manifest. |
|
|
239
|
+
| `engine` | `'auto' \| 'hls' \| 'native'` | `'auto'` | `'auto'` prefers hls.js wherever it is supported, including modern Safari/iOS via ManagedMediaSource, and falls back to native HLS otherwise. |
|
|
240
|
+
| `userId` | `string` | — | Optional viewer id (sent as `X-User-Id` on license requests). |
|
|
241
|
+
| `debug` | `boolean` | `false` | Turn on hls.js's internal console logging: fragment/part scheduling, ABR switches, EME key sessions and license traffic. For diagnosing a playback problem with Oddin support; leave it off in production (it logs on every fragment, and the EME lines include license request/response metadata). hls.js engine only. `hlsConfig.debug` still wins if you set both. |
|
|
242
|
+
| `hlsConfig` | `Partial<HlsConfig>` | — | Escape hatch for advanced hls.js tuning. |
|
|
243
|
+
| `statsIntervalMs` | `number` | `2000` | How often `'stats'` is emitted. |
|
|
244
|
+
| `licenseRefreshMs` | `number` | `480000` (8 min) | How often to silently re-resolve playback so the signed DRM license URL the player would use next stays inside its signature lifetime (~10 min). Refreshes the URL, not the license: it cannot extend a license the CDM already holds, so a session that outlasts its license still ends with a fatal [`DRM_CLIENT`](#errors) error. `0` disables. |
|
|
245
|
+
| `poster` | `string` | — | Poster image shown before playback starts. |
|
|
246
|
+
| `startLevel` | `number` | `-1` | Initial rendition index (`-1` = auto). With auto, ABR starts on a conservative, sustainable rendition (~360p) and ramps up as bandwidth allows; see [Low‑latency & adaptive bitrate](#low-latency--adaptive-bitrate). |
|
|
247
|
+
| `maxBitrate` | `number` | — | Cap ABR to renditions at/below this bitrate (bps). |
|
|
248
|
+
| `liveLatencyTarget` | `number` | `2` | Target live‑edge latency in seconds (hls.js `liveSyncDuration`). The player derives a matching latency **ceiling** internally and catches up at 1.5×, so this is the only live‑latency knob you need. Lower = closer to live but more rebuffer‑prone. Live/LL only. |
|
|
249
|
+
| `snapToLiveOnRefocus` | `boolean` | `true` | Snap to the live edge when a backgrounded tab is refocused while far behind. Live/LL only. |
|
|
250
|
+
| `mediaDuringKey` | `boolean` | `true` | DRM cold start: download the first init segment and parts while the first key is still being acquired, instead of after it. Bytes reach hls.js only when it asks for them; only the network time moves off the critical path (~0.5 s on Widevine LL-HLS). Ignored on clear streams and when `hlsConfig.fLoader` is set. Pass `false` to opt out. |
|
|
251
|
+
| `liveStateEvents` | `boolean` | `true` | Use the push-based **live-state SSE** channel for go-live and end-of-stream (see [Live state](#live-state-sse)). Graceful: falls back to polling if the endpoint is unreachable. Set `false` to disable. |
|
|
252
|
+
| `rejoinOnLive` | `boolean` | `true` | Rejoin automatically when a stream that ended comes back live. An ingest outage longer than the bridge's reconnect grace recreates the session under a **new manifest URL** (the old playlist freezes at HTTP 200), so the player keeps the live-state subscription open after `ended` (until `gone`) and re-arms on a pushed `live`. Set `false` to keep `ended` terminal. Needs `liveStateEvents`. |
|
|
253
|
+
| `analytics` | `boolean \| { endpoint?: string }` | `true` | QoE beacons. Active only when the playback response carries a server-minted `sid`. **havik-streams v0.10.0+ names the beacons host in that response, and it is used whatever `baseUrl` is**; it also wins over `{ endpoint }` (a differing value is ignored with one `console.warn`). Against an older server the host is `{ endpoint }` if given, else derived from `baseUrl` by hostname convention (`feed[-dev].<domain>` → `beacons[-dev].<domain>`); there, **if `baseUrl` is not a `feed` host nothing derives and beacons are disabled** — the SDK then logs one `console.warn` naming the host and emits a non-fatal [`warning`](#player-events) event carrying the same sentence. Recovery: pass `{ endpoint: 'https://beacons[-dev].<domain>' }`. Pass `false` to opt out deliberately (no warning). |
|
|
254
|
+
| `eventsBaseUrl` | `string` | derived | Override the SSE endpoint base. Default: `baseUrl` with the host prefixed by `events.` (e.g. `feed.<d>` → `events.<d>`). |
|
|
255
255
|
|
|
256
256
|
### Low-latency & adaptive bitrate
|
|
257
257
|
|
|
@@ -379,7 +379,7 @@ Notes:
|
|
|
379
379
|
| `paused` | `void` | Playback is paused. |
|
|
380
380
|
| `ended` | `EndedReason \| undefined` | The live stream ended; playback stops and the last frame is kept. The payload says **why**: `'interrupted'` (the match is still running, and its stream dropped, so show "reconnecting", **never** "ended"; the player rejoins by itself) or `'match_ended'` (a real end). `undefined` = the end came from the HLS staleness watchdog, or a server predating the field; treat it as a real end. Fires **again** with `'match_ended'` if an interruption later turns out to be the end, so don't latch on the first one. Also readable any time as `player.endedReason`. |
|
|
381
381
|
| `error` | [`PlaybackError`](#playbackerror) | A fatal error occurred (playback stopped). |
|
|
382
|
-
| `warning` | [`PlaybackError`](#playbackerror) | A non-fatal condition (e.g. FairPlay passthrough, a failed license refresh,
|
|
382
|
+
| `warning` | [`PlaybackError`](#playbackerror) | A non-fatal condition (e.g. FairPlay passthrough, a failed license refresh, **QoE beacons disabled because the endpoint could not be derived** — see [`analytics`](#createplayeroptions) — or **QoE beacons refused by the page's Content-Security-Policy**, naming the origin to add to `connect-src`). Playback continues. |
|
|
383
383
|
| `autoplayblocked` | `void` | The browser blocked autoplay (`NotAllowedError`). Show a tap-to-play / tap-to-unmute affordance, then call `player.play()` from the gesture. |
|
|
384
384
|
| `qualitychange` | `number` | Active rendition changed (level index, `-1` = auto). |
|
|
385
385
|
| `audiotrackchange` | `number` | Active audio track changed (track id). |
|
|
@@ -763,14 +763,14 @@ const watcher = watchStatus({
|
|
|
763
763
|
|
|
764
764
|
#### `WatchStatusOptions`
|
|
765
765
|
|
|
766
|
-
| Option | Type | Default | Description
|
|
767
|
-
| ------------ | --------------------------------------- | ------- |
|
|
768
|
-
| `baseUrl` | `string` | — | **Required.**
|
|
769
|
-
| `matchUrn` | `string` | — | **Required.**
|
|
770
|
-
| `credential` | [`CredentialSource`](#credentialsource) | — | **Required.**
|
|
771
|
-
| `onChange` | `(status: MatchStatus) => void` | — | **Required.** Fired on first read, then on any status, teams or start change.
|
|
772
|
-
| `onError` | `(err: PlaybackError) => void` | — | Fired on a poll error; polling continues.
|
|
773
|
-
| `intervalMs` | `number` | `10000` | Poll interval (floored at `2000`).
|
|
766
|
+
| Option | Type | Default | Description |
|
|
767
|
+
| ------------ | --------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
768
|
+
| `baseUrl` | `string` | — | **Required.** |
|
|
769
|
+
| `matchUrn` | `string` | — | **Required.** |
|
|
770
|
+
| `credential` | [`CredentialSource`](#credentialsource) | — | **Required.** |
|
|
771
|
+
| `onChange` | `(status: MatchStatus) => void` | — | **Required.** Fired on first read, then on any status, teams or start change. |
|
|
772
|
+
| `onError` | `(err: PlaybackError) => void` | — | Fired on a poll error; polling continues, except on `NOT_FOUND`, `GONE` or `INVALID_URN`: the watcher stops itself and this is its last call. |
|
|
773
|
+
| `intervalMs` | `number` | `10000` | Poll interval (floored at `2000`). |
|
|
774
774
|
|
|
775
775
|
<a id="live-state-sse"></a>
|
|
776
776
|
|
|
@@ -954,16 +954,16 @@ api-key. Otherwise (dev/demo) config comes from the query string. The postMessag
|
|
|
954
954
|
**fails closed**: with no `parentOrigin`, the embed neither accepts commands nor posts
|
|
955
955
|
events.
|
|
956
956
|
|
|
957
|
-
| Field | Type | Default | Description
|
|
958
|
-
| -------------- | ---------------------------------- | ------- |
|
|
959
|
-
| `baseUrl` | `string` | — | **Required.** API base URL.
|
|
960
|
-
| `matchUrn` | `string` | — | **Required.** Match to play.
|
|
961
|
-
| `apiKey` | `string` | — | **Required.** Inject server‑side in production; query param is dev‑only.
|
|
962
|
-
| `parentOrigin` | `string` | — | Origin to post events to and accept commands from. **Set this in production** (`mountEmbed` sets it automatically). When absent, the iframe posts to `*` and skips the inbound origin check.
|
|
963
|
-
| `autoplay` | `boolean` | `true` | Start playback once ready.
|
|
964
|
-
| `muted` | `boolean` | `true` | Start muted (recommended for autoplay).
|
|
965
|
-
| `waitForLive` | [`WaitForLive`](#waitforlive) | `true` | Arm and auto‑play at go‑live.
|
|
966
|
-
| `analytics` | `boolean \| { endpoint?: string }` | `true` | QoE beacons, forwarded verbatim to [`createPlayer`](#createplayer). **Injected config only** — never read from the query string, so a link cannot redirect a session's beacons.
|
|
957
|
+
| Field | Type | Default | Description |
|
|
958
|
+
| -------------- | ---------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
959
|
+
| `baseUrl` | `string` | — | **Required.** API base URL. |
|
|
960
|
+
| `matchUrn` | `string` | — | **Required.** Match to play. |
|
|
961
|
+
| `apiKey` | `string` | — | **Required.** Inject server‑side in production; query param is dev‑only. |
|
|
962
|
+
| `parentOrigin` | `string` | — | Origin to post events to and accept commands from. **Set this in production** (`mountEmbed` sets it automatically). When absent, the iframe posts to `*` and skips the inbound origin check. |
|
|
963
|
+
| `autoplay` | `boolean` | `true` | Start playback once ready. |
|
|
964
|
+
| `muted` | `boolean` | `true` | Start muted (recommended for autoplay). |
|
|
965
|
+
| `waitForLive` | [`WaitForLive`](#waitforlive) | `true` | Arm and auto‑play at go‑live. |
|
|
966
|
+
| `analytics` | `boolean \| { endpoint?: string }` | `true` | QoE beacons, forwarded verbatim to [`createPlayer`](#createplayer). **Injected config only** — never read from the query string, so a link cannot redirect a session's beacons. havik-streams v0.10.0+ names the beacons host itself, so this is only needed against an older server: there, set `{ endpoint }` when `baseUrl` is not a `feed[-dev].<domain>` host, since nothing can be derived and analytics is otherwise off. ⚠️ Against such a server, [`mountEmbed`](#mountembed) configures the page via query string, so it cannot carry this: a `mountEmbed` integration on a non-feed `baseUrl` has no way to enable beacons and must self-host the embed page instead. |
|
|
967
967
|
|
|
968
968
|
<a id="frametohost"></a>
|
|
969
969
|
<a id="hosttoframe"></a>
|
|
@@ -1083,6 +1083,11 @@ interface StreamDescriptor {
|
|
|
1083
1083
|
serverTime: string; // RFC3339
|
|
1084
1084
|
liveStartsAt?: string; // present only while upcoming
|
|
1085
1085
|
isLowLatency?: boolean; // filled by the player once detected
|
|
1086
|
+
// Present when the playback response carries an analytics sid. Mode B gets
|
|
1087
|
+
// the data only: no beacons are sent unless you send them. `endpoint` is the
|
|
1088
|
+
// server-named beacons origin (havik-streams v0.10.0+), kept only when it is
|
|
1089
|
+
// a bare https origin; beacons POST to `<endpoint>/v1/beacons`.
|
|
1090
|
+
analytics?: { sid?: string; endpoint?: string };
|
|
1086
1091
|
}
|
|
1087
1092
|
```
|
|
1088
1093
|
|
package/embed/index.html
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
beacons endpoint can be derived and QoE analytics is silently off.
|
|
29
29
|
`analytics` is honoured from the injected config only, never the query.
|
|
30
30
|
-->
|
|
31
|
-
<script src="https://cdn.jsdelivr.net/npm/@oddin-gg/havik-player@2.
|
|
31
|
+
<script src="https://cdn.jsdelivr.net/npm/@oddin-gg/havik-player@2.13.0/dist/havik-player.global.js" integrity="sha384-Ct4ZlpTNiWMbtKCo8d52uoSElmYIBpTVj5AgN8kj8KxV6jU7Ok9dDqSg8Id2k5Kd" crossorigin="anonymous"></script>
|
|
32
32
|
<script>
|
|
33
33
|
HavikPlayer.bootEmbed();
|
|
34
34
|
</script>
|
package/examples/vanilla.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
shipped in each npm release is pinned to that release with Subresource
|
|
13
13
|
Integrity, injected at publish time (scripts/inject-sri.mjs). In
|
|
14
14
|
production, always use a pinned + SRI'd tag like the released copy. -->
|
|
15
|
-
<script src="https://cdn.jsdelivr.net/npm/@oddin-gg/havik-player@2.
|
|
15
|
+
<script src="https://cdn.jsdelivr.net/npm/@oddin-gg/havik-player@2.13.0/dist/havik-player.global.js" integrity="sha384-Ct4ZlpTNiWMbtKCo8d52uoSElmYIBpTVj5AgN8kj8KxV6jU7Ok9dDqSg8Id2k5Kd" crossorigin="anonymous"></script>
|
|
16
16
|
<script>
|
|
17
17
|
(async () => {
|
|
18
18
|
const player = await HavikPlayer.createPlayer({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oddin-gg/havik-player",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Havik HTML5 player SDK — LL-HLS + DRM playback for Oddin live streams (managed, bring-your-own-player, and iframe-embed modes).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|