UNPKG

@liveryvideo/player

Version:

Livery video player for use in web browsers.

973 lines (945 loc) 31 kB
/** * Livery video player for use in web browsers. * * Exports: * * - Element {@link LiveryPlayer} can play a Livery Video stream * - Element {@link LiveryBufferGraph} shows a graph of buffer levels for debugging * - Element {@link LiveryLog} shows logged lines for debugging * - Variable {@link version} specifies the version of this package * - Variable {@link endpointId} returns the Livery player endpoint id * - Classes of events dispatched by the elements: * {@link LiveryConfigChangeEvent}, {@link LiveryDisplayChangeEvent}, {@link LiveryErrorEvent}, * {@link LiveryFeaturesChangeEvent}, {@link LiveryModeChangeEvent}, {@link LiveryPlaybackChangeEvent}, * {@link LiveryQualitiesChangeEvent}, {@link LiveryRecoveredEvent} and {@link LiveryVolumeChangeEvent}. * * **Note:** When using the UMD bundle, the exports can be found as properties of `livery` in the global namespace, * e.g: `livery.version`. * * @packageDocumentation */ import { AuthClaims } from '@liveryvideo/interactive-bridge'; import { CSSResult } from 'lit'; import { LitElement } from 'lit'; import { TemplateResult } from 'lit-html'; export { AuthClaims } /** * Mode of display for player and/or video, i.e: * - `'DEFAULT'` for default display in the web page * - `'FULLSCREEN'` for fullscreen display * - `'PIP'` for picture-in-picture display of the video (the interactive layer remains in the page) * - `'AIRPLAY'` for Airplay display of the video (not yet supported by web player) * - `'CHROMECAST'` for Chromecast display of the video (not yet supported by web player) */ export declare type DisplayMode = 'AIRPLAY' | 'CHROMECAST' | 'DEFAULT' | 'FULLSCREEN' | 'PIP'; /** * Livery endpoint id used by this player (e.g: for analytics). */ export declare const endpointId: string; /** * Element defined as `<livery-buffer-graph>` which renders a graph of the buffer size and latency of specified * `player` or the first `<livery-player>` element found in the document. * * This can dispatch the following events: * - {@link LiveryErrorEvent | livery-error} - Dispatched when an error occurred. * * @group Elements * @noInheritDoc * @example * ```html * <livery-player streamid="6613d164e4b0bf3ad645f3c6"></livery-player> * <livery-buffer-graph></livery-buffer-graph> * ``` */ export declare class LiveryBufferGraph extends LitElement { static readonly styles: CSSResult; /** * Audio buffer line color, defaults to `bufferColor` or '#3366cc'. * * @group Attributes * @defaultValue null */ audioColor: null | string; /** * Chart background color, defaults to 'transparent'. * * @group Attributes * @defaultValue null */ backgroundColor: null | string; /** * If true then events dispatched by this element will bubble. * * @group Attributes * @defaultValue false */ bubbles: boolean; /** * Buffer line color used as default for `audioColor` and `videoColor`. * * @group Attributes * @defaultValue null * @deprecated Instead use {@link audioColor} and {@link videoColor} */ bufferColor: null | string; /** * Decoded FPS line color, defaults to '#f6c2f3'. * * @group Attributes * @defaultValue null */ decodedColor: null | string; /** * Dropped FPS line color, defaults to '#fc1c1c'. * * @group Attributes * @defaultValue null */ droppedColor: null | string; /** * Live latency line color, defaults to '#ffa500'. * * @group Attributes * @defaultValue null */ latencyColor: null | string; /** * Maximum number of rows to store in data table. * * Actually a period is derived from this value and a few extra rows are kept to let lines flow out of view. * E.g: With default value: 60 and 500ms updateInterval this will display a period of 30 seconds. * * @group Attributes * @defaultValue 60 */ maxRows: number; /** * Reference to specific LiveryPlayer element to create the graph for. * If not specified this will default to the first `livery-player` element found in the document. * If that is not found the graph will not start rendering. */ player: LiveryPlayer | null; /** * Chart text color, defaults to '#eee'. * * @group Attributes * @defaultValue null */ textColor: null | string; /** * Interval in milliseconds at which to add a row to the data table and draw the chart. * * @group Attributes * @defaultValue 500 */ updateInterval: number; /** * Video buffer line color, defaults to `bufferColor` or '#dc3912'. * * @group Attributes * @defaultValue null */ videoColor: null | string; connectedCallback(): void; disconnectedCallback(): void; render(): TemplateResult<1>; updated(): void; } /** * Dispatched when `config` has changed. * * @group Events * @noInheritDoc */ export declare class LiveryConfigChangeEvent extends Event { /** * Event type. */ static type: "livery-config-change"; /** * Public part of Livery stream config. */ readonly config: LiveryPlayer['config']; constructor(config: LiveryPlayer['config'], init?: EventInit); } /** * Dispatched when `display` has changed. * * @group Events * @noInheritDoc */ export declare class LiveryDisplayChangeEvent extends Event { /** * Event type. */ static type: "livery-display-change"; /** * Display mode. */ readonly display: LiveryPlayer['display']; constructor(display: LiveryPlayer['display'], init?: EventInit); } /** * Dispatched when an error occurs. * * @group Events * @noInheritDoc */ export declare class LiveryErrorEvent extends Event { /** * Event type. */ static type: "livery-error"; /** * Error that occurred. */ readonly error: Error; constructor(error: Error, init?: EventInit); } /** * Dispatched when `features` has changed. * * @group Events * @noInheritDoc */ export declare class LiveryFeaturesChangeEvent extends Event { /** * Event type. */ static type: "livery-features-change"; /** * Registry of features supported by the player in general and under given circumstances. */ readonly features: LiveryPlayer['features']; constructor(features: LiveryPlayer['features'], init?: EventInit); } /** * Dispatched when `fullscreen` has changed. * * @group Events * @noInheritDoc * @deprecated Instead use {@link LiveryDisplayChangeEvent} */ export declare class LiveryFullscreenChangeEvent extends Event { /** * Event type. */ static type: "livery-fullscreen-change"; /** * True if player became fullscreen, false otherwise. */ readonly fullscreen: boolean; constructor(fullscreen: boolean, init?: EventInit); } /** * Element defined as `<livery-log>` which shows entries logged by Livery modules * and enables them to be copied to clipboard for reporting. * The log copy will also include details from specified `player` or the first `<livery-player>` element * found in the document. * * Note that entries logged before this element is connected to DOM will not be included. * * @group Elements * @noInheritDoc * @example * ```html * <livery-player streamid="6613d164e4b0bf3ad645f3c6"></livery-player> * <livery-log></livery-log> * ``` */ export declare class LiveryLog extends LitElement { static readonly styles: CSSResult; /** * Number of characters after which to truncate displayed lines. * TODO: Rename to maxDisplayLineLength. * * @group Attributes */ maxLineLength: number; /** * Maximum number of log entries to display in this element. * TODO: Rename to maxDisplayEntries. * * @group Attributes */ maxLines: number; /** * Maximum number of log entries to keep in memory for copying to clipboard. * TODO: Rename to maxClipboardEntries. * * @group Attributes */ maxLogLines: number; /** * Reference to specific LiveryPlayer element to show details from. * If not specified this will default to the first `livery-player` element found in the document. * If that is not found some of the information will be missing from the clipboard copy. */ player: LiveryPlayer | null; /** Alias to {@link maxLogLines} for backwards compatibility. */ /** Alias to {@link maxLines} for backwards compatibility. */ /** Alias to {@link maxLineLength} for backwards compatibility. */ connectedCallback(): void; disconnectedCallback(): void; render(): TemplateResult<1>; } /** * Dispatched when `mode` has changed. * * @group Events * @noInheritDoc */ export declare class LiveryModeChangeEvent extends Event { /** * Event type. */ static type: "livery-mode-change"; /** * Display mode. */ readonly mode: LiveryPlayer['mode']; constructor(mode: LiveryPlayer['mode'], init?: EventInit); } /** * Dispatched when `streamPhase` has changed. * * @group Events * @noInheritDoc * @deprecated Instead use {@link LiveryConfigChangeEvent} */ export declare class LiveryPhaseChangeEvent extends Event { /** * Event type. */ static type: "livery-phase-change"; /** * Stream phase. */ readonly phase: LiveryPlayer['streamPhase']; constructor(phase: LiveryPlayer['streamPhase'], init?: EventInit); } /** * Dispatched when `playbackState` has changed. * * @group Events * @noInheritDoc */ export declare class LiveryPlaybackChangeEvent extends Event { /** * Event type. */ static type: "livery-playback-change"; /** * True if `playbackState` is PAUSED or ENDED. * I.e: not playing as intended. */ readonly paused: boolean; /** * Playback state. */ readonly playbackState: LiveryPlayer['playbackState']; /** * True if `playbackState` is PLAYING, FAST_FORWARD, SLOW_MO or REWIND. * I.e: playing as intended. * Can change on: livery-playback-change. */ readonly playing: boolean; /** * True if `playbackState` is BUFFERING or SEEKING. * I.e: not playing, but trying to. * Can change on: livery-playback-change. */ readonly stalled: boolean; constructor(playbackState: LiveryPlayer['playbackState'], init?: EventInit); } /** * Element defined as `<livery-player>` which can be used to play a Livery video stream as specified by * {@link streamId}. * * If auto play is enabled in the stream config this will attempt to start playback unmuted. * If that is not allowed it will attempt to fall back to muted auto play and show a click to unmute dialog. * And if that is not allowed it will just show a click to play (unmuted) dialog. * * Once a user has manually muted or unmuted that state will be attempted to be persisted and respected * on subsequent player page loads. * * This can dispatch the following events: * - {@link LiveryConfigChangeEvent | livery-config-change} - Dispatched when {@link config} has changed. * - {@link LiveryDisplayChangeEvent | livery-display-change} - Dispatched when {@link display} has changed. * - {@link LiveryErrorEvent | livery-error} - Dispatched when an error occurred and {@link error} is a string. * - {@link LiveryFeaturesChangeEvent | livery-features-change} - Dispatched when {@link features} has changed. * - {@link LiveryModeChangeEvent | livery-mode-change} - Dispatched when {@link mode} has changed. * - {@link LiveryPlaybackChangeEvent | livery-playback-change} - Dispatched when {@link playbackState} has changed. * - {@link LiveryQualitiesChangeEvent | livery-qualities-change} - Dispatched when {@link qualities} has changed. * - {@link LiveryRecoveredEvent | livery-recovered} - Dispatched when player has recovered and {@link error} is undefined. * - {@link LiveryVolumeChangeEvent | livery-volume-change} - Dispatched when {@link volume} and/or {@link muted} have changed. * * Note: Element properties that are reflected to attributes are listed with their property names, * p.e: `streamId`, as in: `player.streamId = '1234abcd'`. * The reflected attribute names however are lower case, p.e: `streamid`, as in: `<livery-player streamid="1234abcd">`. * For string attributes the value will be `null` when absent or empty. * For boolean attributes the effective value will be `true` when the attribute is present and `false` when absent, * no matter the attribute value, p.e: `<livery-player controlsdisabled>`. * * @group Elements * @noInheritDoc * @example * ```html * <!-- Replace the Livery Demo id by your stream id below --> * <livery-player streamid="6613d164e4b0bf3ad645f3c6"></livery-player> * ``` */ export declare class LiveryPlayer extends LitElement { static readonly styles: CSSResult; /** * Access token to use to be able to see a stream that uses Akamai’s Long Token Auth feature. * * @group Attributes * @defaultValue null */ akamaiLongToken: null | string; /** * Access token to use to be able to see a stream that uses Akamai’s Token Auth feature. * * @group Attributes * @defaultValue null */ akamaiToken: null | string; /** * If true then events dispatched by this element will bubble. * * @group Attributes * @defaultValue false */ bubbles: boolean; /** * Type of stream config to use. * * Defaults to SDK platform (WEB) when value is null (attribute is absent). * * @group Attributes * @defaultValue null */ configType: null | string; /** * Change this to true to disable all default player controls, e.g: to be able to use your own instead. * * @group Attributes * @defaultValue false */ controlsDisabled: boolean; /** * Display mode. * * Dispatches: {@link LiveryDisplayChangeEvent | livery-display-change} * * @readonly * @defaultValue 'DEFAULT' */ display: DisplayMode; /** * Most recent unrecovered error. * * Dispatches: {@link LiveryErrorEvent | livery-error}, {@link LiveryRecoveredEvent | livery-recovered} * * @readonly * @defaultValue undefined */ error?: Error; /** * Registry of features supported by the player in general and under given circumstances. * * Dispatches: {@link LiveryFeaturesChangeEvent | livery-features-change} * * @readonly * @defaultValue All features false */ features: { airplay: boolean; chromecast: boolean; contact: boolean; fullscreen: boolean; pip: boolean; scrubber: boolean; volume: boolean; }; /** * If true then player is fullscreen. * * Dispatches: livery-fullscreen-change * * @deprecated Instead use {@link display} and {@link setDisplay} * @group Attributes * @defaultValue false */ fullscreen: boolean; /** * AuthClaims object, JWT token string or `undefined` value to be used for interactive authentication. * * An undefined value here should result in logging out. * * @defaultValue `'livery_auth'` query parameter JSON parsed claims object, token string or `undefined` */ interactiveAuth: string | AuthClaims | undefined; /** * Global Livery locale ('de-DE' | 'en-US' | 'es-ES' | 'fr-FR' | 'nl-NL' | 'pt-PT'). * * If just the first part (e.g: 'en') of a locale is assigned that will result in the first matching full locale * value (e.g: 'en-US') being changed to. * * @group Attributes * @defaultValue The first supported locale matching one of the browser languages in-order or falls back to 'en-US' */ locale: null | string; /** * Log level ('quiet' | 'error' | 'warn' | 'info' | 'debug' | 'spam'). * * Defaults to 'info' when value is null (attribute is absent). * * @group Attributes * @defaultValue null */ logLevel: null | string; /** * Mode of playback, e.g. how to buffer, sync, adapt quality, manage stalls, etc. * * Dispatches: {@link LiveryModeChangeEvent | livery-mode-change} * * @readonly * @defaultValue 'UNKNOWN' */ mode: PlaybackMode; /** * If true then audio is muted. * * This value should just be browser controlled (i.e: read only); changing this value as a user is deprecated. * Use {@link setMuted} instead to attempt to change this value, if allowed by the browser. * * Until there is browser controlled video however (e.g: in PRE stream phase) this is the user requested value. * * Dispatches: livery-volume-change * * @readonly * @group Attributes * @defaultValue Persisted user muted value or `false` */ muted: boolean; /** * Playback state. * * Dispatches: {@link LiveryPlaybackChangeEvent | livery-playback-change} * * @readonly * @defaultValue 'ENDED' */ playbackState: PlaybackState; /** * Stream qualities. * * Dispatches: {@link LiveryQualitiesChangeEvent | livery-qualities-change} * * @readonly * @defaultValue undefined */ qualities: { /** Index of quality that is being played, or -1 if no quality is active yet. */ active: number; /** List of qualities that can be played. */ list: Quality[]; /** Index of quality that is selected to be played, or -1 if ABR is used. */ selected: number; }; /** * Active quality label. * * Dispatches: livery-quality-change * * @readonly * @deprecated Instead use {@link qualities} * @defaultValue null */ quality: null | string; /** * Custom video source URLs to override sources specified by stream config with. */ sources?: string[]; /** * Livery stream ID specifying which stream to play. * * @group Attributes * @defaultValue `'livery_stream'` query parameter value or `null` */ streamId: null | string; /** * Audio volume, from `0.0` (silent) to `1.0` (loudest). * * When a player starts unmuted at volume `0` and this is changed to a higher volume later, * that can be disallowed by the browser, e.g: when not called directly from a click event listener. * In that case this will fall back to changing {@link muted} to `true` to allow the volume change to persist. * * Dispatches: livery-volume-change * * @group Attributes * @defaultValue Persisted user muted value or `1` */ volume: number; /** * If true then volume unit meter is shown. * * @group Attributes * @defaultValue false */ vuMeter: boolean; /** * Current playback buffer in seconds ahead of current position. * * @readonly * @defaultValue NaN */ get buffer(): number; /** * Public part of Livery stream config, can change with server side updates or when streamId is changed. * * Note: Player will not be fully usable until configured. * * Dispatches: {@link LiveryConfigChangeEvent | livery-config-change} * * @readonly * @defaultValue undefined */ get config(): { /** Registry of controls that should be shown to the user. */ controls: { /** Enable toggling AirPlay and/or Chromecast display. */ cast: boolean; /** Enable submitting user feedback. */ contact: boolean; /** Enable error feedback and recovery controls. */ error: boolean; /** Enable toggling fullscreen display. */ fullscreen: boolean; /** Enable muting and unmuting audio. */ mute: boolean; /** Enable toggling picture-in-picture display. */ pip: boolean; /** Enable toggling play/pause. */ play: boolean; /** Enable quality selection. */ quality: boolean; /** Enable seeking through the stream. */ scrubber: boolean; }; /** Livery customer ID. */ customerId: string; /** Array of [unixTimestamp, streamPhase] tuples listing the times at which those phases started. */ streamPhases: [number, "POST" | "LIVE" | "PRE"][]; /** Livery stream phase, i.e: PRE/LIVE/POST before/while/after streaming to viewers. */ streamPhase: "POST" | "LIVE" | "PRE"; /** Livery tenant ID. */ tenantId: string; } | undefined; /** * Livery customer ID. * * @readonly * @deprecated Instead use {@link config}.customerId * @defaultValue null */ get customerId(): string | null; /** * Current playback duration in seconds from start to end of live stream or VOD. * * @readonly * @defaultValue NaN */ get duration(): number; /** * Current end-to-end latency in seconds. * * @readonly * @defaultValue NaN */ get latency(): number; /** * True if `playbackState` is PAUSED or ENDED. * I.e: not playing as intended. * Can change on: {@link LiveryPlaybackChangeEvent | livery-playback-change}. * * @readonly * @defaultValue true */ get paused(): boolean; /** * True if `playbackState` is PLAYING, FAST_FORWARD, SLOW_MO or REWIND. * I.e: playing as intended. * Can change on: {@link LiveryPlaybackChangeEvent | livery-playback-change}. * * @readonly * @defaultValue false */ get playing(): boolean; /** * Current playback position in seconds since start of live stream or VOD. * * @readonly * @defaultValue NaN */ get position(): number; /** * True if `playbackState` is BUFFERING or SEEKING. * I.e: not playing, but trying to. * Can change on: {@link LiveryPlaybackChangeEvent | livery-playback-change}. * * @readonly * @defaultValue false */ get stalled(): boolean; /** * Livery stream phase, i.e: PRE/LIVE/POST before/while/after streaming to viewers. * * Dispatches: livery-phase-change * * @readonly * @deprecated Instead use {@link config}.streamPhase * @defaultValue 'PRE' */ get streamPhase(): "POST" | "LIVE" | "PRE"; constructor(); connectedCallback(): void; disconnectedCallback(): void; firstUpdated(changed: Map<PropertyKey, unknown>): void; /** * Pause playback. */ pause(): void; /** * Attempt to start or resume playback. * * This will also attempt to auto unmute (unless user previously muted) while we're at it. * * Can fail if not allowed by the browser, e.g: when not called directly from a click event listener. * The user paused state is kept track of by the player though and respected on reload when possible. * If starting playback unmuted fails this can fall back to muted playback, changing {@link muted} to `true`. * If muted autoplay also fails then {@link paused} will remain `true`. */ play(): void; /** * Register custom player bridge command `handler` by `name`. * * The `handler` will be called with `arg` and `listener` when `sendPlayerCommand()` is called with matching `name` * from the interactive layer bridge side. * The value or Promise returned by `handler` will be passed back and returned by that interactive bridge call. * Any `listener` calls here will similarly result in the interactive `listener` being called with those values. */ registerPlayerCommand(name: string, handler: (arg: unknown, listener: (value: unknown) => void) => unknown): void; /** * Reload player, e.g: to try to recover from an error. */ reload(): void; render(): TemplateResult<1>; /** * Select index of quality from {@link qualities} to play, or select -1 to use ABR (Automatic BitRate selection). * * @param index - Index of quality to select * @throws Error "Player unconfigured" when config has not been loaded yet * @throws Error "Qualities undefined" when stream qualities have not been loaded yet * @throws RangeError when index is not -1 or a valid index of the {@link qualities} array */ selectQuality(index: number): void; /** * Send command to interactive layer via player bridge and return promise of value returned by interactive bridge's * custom command handler with matching `name` that was passed `arg`. * Any of that interactive handler's `listener` calls will subsequently also be bridged to this `listener` callback. */ sendInteractiveCommand(name: string, arg?: unknown, listener?: (value: unknown) => void): Promise<unknown>; /** * Attempt to change display mode to specified value. * * @param display - Display mode to change to * @throws DOMException NotSupportedError: Unsupported feature: [feature] - If related features property is false * @throws DOMException NotAllowedError: [message] - If browser does not allow it */ setDisplay(display: LiveryPlayer['display']): Promise<void>; /** * Attempt to change muted state to specified value. * * Unmuting can fail if not allowed by the browser, e.g: when not called directly from a click event listener. * The specified state is kept track of by the player though and respected on reload when possible. * Look at {@link muted} state to track actual unmuting. * * @param muted - Muted state to change to */ setMuted(muted: boolean): void; /** * Unregister custom player bridge command by `name`. */ unregisterPlayerCommand(name: string): void; update(changed: Map<PropertyKey, unknown>): void; /** * This method can be used to get things started that require a user gesture. * Note: Only use this when it is logical to do this implicitly. */ } /** * Dispatched when `qualities` has changed. * * @group Events * @noInheritDoc */ export declare class LiveryQualitiesChangeEvent extends Event { /** * Event type. */ static type: "livery-qualities-change"; /** * Stream qualities. */ readonly qualities: LiveryPlayer['qualities']; constructor(qualities: LiveryPlayer['qualities'], init?: EventInit); } /** * Dispatched when `quality` has changed. * * @group Events * @noInheritDoc * @deprecated Instead use {@link LiveryQualitiesChangeEvent} */ export declare class LiveryQualityChangeEvent extends Event { /** * Event type. */ static type: "livery-quality-change"; /** * Label of quality that became active. */ readonly quality: null | string; constructor(quality: null | string, init?: EventInit); } /** * Dispatched when player has recovered from an error. * * @group Events * @noInheritDoc */ export declare class LiveryRecoveredEvent extends Event { /** * Event type. */ static type: "livery-recovered"; constructor(init?: EventInit); } /** * Dispatched when `volume` and/or `muted` have changed. * * @group Events * @noInheritDoc */ export declare class LiveryVolumeChangeEvent extends Event { /** * Event type. */ static type: "livery-volume-change"; /** * If true then audio is muted. */ readonly muted: boolean; /** * Audio volume, from 0.0 (silent) to 1.0 (loudest). */ readonly volume: number; constructor(volume: number, muted: boolean, init?: EventInit); } /** * Mode of playback, e.g. how to buffer, sync, adapt quality, manage stalls, etc. * - `'CATCHUP'` stream at increased live latency, i.e. after seeking to catch up to missed content * - `'LIVE'` stream at default live target latency * - `'UNKNOWN'` while state is unknown, e.g: during startup * - `'VOD'` stream video on demand */ export declare type PlaybackMode = 'CATCHUP' | 'LIVE' | 'UNKNOWN' | 'VOD'; /** * Playback state, i.e: * - `'BUFFERING'` while waiting for buffer to fill before being able to play * - `'ENDED'` after video has ended * - `'FAST_FORWARD'` while playing at an increased rate * - `'PAUSED'` while playback has been paused * - `'PLAYING'` while playing * - `'REWIND'` while playing at a negative rate (in reverse) * - `'SEEKING'` while waiting for buffer after seeking * - `'SLOW_MO'` while playing a decreased rate */ export declare type PlaybackState = 'BUFFERING' | 'ENDED' | 'FAST_FORWARD' | 'PAUSED' | 'PLAYING' | 'REWIND' | 'SEEKING' | 'SLOW_MO'; /** * An audio and video quality tuple for quality selection. */ export declare interface Quality { /** * Audio quality. */ audio?: { /** * Audio bandwidth in bits per second. */ bandwidth: number; /** * Audio quality index. */ index: number; }; /** * Total bandwidth in bits per second. */ bandwidth: number; /** * Quality label. * If video height is unique: ‘[height]p’ else ‘[bandwidth/1000]k’. */ label: string; /** * Video quality. */ video?: { /** * Video andwidth in bits per second. */ bandwidth: number; /** * Video height in pixels. */ height: number; /** * Video quality index. */ index: number; /** * Video width in pixels. */ width: number; }; } /** * Livery video web player semantic version, e.g: 1.2.3 (major.minor.patch). */ export declare const version: string; export { } declare global { interface GlobalEventHandlersEventMap { 'livery-config-change': LiveryConfigChangeEvent; 'livery-display-change': LiveryDisplayChangeEvent; 'livery-error': LiveryErrorEvent; 'livery-features-change': LiveryFeaturesChangeEvent; 'livery-fullscreen-change': LiveryFullscreenChangeEvent; 'livery-mode-change': LiveryModeChangeEvent; 'livery-phase-change': LiveryPhaseChangeEvent; 'livery-playback-change': LiveryPlaybackChangeEvent; 'livery-qualities-change': LiveryQualitiesChangeEvent; 'livery-quality-change': LiveryQualityChangeEvent; 'livery-recovered': LiveryRecoveredEvent; 'livery-volume-change': LiveryVolumeChangeEvent; } interface HTMLElementTagNameMap { 'livery-buffer-graph': LiveryBufferGraph; 'livery-log': LiveryLog; 'livery-player': LiveryPlayer; } }