UNPKG

@glomex/integration-web-component

Version:

Web component and types to integrate the glomex player

1,489 lines (1,451 loc) 87.8 kB
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