@glomex/integration-web-component
Version:
Web component and types to integrate the glomex player
1,489 lines (1,451 loc) • 87.8 kB
TypeScript
import type { SerializedError } from '@reduxjs/toolkit';
export declare interface Ad {
sessionId: string;
id: string;
adFormat: AdFormat | `${AdFormat}`;
duration?: number;
positionIndex: number;
breakIndex: number;
breakName: AdBreakName | `${AdBreakName}`;
mimetype: string;
totalAds: number;
adUrl?: string;
nonLinearWidth?: number;
nonLinearHeight?: number;
title?: string;
advertiserName?: string;
width?: number;
height?: number;
adSystem?: string;
universalAdIds?: {
id: string;
registry: string;
}[];
creativeId?: string;
skippable: boolean;
clickThroughUrl?: string;
}
/** Name of ad break - when the ad appears, `OVERLAY` is deprecated */
export declare enum AdBreakName {
PREROLL = "preroll",
MIDROLL = "midroll",
POSTROLL = "postroll"
}
export declare class AdError extends Error {
code: string;
name: string;
constructor(message: string, code: string);
}
/** Format of the ad - how it is presented */
export declare enum AdFormat {
LINEAR = "linear",
OVERLAY = "overlay",
CUTIN = "cutin",
PAUSE = "pause"
}
declare const ALLOWED_UI_ACTIONS: readonly ["play", "pause", "openEpg", "startAgeSetup", "forgotPin"];
/**
* An additional API script definition that should be executed for this media-item.
*
* @example
* ```
* {
* name: 'some-name',
* scriptUrl: 'https://content-owner.com/tracking/script.js',
* conditions: [
* { startMethods: ['click-to-play'], muted: false, requiredVendors: ['967'], probability: 1 },
* { startMethods: ['autoplay-scroll'], muted: undefined, requiredVendors: undefined, probability: 1 } // undefined = no filtering
* ]
* }
* ```
*/
declare interface ApiScript {
/** Name of the API script that should be exposed to tracking */
name: string;
/** URL of the API script that should be executed. Must implement {@link ConnectIntegration}. */
url: string;
/**
* Conditions under which the API script should be executed. Undefined means always.
*/
conditions?: {
startMethods?: StartMethod[];
muted?: boolean | undefined;
requiredVendors?: string[];
probability: number;
}[];
}
/**
* Represents an audio track.
*/
export declare interface AudioTrack extends MediaTrack {
/** The type of audio track. */
kind: 'main' | string;
}
/**
* A collection of audio tracks with selection support.
* A selected track is available when track info is exposed; otherwise null.
*
* **Note:** Audio tracks are available after the {@link IntegrationElement.ready | integration.ready} promise resolves.
*
* The list is iterable and can be converted to an array:
* @example
* ```ts
* for (const track of integration.audioTracks) { console.log(track); }
* const tracks = Array.from(integration.audioTracks);
* ```
*/
export declare interface AudioTrackList extends MediaTrackList<AudioTrack> {
/** The currently selected audio track, or `null` if unavailable. */
readonly selected: AudioTrack | null;
/**
* Selects an audio track.
* @param trackOrId - The track or track ID to select.
*/
select(trackOrId: AudioTrack | string): void;
}
declare class BaseMediaError<T extends string = string> extends Error {
code: T;
name: string;
constructor(message: string, code: T);
}
export declare interface Channel {
/** Human-readable channel title shown in the player UI */
name?: string;
/** Stable machine-facing code used for lookups or analytics */
code?: string;
/** Provider-specific identifier when it differs from `code` */
id?: string;
/** Canonical playback or landing URL clients should open */
url?: string;
/** Square channel-logo URL (ideally 96x96) used wherever icons appear */
logo?: string;
}
export declare enum ComponentName {
INTEGRATION = "glomex-integration",
EXTERNAL_MEDIA_ITEM = "external-media-item",
GLOMEX_MEDIA_ITEM = "glomex-media-item",
JOYN_MEDIA_ITEM = "joyn-media-item"
}
/**
* Describes the contract that an external API tracking script must implement so that it can be
* imported and executed by the integration. The API script must be hosted on the remote server
* with CORS enabled.
*
* @example
* ```ts
* import { IntegrationEvent } from '@glomex/integration';
* export const connectIntegration: ConnectIntegration = (
* integration,
* // userId will be undefined when no consent is given
* { userCountryCode, userId, integrationEnvironment }
* ) => {
* integration.addEventListener(IntegrationEvent.CONTENT_PLAY, () => {
* console.log('play', integration.content);
* });
* };
* ```
*
* @example
* ```js
* export const connectIntegration = (
* integration,
* // userId will be undefined when no consent is given
* { userCountryCode, userId, integrationEnvironment }
* ) => {
* const { IntegrationEvent } = integration.constructor;
* integration.addEventListener(IntegrationEvent.CONTENT_PLAY, () => {
* console.log('play', integration.content);
* });
* };
* ```
*/
export declare type ConnectIntegration = (integration: IntegrationElement, context: {
userCountryCode?: string;
userId?: string;
integrationEnvironment?: string;
}, options?: {
warnCallback?: (error: Error) => void;
}) => (() => void) | undefined;
export declare interface Consent {
gdprApplies: boolean;
consentString?: string;
cmpId?: number;
policyVersion?: number;
vendorListVersion?: number;
vendorConsents?: Record<string, boolean>;
vendorLegitimateInterests?: Record<string, boolean>;
purposeConsents?: Record<string, boolean>;
purposeLegitimateInterests?: Record<string, boolean>;
ready: boolean;
addtlConsent?: string;
}
/**
* Selected source of the given content.
*/
export declare interface ContentSource {
id?: string;
mimetype: Mimetype;
src: string;
playbackMode: PlaybackMode;
entitlementToken?: string;
drm: boolean;
liveEdgeTolerance: number;
}
export declare enum ContentStopReason {
CLEAR_PLAYLIST = "clearPlaylist",
SELECT_PLAYLIST_ITEM = "selectPlaylistItem",
ENDED = "ended",
CONTENT_ERROR = "contentError",
API_STOP = "apiStop",
LIVESTREAM_STOP = "livestreamStop",
PAGE_HIDE = "pageHide",
BEFORE_UNLOAD = "beforeUnload"
}
export declare interface CustomMarker extends Omit<Marker, 'name'> {
/** {@inheritDoc Marker.name} */
name: string;
}
/**
* Identifier names for device IDs that can be passed via {@link SharedContextData.deviceId}.
*/
export declare enum DeviceIdName {
/** Android Advertising ID (Google) */
AAID = "aaid",
/** Amazon Fire OS Advertising ID */
AFAI = "afai",
/** Android App Set ID — scope: app */
ASIA = "asia",
/** Android App Set ID — scope: developer */
ASID = "asid",
/** Tizen Identifier for Advertising (Samsung) */
TIFA = "tifa",
/** VIDAA Advertising ID (Hisense) */
VAID = "vaid",
/** Apple Identifier for Advertisers */
IDFA = "idfa",
/** Apple Identifier for Vendors */
IDFV = "idfv",
/** LG Unique Device ID */
LGUDID = "lgudid",
/** Microsoft Advertising ID */
MSAI = "msai",
/** Huawei Open Advertising ID */
OAID = "oaid",
/** PlayStation Advertising ID */
PSNAI = "psnai",
/** Roku Identifier for Advertising */
RIDA = "rida",
/** Vizio Advertising ID */
VIDA = "vida",
/** TitanOS Advertising ID (Walmart) */
WAID = "waid"
}
declare interface Experiment {
name: string;
enabled: boolean;
participantPercentage: number;
variants: Record<string, ExperimentVariant>;
conditions: Record<string, unknown>;
}
declare interface ExperimentVariant {
weight: number;
contentOverride: Record<string, unknown>;
}
export declare interface ExtendedVideoPlaybackQuality extends VideoPlaybackQuality {
bitrate: number;
liveLatency: number;
throughput: number;
bytes: number;
bandwidth: number;
width: number;
height: number;
}
/** @ignore */
export declare const EXTERNAL_PLAYER_NAME = "turbo-player";
/**
* A media item web component that allows to define external media items via inline JSON.
* It can be placed inside the integration element as a child.
* For more complex use cases, see {@link MediaItemElement}.
*
* @tagname external-media-item
*
* @slot - Slot for inline JSON of type `application/external-media-item+json`
*
* @example single media item with inline JSON
*
* This only works when no `playlist-id` is assigned to `glomex-integration`
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <external-media-item>
* <script type="application/external-media-item+json">
* {
* "id": "SOME_ID",
* "sources": [
* {
* "src": "SOME_VIDEO_URL",
* "mimetype": "video/mp4"
* }
* ],
* "duration": 120,
* "poster": "POSTER_URL",
* "title": "VIDEO_TITLE"
* }
* </script>
* </external-media-item>
* </glomex-integration>
* ```
*
* @example multiple media items with inline JSON array
*
* You can also pass an array of {@link MediaItem} objects to define a playlist.
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <external-media-item>
* <script type="application/external-media-item+json">
* [
* {
* "id": "VIDEO_1",
* "sources": [{ "src": "VIDEO_1_URL", "mimetype": "video/mp4" }],
* "duration": 120,
* "poster": "POSTER_1_URL",
* "title": "First Video"
* },
* {
* "id": "VIDEO_2",
* "sources": [{ "src": "VIDEO_2_URL", "mimetype": "video/mp4" }],
* "duration": 180,
* "poster": "POSTER_2_URL",
* "title": "Second Video"
* }
* ]
* </script>
* </external-media-item>
* </glomex-integration>
* ```
*/
export declare class ExternalMediaItemElement extends MediaItemElement {
}
/**
* An optional context object that can be used to pass additional application, device and user information to the integration. Updates must be performed immutably: always provide a new object to the {@link IntegrationElement#extraContext} property when modifying any property or nested field.
*/
export declare interface ExtraContext {
/**
* The presentational context of the integration. Do not define it when it is not part of those contexts.
*/
presentationalContext?: 'curated-list' | 'discovery-page';
/**
* The version of the app. When it is a website, fill in the deployed version of the website.
*/
appVersion?: string;
/**
* The name of the app. When it is a website, fill in the name of the project.
*/
appName?: string;
/**
* User ids of the user. User ids are only used when the user has given consent for the assigned vendor.
*/
userIds?: {
id: string;
name: UserIdName | `${UserIdName}`;
ext?: Record<string, unknown>;
}[];
/**
* The bundle id of the app. Only required for iOS apps.
*/
appBundleId?: string;
/**
* The store id of the app. Only required for apps. Depending on the app store, the id is formatted differently.
* {@link https://iabtechlab.com/wp-content/uploads/2020/08/IAB-Tech-Lab-OTT-store-assigned-App-Identification-Guidelines-2020.pdf IAB Tech Lab App Identification Guidelines}
*/
appStoreId?: string;
/**
* The store URL of the app. Only required for apps.
* {@link https://iabtechlab.com/wp-content/uploads/2020/08/IAB-Tech-Lab-OTT-store-assigned-App-Identification-Guidelines-2020.pdf IAB Tech Lab App Identification Guidelines}
*/
appStoreUrl?: string;
b2bContext?: string;
deviceId?: {
id: string;
name: DeviceIdName | `${DeviceIdName}`;
};
}
/**
* Returns the CSS URL for a given integration variant.
*
* @example
* ```ts
* import { getIntegrationCssUrl } from '@glomex/integration-web-component';
*
* const cssUrl = getIntegrationCssUrl('my-integration-id');
* // => 'https://player.glomex.com/variant/my-integration-id/variant.css'
* ```
*/
export declare function getIntegrationCssUrl(integrationId: string): string;
/**
* Returns the {@link SharedContext} singleton from the loaded `integration.js`.
*
* Waits for the `<glomex-integration>` custom element to be defined, then
* reads the singleton from its static property — guaranteeing the same
* instance that the running player uses.
*
* @example
* ```ts
* import { getSharedContext } from '@glomex/integration-web-component';
*
* const sharedContext = await getSharedContext();
* sharedContext.set({
* appVersion: '2.3.0',
* providers: {
* 'my-provider': async () => ({ token: await myAuth.getFreshToken() }),
* }
* });
* ```
*/
export declare function getSharedContext(): Promise<SharedContext>;
/**
* Web component that allows to override title and poster of a given glomex content id. It can be placed
* inside the integration element. For integrating external media items, see {@link ExternalMediaItemElement}.
*
* @tagname glomex-media-item
*
* @attribute id - The glomex media ID or playlist ID to load.
* @attribute {stage|prod} environment - The environment to use for the provider request.
* @attribute poster - URL to override the poster image of the media item.
* @attribute title - Override the title of the media item.
*
* @example with 2 glomex-media-items
*
* This only works when no `playlist-id` is assigned to `glomex-integration`
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <glomex-media-item
* id="REPLACE_WITH_MEDIA_OR_PLAYLIST_ID"
* ></glomex-media-item>
* <glomex-media-item
* id="ANOTHER_MEDIA_OR_PLAYLIST_ID"
* ></glomex-media-item>
* </glomex-integration>
* ```
*
* @example glomex-media-item with title and poster override
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <glomex-media-item
* id="REPLACE_WITH_MEDIA_OR_PLAYLIST_ID"
* title="REPLACE_WITH_TITLE_OVERRIDE"
* poster="REPLACE_WITH_POSTER_URL_OVERRIDE"
* ></glomex-media-item>
* </glomex-integration>
* ```
*
* @example glomex-media-item targeting the stage environment
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <glomex-media-item
* id="REPLACE_WITH_MEDIA_OR_PLAYLIST_ID"
* environment="stage"
* ></glomex-media-item>
* </glomex-integration>
* ```
*/
export declare class GlomexMediaItemElement extends MediaItemElement {
/**
* Overridden poster of the media item.
* @attribute poster
*/
poster: string;
}
/**
* Web component to integrate the player.
*
* @see {@link IntegrationElementEventMap} for a full list of event types and their payloads
* @tagname glomex-integration
* @slot - (optional) Slot for custom media items ({@link GlomexMediaItemElement}, {@link JoynMediaItemElement}, {@link ExternalMediaItemElement} or {@link MediaItemElement})
*
* @example with a playlist-id
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* playlist-id="REPLACE_WITH_PLAYLIST_ID"
* ></glomex-integration>
* ```
*
* You can find more advanced examples in the {@link GlomexMediaItemElement}, {@link JoynMediaItemElement}, {@link ExternalMediaItemElement} or {@link MediaItemElement} documentation.
*/
export declare class IntegrationElement extends HTMLElement implements IntegrationProperties {
#private;
static MarkerType: typeof MarkerType;
static KnownMarkerName: typeof KnownMarkerName;
static PlaybackMode: typeof PlaybackMode;
static Mimetype: typeof Mimetype;
static PresentationMode: typeof PresentationMode;
static IntegrationEvent: typeof IntegrationEvent;
static sharedContext: SharedContext;
/**
* {@inheritDoc IntegrationProperties.integrationId}
* @attribute integration-id
*/
integrationId?: string;
/**
* {@inheritDoc IntegrationProperties.playlistId}
* @attribute playlist-id
*/
playlistId?: string;
/**
* {@inheritDoc IntegrationProperties.index}
* @attribute index
*/
index?: number;
/**
* {@inheritDoc IntegrationProperties.hidden}
* @attribute {on|off} hidden
*/
hidden: boolean;
/**
* {@inheritDoc IntegrationProperties.topLevelIframe}
* @attribute top-level-iframe
*/
topLevelIframe: boolean;
/**
* {@inheritDoc IntegrationProperties.placement}
* @attribute placement
*/
placement?: string;
variant?: string;
adPlayer?: string;
/**
* {@inheritDoc IntegrationProperties.crossorigin}
* @attribute crossorigin
*/
crossorigin?: IntegrationProperties['crossorigin'];
/**
* {@inheritDoc IntegrationProperties.userLanguage}
* @attribute user-language
*/
userLanguage?: string;
extraContext?: ExtraContext;
/**
* Optional callback function invoked when the integration fails to load an advertisement.
* The callback receives an object with a `reason` property that explains why no ad was loaded.
* It must be defined before the element gets attached to the DOM.
*/
passback?: (payload: {
reason: string;
}) => void;
/**
* Resolves when the integration API is available (e.g. setting volume, play, pause, etc.).
* Alternatively to `element.addEventListener(IntegrationEvent.READY, () => {...})`
*/
ready: Promise<void>;
/**
* Initiates playback of the media content.
* @param options.startMethod - The method used to start playback (defaults to CLICK)
*/
play(options?: {
startMethod: Exclude<StartMethod, StartMethod.PRE_CLICK>;
}): Promise<void>;
/**
* Pauses the current media playback.
*/
pause(): Promise<void>;
/**
* Snapshots current video frame. Requires {@link crossorigin} to be set to `anonymous`.
*/
getCurrentVideoFrame(): Promise<ImageBitmap>;
/**
* Returns the current playback time (in seconds) of the media.
*/
get currentTime(): number;
/**
* Returns the current extended playback quality.
*/
getVideoPlaybackQuality(): {
droppedVideoFrames: number;
totalVideoFrames: number;
creationTime: number;
corruptedVideoFrames: number;
bitrate: number;
liveLatency: number;
throughput: number;
bytes: number;
bandwidth: number;
width: number;
height: number;
} | undefined;
/**
* Returns the current session ID.
*/
get sessionId(): string;
/**
* Returns the current wall clock time (UNIX timestamp in seconds). Useful for livestreams.
*/
get wallClockTime(): number;
/**
* Seeks the media to the specified time, updating the current playback time.
* @param time - The time (in seconds) to seek to.
*/
set currentTime(time: number);
/**
* Retrieves the total duration (in seconds) of the current media content.
*/
get duration(): number;
/**
* Retrieves the seekable range of the current media content.
* For VoD content, this typically represents the full duration (0 to duration).
* For live streams, this represents the DVR window that can be seeked to.
* The `start` and `end` properties are `undefined` if the seek range is not yet available.
*/
get seekRange(): SeekRange;
/**
* Indicates whether the media playback is currently muted.
*/
get muted(): boolean;
/**
* Mutes or unmutes the media playback.
* @param value - A boolean value indicating whether to mute the media playback.
*/
set muted(value: boolean);
/**
* Returns the current volume level of the media playback (0-1).
*/
get volume(): number;
/**
* Sets the media playback volume to the specified level.
* @param value - The volume level to be set (0-1).
*/
set volume(value: number);
/**
* Returns the current playback speed.
*/
get playbackRate(): number;
/**
* Sets the playback speed.
* @param value - The playback speed to be set (e.g. 0.5, 1, 1.5, 2).
*/
set playbackRate(value: number);
/**
* Returns `true` if the media playback is currently paused; otherwise, returns `false`.
*/
get paused(): boolean;
/**
* Indicates whether the media playback has ended.
*/
get ended(): boolean;
/**
* Indicates whether the media is currently in a seeking state.
*/
get seeking(): boolean;
/**
* Indicates whether the media is currently in a buffering state.
*/
get buffering(): boolean;
/**
* Retrieves the current presentation mode of the media player.
* This mode may affect how the media is displayed.
*/
get presentationMode(): PresentationMode;
/**
* Returns whether the ad playback is muted. If no ad is currently active, this value is `undefined`.
*/
get adMuted(): boolean | undefined;
/**
* Retrieves the volume level for the ad playback. If no ad is currently active, this value is `undefined`.
*/
get adVolume(): number | undefined;
/**
* Returns the current playback time (in seconds) for the ad content. If no ad is currently active, this value is `NaN`.
*/
get adCurrentTime(): number;
/**
* Retrieves the total duration (in seconds) of the ad content. If no ad is currently active, this value is `NaN`.
*/
get adDuration(): number;
/**
* Indicates whether the ad playback is currently paused. If no ad is currently active, this value is `undefined`.
*/
get adPaused(): boolean | undefined;
/**
* Retrieves the currently selected content item.
*/
get content(): MediaItemResolved | undefined;
/**
* Retrieves the currently selected source.
*/
get source(): ContentSource | undefined;
/**
* Retrieves the current playlist.
*/
get playlist(): MediaItemResolved[] | undefined;
/**
* Provides access to the user's consent information.
*/
get consent(): Consent | undefined;
/**
* Retrieves information about the detected page.
*/
get page(): Page | undefined;
/**
* Retrieves the playback time (in seconds) of the current content.
*/
get contentPlaybackTime(): number;
/**
* Retrieves details about the currently selected ad, if any.
*/
get currentAd(): Ad | undefined;
/** Version of the integration */
get version(): string;
/**
* Sets the presentation mode of the media player to the specified mode. This mode affects how the integration gets displayed
* (e.g. inline, dock, lightbox, fullscreen).
*
* @param {PresentationMode} mode - The presentation mode to set.
* @param {Object} [options] - Optional configuration.
* @param {boolean} [options.byUser=false] - Indicates if the change was initiated by a user action.
*/
setPresentationMode(mode: PresentationMode | `${PresentationMode}`, { byUser }?: {
byUser?: boolean | undefined;
}): Promise<void>;
/**
* Exits the current presentation mode.
*
* @param {Object} [options] - Optional configuration.
* @param {boolean} [options.byUser=false] - Indicates if the change was initiated by a user action.
*/
exitCurrentPresentationMode({ byUser }?: {
byUser?: boolean;
}): Promise<void>;
/**
* Returns the audio track list.
* You can use this to listen to audio track changes via `audioTracks.addEventListener('change', ...)`.
*
* **Note:** Audio tracks are available after the {@link ready | integration.ready} promise resolves.
* @example
* ```ts
* await integration.ready;
* for (const track of integration.audioTracks) { console.log(track); }
* const tracks = Array.from(integration.audioTracks);
* ```
*
* Use the `select()` method to change the active audio track:
* @example
* ```ts
* integration.audioTracks?.select(trackId);
* ```
*/
get audioTracks(): AudioTrackList | undefined;
/**
* Returns the text track list.
* You can use this to listen to text track changes via `textTracks.addEventListener('change', ...)`.
*
* **Note:** Text tracks are available after the {@link ready | integration.ready} promise resolves.
* @example
* ```ts
* await integration.ready;
* for (const track of integration.textTracks) { console.log(track); }
* const tracks = Array.from(integration.textTracks);
* ```
*
* Use the `select()` method to change the active text track, or pass `undefined` to disable:
* @example
* ```ts
* integration.textTracks?.select(trackId);
* integration.textTracks?.select(undefined); // disable text tracks
* ```
*/
get textTracks(): TextTrackList_2 | undefined;
/**
* Returns the video track list.
* You can use this to listen to video track changes via `videoTracks.addEventListener('change', ...)`.
*
* **Note:** Video tracks are available after the {@link ready | integration.ready} promise resolves.
* @example
* ```ts
* await integration.ready;
* for (const track of integration.videoTracks) { console.log(track); }
* const tracks = Array.from(integration.videoTracks);
* ```
*
* Use the `select()` method to change the active video track, or pass `'auto'` for automatic quality selection:
* @example
* ```ts
* integration.videoTracks?.select(trackId);
* integration.videoTracks?.select('auto'); // enable ABR
* ```
*/
get videoTracks(): VideoTrackList | undefined;
}
/**
* Map of events that are dispatched by the {@link IntegrationElement}. The {@link IntegrationElement} provides
* getters to read {@link IntegrationElement#consent consent}, {@link IntegrationElement#content content}, {@link IntegrationElement#page page}, {@link IntegrationElement#currentTime currentTime}, ... state from.
*
* @see {@link IntegrationEvent} for all event types as constants
*
* @example
*
* ```js
* // using strings
* integration.addEventListener('ready', () => {});
* // using constants
* await window.customElements.whenDefined('glomex-integration');
* const { IntegrationEvent } = integration.constructor;
* integration.addEventListener(IntegrationEvent.READY, () => {});
* ```
*/
export declare interface IntegrationElementEventMap {
/**
* @inheritdoc IntegrationEvent.READY
* @eventProperty
*/
[IntegrationEvent.READY]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.INTEGRATION_ABORT
* @eventProperty
*/
[IntegrationEvent.INTEGRATION_ABORT]: CustomEvent<{
error: SerializedError;
}>;
/**
* @inheritdoc IntegrationEvent.INTEGRATION_AD_AVAILABLE
* @eventProperty
*/
[IntegrationEvent.INTEGRATION_AD_AVAILABLE]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.INTEGRATION_PASSBACK
* @eventProperty
*/
[IntegrationEvent.INTEGRATION_PASSBACK]: CustomEvent<{
reason: string;
}>;
/**
* @inheritdoc IntegrationEvent.USER_UPDATE_CONSENT
* @eventProperty
*/
[IntegrationEvent.USER_UPDATE_CONSENT]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.PLAYLIST_UPDATE
* @eventProperty
*/
[IntegrationEvent.PLAYLIST_UPDATE]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.PLAYER_SET_PRESENTATION_MODE
* @eventProperty
*/
[IntegrationEvent.PLAYER_SET_PRESENTATION_MODE]: CustomEvent<{
mode: PresentationMode;
previousMode: PresentationMode;
}>;
/**
* @inheritdoc IntegrationEvent.CONTENT_SELECT
* @eventProperty
*/
[IntegrationEvent.CONTENT_SELECT]: CustomEvent<{
sessionId: string;
source: ContentSource;
}>;
/**
* @inheritdoc IntegrationEvent.CONTENT_START
* @eventProperty
*/
[IntegrationEvent.CONTENT_START]: CustomEvent<{
startMethod: StartMethod;
}>;
/**
* @inheritdoc IntegrationEvent.CONTENT_IMPRESSION
* @eventProperty
*/
[IntegrationEvent.CONTENT_IMPRESSION]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.CONTENT_BUFFERING_START
* @eventProperty
*/
[IntegrationEvent.CONTENT_BUFFERING_START]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.CONTENT_BUFFERING_END
* @eventProperty
*/
[IntegrationEvent.CONTENT_BUFFERING_END]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.CONTENT_STOP
* @eventProperty
*/
[IntegrationEvent.CONTENT_STOP]: CustomEvent<{
reason: ContentStopReason;
}>;
/**
* @inheritdoc IntegrationEvent.CONTENT_ERROR
* @eventProperty
*/
[IntegrationEvent.CONTENT_ERROR]: CustomEvent<{
error: SerializedError;
}>;
/**
* @inheritdoc IntegrationEvent.CONTENT_MARKER_REACHED
* @eventProperty
*/
[IntegrationEvent.CONTENT_MARKER_REACHED]: CustomEvent<{
markerName: string;
markerData: unknown;
}>;
/**
* @inheritdoc IntegrationEvent.CONTENT_TIME_UPDATE
* @eventProperty
*/
[IntegrationEvent.CONTENT_TIME_UPDATE]: CustomEvent<void> | HTMLElementEventMap['timeupdate'];
/**
* @inheritdoc IntegrationEvent.CONTENT_SEEKING
* @eventProperty
*/
[IntegrationEvent.CONTENT_SEEKING]: CustomEvent<void> | HTMLElementEventMap['seeking'];
/**
* @inheritdoc IntegrationEvent.CONTENT_SEEKED
* @eventProperty
*/
[IntegrationEvent.CONTENT_SEEKED]: CustomEvent<void> | HTMLElementEventMap['seeked'];
/**
* @inheritdoc IntegrationEvent.CONTENT_PLAY
* @eventProperty
*/
[IntegrationEvent.CONTENT_PLAY]: CustomEvent<void> | HTMLElementEventMap['play'];
/**
* @inheritdoc IntegrationEvent.CONTENT_PAUSE
* @eventProperty
*/
[IntegrationEvent.CONTENT_PAUSE]: CustomEvent<void> | HTMLElementEventMap['pause'];
/**
* @inheritdoc IntegrationEvent.CONTENT_VOLUME_CHANGE
* @eventProperty
*/
[IntegrationEvent.CONTENT_VOLUME_CHANGE]: CustomEvent<void> | HTMLElementEventMap['volumechange'];
/**
* @inheritdoc IntegrationEvent.CONTENT_RATECHANGE
* @eventProperty
*/
[IntegrationEvent.CONTENT_RATECHANGE]: CustomEvent<void> | HTMLElementEventMap['ratechange'];
/**
* @inheritdoc IntegrationEvent.CONTENT_ENDED
* @eventProperty
*/
[IntegrationEvent.CONTENT_ENDED]: CustomEvent<void> | HTMLElementEventMap['ended'];
/**
* @inheritdoc IntegrationEvent.AD_BREAK_REQUEST
* @eventProperty
*/
[IntegrationEvent.AD_BREAK_REQUEST]: CustomEvent<{
name: string;
index: number;
plannedSlotCount: number;
plannedAdRequestCount: number;
}>;
/**
* @inheritdoc IntegrationEvent.AD_BREAK_REQUEST_ERROR
* @eventProperty
*/
[IntegrationEvent.AD_BREAK_REQUEST_ERROR]: CustomEvent<{
name: string;
index: number;
error: Error & {
code?: string;
};
}>;
/**
* @inheritdoc IntegrationEvent.AD_LOADED
* @eventProperty
*/
[IntegrationEvent.AD_LOADED]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_IMPRESSION
* @eventProperty
*/
[IntegrationEvent.AD_IMPRESSION]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_BUFFERING_START
* @eventProperty
*/
[IntegrationEvent.AD_BUFFERING_START]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_BUFFERING_END
* @eventProperty
*/
[IntegrationEvent.AD_BUFFERING_END]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_TIME_UPDATE
* @eventProperty
*/
[IntegrationEvent.AD_TIME_UPDATE]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_VOLUME_CHANGE
* @eventProperty
*/
[IntegrationEvent.AD_VOLUME_CHANGE]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_PAUSED
* @eventProperty
*/
[IntegrationEvent.AD_PAUSED]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_RESUMED
* @eventProperty
*/
[IntegrationEvent.AD_RESUMED]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_CLICK
* @eventProperty
*/
[IntegrationEvent.AD_CLICK]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_SKIPPED
* @eventProperty
*/
[IntegrationEvent.AD_SKIPPED]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_COMPLETE
* @eventProperty
*/
[IntegrationEvent.AD_COMPLETE]: CustomEvent<void>;
/**
* @inheritdoc IntegrationEvent.AD_ERROR
* @eventProperty
*/
[IntegrationEvent.AD_ERROR]: CustomEvent<{
error: AdError;
}>;
/**
* @inheritdoc IntegrationEvent.UI_INTERACTION
* @eventProperty
*/
[IntegrationEvent.UI_INTERACTION]: CustomEvent<{
action: UiAction;
}>;
}
/**
* Constants for all events dispatched by the {@link IntegrationElement}.
*
* @see {@link IntegrationElementEventMap} for a full list of event types and their payloads
*/
export declare enum IntegrationEvent {
/**
* When the integration got initialized.
* @eventProperty
*/
READY = "ready",
/**
* When the integration got aborted because of a configuration / authorization error.
* It is not triggered when the content errors.
* @eventProperty
*/
INTEGRATION_ABORT = "integrationabort",
/**
* When an ad is available.
* @eventProperty
*/
INTEGRATION_AD_AVAILABLE = "integrationadavailable",
/**
* When a passback is triggered because of no content or no ad. Only available when {@link IntegrationElement#passback} is set.
* @eventProperty
*/
INTEGRATION_PASSBACK = "integrationpassback",
/**
* When the user's consent got updated.
* See {@link IntegrationElement#consent} to get the current consent.
* @eventProperty
*/
USER_UPDATE_CONSENT = "userupdateconsent",
/**
* When the playlist is updated (e.g. new media item got added). See {@link IntegrationElement#playlist} to get the current playlist items.
* @eventProperty
*/
PLAYLIST_UPDATE = "playlistupdate",
/**
* When the player's presentation mode got changed.
* @eventProperty
*/
PLAYER_SET_PRESENTATION_MODE = "playersetpresentationmode",
/**
* When content got selected. See {@link IntegrationElement#content} to get the current content.
* @eventProperty
*/
CONTENT_SELECT = "contentselect",
/**
* When content started initially (e.g. before ad break).
* @eventProperty
*/
CONTENT_START = "contentstart",
/**
* When the first frame of the content got played back.
* @eventProperty
*/
CONTENT_IMPRESSION = "contentimpression",
/**
* When content buffering started.
* @eventProperty
*/
CONTENT_BUFFERING_START = "contentbufferingstart",
/**
* When content buffering ended.
* @eventProperty
*/
CONTENT_BUFFERING_END = "contentbufferingend",
/**
* When content got stopped (e.g. loading another content or it ended normally). The reason is provided in the payload.
* It gets triggered after a potential postroll.
* @eventProperty
*/
CONTENT_STOP = "contentstop",
/**
* When a content error occurs upon loading or playing the content.
* @eventProperty
*/
CONTENT_ERROR = "contenterror",
/**
* When a marker is reached. See {@link MediaItem#markers} how to define own markers.
* @eventProperty
*/
CONTENT_MARKER_REACHED = "contentmarkerreached",
/**
* When the content's time updates. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/timeupdate_event HTMLMediaElement.timeupdate}.
* See {@link IntegrationElement#currentTime} to get the current time.
* @eventProperty
*/
CONTENT_TIME_UPDATE = "timeupdate",
/**
* When the content is seeking. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeking_event HTMLMediaElement.seeking}.
* See {@link IntegrationElement#seeking} to get the current seeking state.
* @eventProperty
*/
CONTENT_SEEKING = "seeking",
/**
* When the content has seeked. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeked_event HTMLMediaElement.seeked}.
* @eventProperty
*/
CONTENT_SEEKED = "seeked",
/**
* When the content switches from paused to playing. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play_event HTMLMediaElement.play}.
* @eventProperty
*/
CONTENT_PLAY = "play",
/**
* When the content switches from playing to paused. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/pause_event HTMLMediaElement.pause}.
* @eventProperty
*/
CONTENT_PAUSE = "pause",
/**
* When the content's volume changes. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volumechange_event HTMLMediaElement.volumechange}.
* See {@link IntegrationElement#volume} to get the current volume.
* @eventProperty
*/
CONTENT_VOLUME_CHANGE = "volumechange",
/**
* When the content playback rate changes. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ratechange_event HTMLMediaElement.ratechange}.
* See {@link IntegrationElement#playbackRate} to get the current playback rate.
* @eventProperty
*/
CONTENT_RATECHANGE = "ratechange",
/**
* When the content reached its end. This is equal to {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended_event HTMLMediaElement.ended}.
* See {@link IntegrationElement#ended} to check if the content ended.
* @eventProperty
*/
CONTENT_ENDED = "ended",
/**
* When an ad break gets requested
*/
AD_BREAK_REQUEST = "adbreakrequest",
/**
* When an ad break request fails
*/
AD_BREAK_REQUEST_ERROR = "adbreakrequesterror",
/**
* When an ad is loaded.
* See {@link IntegrationElement#currentAd} to get the loaded ad.
* @eventProperty
*/
AD_LOADED = "adloaded",
/**
* When the first frame of the ad got played back.
* See {@link IntegrationElement#currentAd} to get the current ad.
* @eventProperty
*/
AD_IMPRESSION = "adimpression",
/**
* When the ad started buffering.
* @eventProperty
*/
AD_BUFFERING_START = "adbufferingstart",
/**
* When the ad stopped buffering.
* @eventProperty
*/
AD_BUFFERING_END = "adbufferingend",
/**
* When the ad's time updates.
* @eventProperty
*/
AD_TIME_UPDATE = "adtimeupdate",
/**
* When the ad's volume changes.
* See {@link IntegrationElement#adVolume} to get the current volume.
* @eventProperty
*/
AD_VOLUME_CHANGE = "advolumechange",
/**
* When the ad paused.
* @eventProperty
*/
AD_PAUSED = "adpaused",
/**
* When the ad resumed.
* @eventProperty
*/
AD_RESUMED = "adresumed",
/**
* When the ad was clicked.
* @eventProperty
*/
AD_CLICK = "adclick",
/**
* When the ad was skipped.
* @eventProperty
*/
AD_SKIPPED = "adskipped",
/**
* When the ad completed.
* @eventProperty
*/
AD_COMPLETE = "adcomplete",
/**
* When a non-fatal ad error occurs during playback or setup (not triggered when ad loading fails).
* @eventProperty
*/
AD_ERROR = "aderror",
/**
* When the user interacted with the UI (e.g. play, pause, seek, etc.). The specific action is provided in the payload.
* @eventProperty
*/
UI_INTERACTION = "uiinteraction"
}
/**
* Properties that can be set on the integration element.
*/
export declare interface IntegrationProperties {
/**
* The identifier for this integration. This value is used to determine the configuration and behavior of the integration.
*/
integrationId?: string;
/**
* Defines the playlist / content identifier that should be loaded and managed by the integration. It can be a single content id, a playlist id or `auto`.
* It must be empty when the content is provided via the `media-item` web components inside the integration.
*/
playlistId?: string;
/**
* Determines the index of the media item within the playlist that should be or is currently selected.
*
* This property can be used to:
* - **Switch between media items**: Set this property to navigate to a different item in the playlist (zero-based index).
* - **Get the current playlist index**: Read this property to determine which media item is currently active in the playlist.
*/
index?: number;
/**
* Hides the integration element when set to `true`.
*/
hidden?: boolean;
/**
* An optional flag that can mark the integration as if it is running in a top-level window context. Useful when the embedded iframe represents an article, which contains this integration.
*/
topLevelIframe?: boolean;
/**
* Allows the publisher to provide an optional placement attribute, which supplies additional contextual information for enhanced analytics tracking.
* This can be a simple string or a stringified JSON object. If it is a stringified JSON object, its contents are forwarded as `placementDetail`. If the object contains a property key `name`, its value will be tracked for the placement attribute.
*/
placement?: string;
env?: 'stage' | 'local';
variant?: string;
adPlayer?: string;
/**
* The {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/crossorigin crossorigin attribute}
* is used to define the CORS (Cross-Origin Resource Sharing) policy for the video element.
* Defaults to `anonymous`. If set to `none` (non-standard value) it won't require CORS headers
* for the loaded media files, though text-tracks from foreign origins then cannot be loaded.
*/
crossorigin?: '' | 'anonymous' | 'use-credentials' | 'none';
/**
* Preferred language for the current user.
* When provided, this value is used for the UI instead of the browser language detected in the environment.
* Accepts a BCP 47 language tag (e.g. "de", "en-US").
*/
userLanguage?: string;
/**
* {@inheritDoc ExtraContext}
*/
extraContext?: ExtraContext;
}
/**
* Web component that allows to register Joyn media items. It can be placed
* inside the integration element as a child.
*
* @tagname joyn-media-item
*
* @attribute id - The Joyn media ID to load.
* @attribute {stage|prod} environment - The environment to use for the provider request.
*
* @example with a joyn-media-item
*
* This only works when no `playlist-id` is assigned to `glomex-integration`
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <joyn-media-item
* id="REPLACE_WITH_JOYN_MEDIA_ID"
* ></joyn-media-item>
* </glomex-integration>
* ```
*
* @example with 2 joyn-media-items
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <joyn-media-item
* id="REPLACE_WITH_JOYN_MEDIA_ID"
* ></joyn-media-item>
* <joyn-media-item
* id="ANOTHER_JOYN_MEDIA_ID"
* ></joyn-media-item>
* </glomex-integration>
* ```
*
* @example joyn-media-item targeting the stage environment
*
* ```html
* <glomex-integration
* integration-id="REPLACE_WITH_INTEGRATION_ID"
* >
* <joyn-media-item
* id="REPLACE_WITH_JOYN_MEDIA_ID"
* environment="stage"
* ></joyn-media-item>
* </glomex-integration>
* ```
*/
export declare class JoynMediaItemElement extends MediaItemElement {
}
export declare enum KnownMarkerName {
PREROLL = "preroll",
MIDROLL = "midroll",
POSTROLL = "postroll",
FIRST_QUARTILE = "contentFirstQuartile",
MIDPOINT = "contentMidpoint",
THIRD_QUARTILE = "contentThirdQuartile",
COMPLETE = "contentComplete",
STILL_INTERESTING = "stillInteresting",
REQUEST_RECOMMENDATIONS = "requestRecommendations"
}
/**
* Loads the `<glomex-integration>` custom element by injecting the
* `integration.js` script into the document. Does nothing if the element
* is already defined.
*
* @example
* ```ts
* import { loadIntegrationComponent } from '@glomex/integration-web-component';
*
* loadIntegrationComponent();
* ```
*/
export declare function loadIntegrationComponent(): void;
/**
* Loads the variant CSS for the given integration ID by injecting a
* `<link>` element into the document head. Does nothing if the stylesheet
* is already loaded.
*
* @example
* ```ts
* import { loadIntegrationStyles } from '@glomex/integration-web-component';
*
* loadIntegrationStyles('my-integration-id');
* ```
*/
export declare function loadIntegrationStyles(integrationId: string): void;
/**
* Known markers that the integration interprets.
*/
export declare interface Marker {
/** Name of the marker */
name: KnownMarkerName;
/** Type of the marker */
type: MarkerType;
/**
* Threshold for the marker:
* - {@link MarkerType.TIME_IN_SECONDS}: seconds (use negative values to calculate position from end of content, e.g., -10 means 10 seconds before the end; only valid for VoD content)
* - {@link MarkerType.PERCENT}: percent as fraction (0-1)
* - {@link MarkerType.TIME_IN_SECONDS_RECURRING}: seconds
*/
threshold: number;
/** Whether the marker should reference watch time instead of current time. Livestreams always use watch time. */
useWatchTime?: boolean;
}
export declare enum MarkerType {
/** Triggers by time in seconds */
TIME_IN_SECONDS = "time",
/** Triggers by percentage (only works when media item has a {@link MediaItem#duration duration}) */
PERCENT = "percent",
/** Recurringly triggers by time in seconds (e.g. every 60 seconds) */
TIME_IN_SECONDS_RECURRING = "timeRecurring"
}
/**
* Represents the input description of a media asset for the player.
*
* A minimal playable `MediaItem` requires only a source — every other field is optional.
* Additional fields can be supplied to support analytics, monetization, UI enhancements, and other use cases.
* In general, the richer the metadata, the more likely the `MediaItem` can satisfy all integration requirements.
*
* Alternatively, a {@link MediaItemReference} can be passed to the player instead of a
* full `MediaItem`. A reference carries only an `id` and a `provider`, letting the player
* resolve the complete media item from that provider by ID.
*
* When the player processes a `MediaItem` (or a resolved {@link MediaItemReference}) it
* produces a {@link MediaItemResolved} — an expanded version where missing fields are
* filled with defaults (e.g. `id`, `language`, `aspectRatio`) and additional data is
* derived automatically.
*/
export declare interface MediaItem {
/**
* Unique identifier of the media item.
*/
id?: string;
/**
* Additional ids that identify the media item in other systems
*/
additionalIds?: {
originId?: string;
externalId?: string;
};
/**
* Poster image of the media item.
*/
poster?: string;
/**
* Sources of the media item.
*/
sources?: MediaSource_2[];
/**
* Array of text tracks for subtitles, captions, etc.
* These tracks apply to the whole media