livestream-player

The event contract

The normalized, engine-agnostic events analytics and host code bind to.

onEvent receives a discriminated union — the normalized event contract. Consumers — analytics (Nielsen / Chartbeat / GA) and host-page coordination — bind to these events, never to raw Shaka or IMA events, so the Engine can change without touching consumers (ADR 0005/0006).

Playback

typepayloadmeaning
ready{ isLive }stream loaded and ready to play
playplayback requested (may still be buffering)
playingmedia is actually advancing
pausedplayback paused
error{ error }error.fatal distinguishes terminal from recoverable

Ads

DAI stitches ad pods into the live stream server-side; the window between adbreakstart and adbreakend is the adplaying state (controls locked, ad overlay shown).

typepayloadmeaning
adbreakstart / adbreakendan ad break (pod) started / ended
adstart{ ad }an individual ad started (position, count, duration when known)
adquartile{ quartile }first / midpoint / third / complete — used for beacons
adskipa skippable ad (CSAI pre-roll) was skipped by the viewer
adfinishan individual ad finished
aderror{ error }an ad/SDK error; playback fails open to content

Captions

typepayloadmeaning
texttrackschange{ tracks }the set of available caption/subtitle tracks changed
cuechange{ cues }the active caption cues changed

Narrowing

import type {
  PlayerEvent,
  PlayerEventOf,
} from "@grahamdigital/livestream-player";

function onEvent(event: PlayerEvent) {
  if (event.type === "adstart") {
    // event is PlayerEventOf<"adstart"> — `event.ad` is available
    beacon("ad_start", { position: event.ad.position });
  }
}

Errors

Every error / aderror payload is a normalized PlayerError:

interface PlayerError {
  code?: string | number;     // engine-specific, when available
  category?: string | number; // coarse: network / media / manifest
  message: string;            // human-readable, non-localized
  fatal: boolean;             // true when playback needs a reload
  cause?: unknown;            // underlying engine error — NOT stable contract
}

Telemetry

onTelemetry is a separate, minimal operational sink — fatal errors and startup failures only (full QoS is deferred, ADR 0006):

interface TelemetryEvent {
  type: "startup_failure" | "fatal_error";
  error: PlayerError;
  reloadAttempt: number; // 1-based silent-reload attempt (0 if none scheduled)
}

Trigger it in the demo with Simulate outage.

On this page