@mux/playback-core 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/errors.ts", "../src/autoplay.ts", "../src/types.ts", "../src/util.ts", "../src/preload.ts", "../src/tracks.ts"],
4
- "sourcesContent": ["import mux, { ErrorEvent } from 'mux-embed';\nimport Hls from 'hls.js';\nimport { MediaError } from './errors';\nimport { setupAutoplay } from './autoplay';\nimport { setupPreload } from './preload';\nimport { setupTracks, addTextTrack, removeTextTrack } from './tracks';\nimport { inSeekableRange, toPlaybackIdParts, getType } from './util';\nimport {\n StreamTypes,\n PlaybackTypes,\n ExtensionMimeTypeMap,\n type ValueOf,\n type PlaybackCore,\n type MuxMediaProps,\n type MuxMediaPropsInternal,\n} from './types';\n\nexport { mux, Hls, MediaError, addTextTrack, removeTextTrack };\nexport * from './types';\n\nconst userAgentStr = globalThis?.navigator?.userAgent ?? '';\nconst isAndroid = userAgentStr.toLowerCase().indexOf('android') !== -1;\nconst muxMediaState: WeakMap<HTMLMediaElement, Partial<MuxMediaProps> & { error?: MediaError }> = new WeakMap();\n\nconst MUX_VIDEO_DOMAIN = 'mux.com';\nconst MSE_SUPPORTED = Hls.isSupported?.();\nconst DEFAULT_PREFER_MSE = isAndroid;\n\nexport const generatePlayerInitTime = () => {\n return mux.utils.now();\n};\n\nexport const toMuxVideoURL = (playbackId?: string, { domain = MUX_VIDEO_DOMAIN } = {}) => {\n if (!playbackId) return undefined;\n const [idPart, queryPart = ''] = toPlaybackIdParts(playbackId);\n return `https://stream.${domain}/${idPart}.m3u8${queryPart}`;\n};\n\nexport const getError = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.error;\n};\n\nexport const initialize = (\n props: Partial<MuxMediaPropsInternal>,\n mediaEl?: HTMLMediaElement | null,\n core?: PlaybackCore\n) => {\n // Automatically tear down previously initialized mux data & hls instance if it exists.\n teardown(mediaEl, core);\n\n muxMediaState.set(mediaEl as HTMLMediaElement, {});\n const nextHlsInstance = setupHls(props, mediaEl);\n setupMux(props, mediaEl, nextHlsInstance);\n loadMedia(props, mediaEl, nextHlsInstance);\n\n const setAutoplay = setupAutoplay(props as Pick<MuxMediaProps, 'autoplay'>, mediaEl, nextHlsInstance);\n const setPreload = setupPreload(props as Pick<MuxMediaProps, 'preload' | 'src'>, mediaEl, nextHlsInstance);\n\n return {\n engine: nextHlsInstance,\n setAutoplay,\n setPreload,\n };\n};\n\nexport const teardown = (mediaEl?: HTMLMediaElement | null, core?: PlaybackCore) => {\n const hls = core?.engine;\n if (hls) {\n hls.detachMedia();\n hls.destroy();\n }\n if (mediaEl?.mux && !mediaEl.mux.deleted) {\n mediaEl.mux.destroy();\n delete mediaEl.mux;\n }\n if (mediaEl) {\n mediaEl.removeAttribute('src');\n mediaEl.load();\n mediaEl.removeEventListener('error', handleNativeError);\n mediaEl.removeEventListener('error', handleInternalError);\n mediaEl.removeEventListener('durationchange', seekInSeekableRange);\n muxMediaState.delete(mediaEl);\n mediaEl.dispatchEvent(new Event('teardown'));\n }\n};\n\n/**\n * Returns true if we should use native playback. e.g. progressive files (mp3, mp4, webm) or native HLS on Safari.\n * We should use native playback for hls media sources if we\n *\n * a) can use native playback (excluding Android, it's MSE by default)\n * b) not prefer to use MSE/hls.js if it's supported\n */\nfunction useNative(\n props: Partial<Pick<MuxMediaProps, 'preferPlayback' | 'type'>>,\n mediaEl?: Pick<HTMLMediaElement, 'canPlayType'> | null\n) {\n const type = getType(props);\n const hlsType = type === ExtensionMimeTypeMap.M3U8;\n if (!hlsType) return true;\n\n const canUseNative = !type || (mediaEl?.canPlayType(type) ?? true);\n const { preferPlayback } = props;\n\n const preferMse = preferPlayback === PlaybackTypes.MSE;\n const preferNative = preferPlayback === PlaybackTypes.NATIVE;\n const forceMse = MSE_SUPPORTED && (preferMse || DEFAULT_PREFER_MSE);\n\n return canUseNative && (preferNative || !forceMse);\n}\n\nexport const setupHls = (\n props: Partial<Pick<MuxMediaProps, 'debug' | 'streamType' | 'type' | 'startTime'>>,\n mediaEl?: Pick<HTMLMediaElement, 'canPlayType'> | null\n) => {\n const { debug, streamType, startTime: startPosition = -1 } = props;\n const type = getType(props);\n const hlsType = type === ExtensionMimeTypeMap.M3U8;\n const shouldUseNative = useNative(props, mediaEl);\n\n // 1. if we are trying to play an hls media source create hls if we should be using it \"under the hood\"\n if (hlsType && !shouldUseNative && MSE_SUPPORTED) {\n const defaultConfig = {\n backBufferLength: 30,\n renderTextTracksNatively: false,\n liveDurationInfinity: true,\n };\n const streamTypeConfig = getStreamTypeConfig(streamType);\n const hls = new Hls({\n // Kind of like preload metadata, but causes spinner.\n // autoStartLoad: false,\n debug,\n startPosition,\n ...defaultConfig,\n ...streamTypeConfig,\n });\n\n return hls;\n }\n return undefined;\n};\n\nexport const getStreamTypeConfig = (streamType?: ValueOf<StreamTypes>) => {\n // for regular live videos, set backBufferLength to 8\n if ([StreamTypes.LIVE, StreamTypes.DVR].includes(streamType as any)) {\n const liveConfig = {\n backBufferLength: 8,\n };\n\n return liveConfig;\n }\n\n // for LL Live videos, set backBufferLenght to 4 and maxFragLookUpTolerance to 0.001\n if ([StreamTypes.LL_LIVE, StreamTypes.LL_DVR].includes(streamType as any)) {\n const liveConfig = {\n backBufferLength: 4,\n maxFragLookUpTolerance: 0.001,\n };\n\n return liveConfig;\n }\n\n return {};\n};\n\nexport const isMuxVideoSrc = ({\n playbackId,\n src,\n customDomain,\n}: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'src' | 'customDomain'>>) => {\n if (!!playbackId) return true;\n // having no playback id and no src string should never actually happen, but could\n if (typeof src !== 'string') return false;\n // Include base for relative paths\n const base = window?.location.href;\n const hostname = new URL(src, base).hostname.toLocaleLowerCase();\n\n return hostname.includes(MUX_VIDEO_DOMAIN) || (!!customDomain && hostname.includes(customDomain.toLocaleLowerCase()));\n};\n\nexport const setupMux = (\n props: Partial<\n Pick<\n MuxMediaPropsInternal,\n | 'envKey'\n | 'playerInitTime'\n | 'beaconCollectionDomain'\n | 'errorTranslator'\n | 'metadata'\n | 'debug'\n | 'playerSoftwareName'\n | 'playerSoftwareVersion'\n | 'playbackId'\n | 'src'\n | 'customDomain'\n >\n >,\n mediaEl?: HTMLMediaElement | null,\n hlsjs?: Hls\n) => {\n const { envKey: env_key } = props;\n const inferredEnv = isMuxVideoSrc(props);\n\n if ((env_key || inferredEnv) && mediaEl) {\n const {\n playerInitTime: player_init_time,\n playerSoftwareName: player_software_name,\n playerSoftwareVersion: player_software_version,\n beaconCollectionDomain,\n metadata,\n debug,\n } = props;\n\n const muxEmbedErrorTranslator = (error: ErrorEvent) => {\n // mux-embed auto tracks fatal hls.js errors, turn it off.\n // playback-core will emit errors with a numeric code manually to mux-embed.\n if (typeof error.player_error_code === 'string') return false;\n\n if (typeof props.errorTranslator === 'function') {\n return props.errorTranslator(error);\n }\n\n return error;\n };\n\n mux.monitor(mediaEl, {\n debug,\n beaconCollectionDomain,\n hlsjs,\n Hls: hlsjs ? Hls : undefined,\n automaticErrorTracking: false,\n errorTranslator: muxEmbedErrorTranslator,\n data: {\n ...(env_key ? { env_key } : {}),\n // Metadata fields\n player_software_name,\n // NOTE: Adding this because there appears to be some instability on whether\n // player_software_name or player_software \"wins\" for Mux Data (CJP)\n player_software: player_software_name,\n player_software_version,\n player_init_time,\n // Use any metadata passed in programmatically (which may override the defaults above)\n ...metadata,\n },\n });\n }\n};\n\nexport const loadMedia = (\n props: Partial<Pick<MuxMediaProps, 'preferPlayback' | 'src' | 'type' | 'startTime' | 'streamType' | 'autoplay'>>,\n mediaEl?: HTMLMediaElement | null,\n hls?: Pick<\n Hls,\n | 'config'\n | 'on'\n | 'once'\n | 'startLoad'\n | 'stopLoad'\n | 'recoverMediaError'\n | 'destroy'\n | 'loadSource'\n | 'attachMedia'\n | 'liveSyncPosition'\n | 'subtitleTracks'\n | 'subtitleTrack'\n >\n) => {\n if (!mediaEl) {\n console.warn('attempting to load media before mediaEl exists');\n return;\n }\n const shouldUseNative = useNative(props, mediaEl);\n const { src } = props;\n if (mediaEl && shouldUseNative) {\n if (typeof src === 'string') {\n mediaEl.setAttribute('src', src);\n if (props.startTime) {\n (muxMediaState.get(mediaEl) ?? {}).startTime = props.startTime;\n // seekable is set to the range of the entire video once durationchange fires\n mediaEl.addEventListener('durationchange', seekInSeekableRange, { once: true });\n }\n } else {\n mediaEl.removeAttribute('src');\n }\n\n mediaEl.addEventListener('error', handleNativeError);\n mediaEl.addEventListener('error', handleInternalError);\n } else if (hls && src) {\n hls.on(Hls.Events.ERROR, (_event, data) => {\n // if (data.fatal) {\n // switch (data.type) {\n // case Hls.ErrorTypes.NETWORK_ERROR:\n // // try to recover network error\n // console.error(\"fatal network error encountered, try to recover\");\n // hls.startLoad();\n // break;\n // case Hls.ErrorTypes.MEDIA_ERROR:\n // console.error(\"fatal media error encountered, try to recover\");\n // hls.recoverMediaError();\n // break;\n // default:\n // // cannot recover\n // console.error(\n // \"unrecoverable fatal error encountered, cannot recover (check logs for more info)\"\n // );\n // hls.destroy();\n // break;\n // }\n // }\n\n const errorCodeMap: Record<string, number> = {\n [Hls.ErrorTypes.NETWORK_ERROR]: MediaError.MEDIA_ERR_NETWORK,\n [Hls.ErrorTypes.MEDIA_ERROR]: MediaError.MEDIA_ERR_DECODE,\n };\n const error = new MediaError('', errorCodeMap[data.type]);\n error.fatal = data.fatal;\n error.data = data;\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n });\n mediaEl.addEventListener('error', handleInternalError);\n\n setupTracks(mediaEl, hls);\n\n hls.attachMedia(mediaEl);\n } else {\n console.error(\n \"It looks like the video you're trying to play will not work on this system! If possible, try upgrading to the newest versions of your browser or software.\"\n );\n }\n};\n\nfunction seekInSeekableRange(event: Event) {\n const mediaEl = event.target as HTMLMediaElement;\n const startTime = muxMediaState.get(mediaEl)?.startTime;\n if (!startTime) return;\n\n if (inSeekableRange(mediaEl.seekable, mediaEl.duration, startTime)) {\n // Setting preload to `none` from `auto` was required on iOS to fix a bug\n // that caused no `timeupdate` events to fire after seeking \u00AF\\_(\u30C4)_/\u00AF\n const wasAuto = mediaEl.preload === 'auto';\n if (wasAuto) {\n mediaEl.preload = 'none';\n }\n\n mediaEl.currentTime = startTime;\n\n if (wasAuto) {\n mediaEl.preload = 'auto';\n }\n }\n}\n\nasync function handleNativeError(event: Event) {\n // Return if the event was created or modified by a script or dispatched\n // via EventTarget.dispatchEvent() preventing an infinite loop.\n if (!event.isTrusted) return;\n\n // Stop immediate propagation of the native error event, re-dispatch below!\n event.stopImmediatePropagation();\n\n const mediaEl = event.target as HTMLMediaElement;\n // Safari sometimes throws an error event with a null error.\n if (!mediaEl?.error) return;\n\n const { message, code } = mediaEl.error;\n const error = new MediaError(message, code);\n\n if (mediaEl.src && (code !== MediaError.MEDIA_ERR_DECODE || code !== undefined)) {\n // Attempt to get the response code from the video src url.\n try {\n const { status } = await fetch(mediaEl.src as RequestInfo);\n // Use the same hls.js data structure.\n error.data = { response: { code: status } };\n } catch {}\n }\n\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n}\n\n/**\n * Use a event listener instead of a function call when dispatching the Custom error\n * event so consumers are still able to disable or intercept this error event.\n * @param {Event} event\n */\nfunction handleInternalError(event: Event) {\n if (!(event instanceof CustomEvent) || !(event.detail instanceof MediaError)) return;\n\n const mediaEl = event.target as HTMLMediaElement;\n const error = event.detail;\n // Prevent tracking non-fatal errors in Mux data.\n if (!error || !error.fatal) return;\n\n (muxMediaState.get(mediaEl) ?? {}).error = error;\n\n // Only pass valid mux-embed props: player_error_code, player_error_message\n mediaEl.mux?.emit('error', {\n player_error_code: error.code,\n player_error_message: error.message,\n });\n}\n", "export class MediaError extends Error {\n static MEDIA_ERR_ABORTED = 1;\n static MEDIA_ERR_NETWORK = 2;\n static MEDIA_ERR_DECODE = 3;\n static MEDIA_ERR_SRC_NOT_SUPPORTED = 4;\n static MEDIA_ERR_ENCRYPTED = 5;\n // @see https://docs.mux.com/guides/data/monitor-html5-video-element#customize-error-tracking-behavior\n static MEDIA_ERR_CUSTOM = 100;\n\n static defaultMessages: Record<number, string> = {\n 1: 'You aborted the media playback',\n 2: 'A network error caused the media download to fail.',\n 3: 'A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.',\n 4: 'An unsupported error occurred. The server or network failed, or your browser does not support this format.',\n 5: 'The media is encrypted and there are no keys to decrypt it.',\n };\n\n name: string;\n code: number;\n fatal: boolean;\n data?: any;\n\n constructor(message?: string, code: number = MediaError.MEDIA_ERR_CUSTOM, fatal?: boolean) {\n super(message);\n this.name = 'MediaError';\n this.code = code;\n this.fatal = fatal ?? (code >= MediaError.MEDIA_ERR_NETWORK && code <= MediaError.MEDIA_ERR_ENCRYPTED);\n\n if (!this.message) {\n this.message = MediaError.defaultMessages[this.code] ?? '';\n }\n }\n}\n", "import Hls from 'hls.js';\nimport { addEventListenerWithTeardown } from './util';\nimport { ValueOf, Autoplay, AutoplayTypes, PlaybackEngine } from './types';\n\nconst AutoplayTypeValues = Object.values(AutoplayTypes);\nexport const isAutoplayValue = (value: unknown): value is Autoplay => {\n return (\n typeof value === 'boolean' ||\n (typeof value === 'string' && AutoplayTypeValues.includes(value as ValueOf<AutoplayTypes>))\n );\n};\n\n// Given a video element, will listen to lifecycle events to determine important\n// things like whether the video is live or whether the video has played\n// and then handles autoplaying the video as appropraite.\n// It works with both the native video element or hls.js.\n// This returns a method UpdateAutoplay, that allows the user to change\n// the value of the autoplay attribute and it will react appropriately.\nexport const setupAutoplay = (\n { autoplay: maybeAutoplay }: { autoplay?: Autoplay },\n mediaEl?: HTMLMediaElement | null,\n hls?: PlaybackEngine\n) => {\n if (!mediaEl) return () => undefined;\n\n let hasPlayed = false;\n let isLive = false;\n let autoplay: Autoplay = isAutoplayValue(maybeAutoplay) ? maybeAutoplay : !!maybeAutoplay;\n\n const updateHasPlayed = () => {\n // hasPlayed\n\n if (!hasPlayed) {\n addEventListenerWithTeardown(\n mediaEl,\n 'playing',\n () => {\n hasPlayed = true;\n },\n { once: true }\n );\n }\n };\n\n updateHasPlayed();\n\n // on `loadstart`\n // hasPlayed should default to false\n // we should try and autoplay\n addEventListenerWithTeardown(\n mediaEl,\n 'loadstart',\n () => {\n hasPlayed = false;\n updateHasPlayed();\n handleAutoplay(mediaEl, autoplay);\n },\n { once: true }\n );\n\n // on `loadedmetadata` we can check whether we're live in the case of native playback\n addEventListenerWithTeardown(\n mediaEl,\n 'loadstart',\n () => {\n // only update isLive here if we're using native playback\n if (!hls) {\n isLive = !Number.isFinite(mediaEl.duration);\n }\n handleAutoplay(mediaEl, autoplay);\n },\n { once: true }\n );\n\n // determine if we're live for hls.js\n if (hls) {\n hls.once(Hls.Events.LEVEL_LOADED, (e: any, data: any) => {\n isLive = data.details.live ?? false;\n });\n }\n\n // When we are not auto-playing, we should seek to the live sync position\n // This will seek first play event of *any* live video including event-type,\n // which probably shouldn't seek\n if (!autoplay) {\n const handleSeek = () => {\n // don't seek if we're not live\n if (!isLive) {\n return;\n }\n // seek to either hls.js's liveSyncPosition or the native seekable end\n if (hls?.liveSyncPosition) {\n mediaEl.currentTime = hls.liveSyncPosition;\n } else {\n if (Number.isFinite(mediaEl.seekable.end(0))) {\n mediaEl.currentTime = mediaEl.seekable.end(0);\n }\n }\n };\n if (hls) {\n addEventListenerWithTeardown(\n mediaEl,\n 'play',\n () => {\n if (mediaEl.preload === 'metadata') {\n hls.once(Hls.Events.LEVEL_UPDATED, handleSeek);\n } else {\n handleSeek();\n }\n },\n { once: true }\n );\n }\n }\n\n // this method allows us to update the value of autoplay\n // and try autoplaying appropriately.\n const updateAutoplay = (newAutoplay?: Autoplay) => {\n if (!hasPlayed) {\n autoplay = isAutoplayValue(newAutoplay) ? newAutoplay : !!newAutoplay;\n handleAutoplay(mediaEl, autoplay);\n }\n };\n\n return updateAutoplay;\n};\n\nexport const handleAutoplay = (mediaEl: HTMLMediaElement, autoplay: Autoplay) => {\n if (!autoplay) {\n return;\n }\n\n const oldMuted = mediaEl.muted;\n const restoreMuted = () => (mediaEl.muted = oldMuted);\n\n switch (autoplay) {\n // ANY:\n // try to play with current options\n // if it fails, mute and try playing again\n // if that fails, restore muted state and don't try playing again\n case AutoplayTypes.ANY:\n mediaEl.play().catch(() => {\n mediaEl.muted = true;\n mediaEl.play().catch(restoreMuted);\n });\n break;\n\n // MUTED:\n // mute the player and then try playing\n // if that fails, restore muted state\n case AutoplayTypes.MUTED:\n mediaEl.muted = true;\n mediaEl.play().catch(restoreMuted);\n break;\n\n // Default or if autoplay is a boolean attribute:\n // Try playing the video and catch the failed autoplay warning\n default: // eslint-disable-next-line\n mediaEl.play().catch(() => {});\n break;\n }\n};\n", "import { Options } from 'mux-embed';\nimport Hls, { HlsConfig } from 'hls.js';\n\ntype KeyTypes = string | number | symbol;\n\n// Type Guard to determine if a given key is actually a key of some object of type T\nexport const isKeyOf = <T = any>(k: KeyTypes, o: T): k is keyof T => {\n return k in o;\n};\n\nexport type ValueOf<T> = T[keyof T];\nexport type Metadata = Partial<Options['data']>;\nexport type PlaybackEngine = Hls;\n\nexport type PlaybackCore = {\n engine?: PlaybackEngine;\n setAutoplay: (autoplay?: Autoplay) => void;\n setPreload: (preload?: HTMLMediaElement['preload']) => void;\n};\n\n// TODO add INVIEW_MUTED, INVIEW_ANY\nexport type AutoplayTypes = {\n ANY: 'any';\n MUTED: 'muted';\n};\n\nexport const AutoplayTypes: AutoplayTypes = {\n ANY: 'any',\n MUTED: 'muted',\n};\n\nexport type Autoplay = boolean | ValueOf<AutoplayTypes>;\n\nexport type StreamTypes = {\n VOD: 'on-demand';\n ON_DEMAND: 'on-demand';\n LIVE: 'live';\n LL_LIVE: 'll-live';\n DVR: 'live:dvr';\n LL_DVR: 'll-live:dvr';\n};\n\nexport const StreamTypes: StreamTypes = {\n VOD: 'on-demand',\n ON_DEMAND: 'on-demand',\n LIVE: 'live',\n LL_LIVE: 'll-live',\n DVR: 'live:dvr',\n LL_DVR: 'll-live:dvr',\n};\n\nexport type PlaybackTypes = {\n MSE: 'mse';\n NATIVE: 'native';\n};\n\nexport const PlaybackTypes: PlaybackTypes = {\n MSE: 'mse',\n NATIVE: 'native',\n};\n\nexport type ExtensionMimeTypeMap = {\n M3U8: 'application/vnd.apple.mpegurl';\n MP4: 'video/mp4';\n};\n\nexport const ExtensionMimeTypeMap: ExtensionMimeTypeMap = {\n M3U8: 'application/vnd.apple.mpegurl',\n MP4: 'video/mp4',\n};\n\nexport type MimeTypeShorthandMap = {\n HLS: ExtensionMimeTypeMap['M3U8'];\n};\n\nexport const MimeTypeShorthandMap: MimeTypeShorthandMap = {\n HLS: ExtensionMimeTypeMap.M3U8,\n};\n\nexport const shorthandKeys = Object.keys(MimeTypeShorthandMap);\n\nexport type MediaTypes =\n | ValueOf<ExtensionMimeTypeMap>\n | keyof MimeTypeShorthandMap\n /** @TODO Figure out a way to \"downgrade\" derived types below to early TS syntax (e.g. 3.4) instead of explicit versions here (CJP) */\n | 'hls';\n// | `${Lowercase<keyof MimeTypeShorthandMap>}`\n// | `${Uppercase<keyof MimeTypeShorthandMap>}`;\n\nexport const allMediaTypes = [\n ...(Object.values(ExtensionMimeTypeMap) as ValueOf<ExtensionMimeTypeMap>[]),\n /** @TODO Figure out a way to \"downgrade\" derived types below to early TS syntax (e.g. 3.4) instead of explicit versions here (CJP) */\n 'hls',\n 'HLS',\n // ...(shorthandKeys as (keyof MimeTypeShorthandMap)[]),\n // ...(shorthandKeys.map((k) => k.toUpperCase()) as `${Uppercase<keyof MimeTypeShorthandMap>}`[]),\n // ...(shorthandKeys.map((k) => k.toLowerCase()) as `${Lowercase<keyof MimeTypeShorthandMap>}`[]),\n] as MediaTypes[];\n\nexport type MuxMediaPropTypes = {\n envKey: Options['data']['env_key'];\n debug: Options['debug'] & Hls['config']['debug'];\n metadata: Partial<Options['data']>;\n customDomain: string;\n beaconCollectionDomain: Options['beaconCollectionDomain'];\n errorTranslator: Options['errorTranslator'];\n playbackId: string;\n playerInitTime: Options['data']['player_init_time'];\n preferPlayback: ValueOf<PlaybackTypes> | undefined;\n type: MediaTypes;\n streamType: ValueOf<StreamTypes>;\n startTime: HlsConfig['startPosition'];\n autoPlay?: Autoplay;\n autoplay?: Autoplay;\n};\n\nexport type HTMLMediaElementProps = Partial<Pick<HTMLMediaElement, 'src' | 'preload'>>;\n\nexport type MuxMediaProps = HTMLMediaElementProps & MuxMediaPropTypes;\nexport type MuxMediaPropsInternal = MuxMediaProps & {\n playerSoftwareName: Options['data']['player_software_name'];\n playerSoftwareVersion: Options['data']['player_software_version'];\n};\n", "import { isKeyOf, ExtensionMimeTypeMap, MimeTypeShorthandMap, type MuxMediaProps } from './types';\n\ntype addEventListenerWithTeardown = <K extends keyof HTMLMediaElementEventMap>(\n mediaEl: HTMLMediaElement,\n type: K,\n listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions\n) => void;\n\n// Adds an event listener to a media element that will be removed when an 'teardown' event is dispatched.\n// Using this instead of 'emptied' as that can fire on initial load based on prior state of the media element\n// Will be fired as a result of (directly or indirectly) invoking playback-core's `teardown()` function.\nexport const addEventListenerWithTeardown: addEventListenerWithTeardown = (mediaEl, type, listener, options) => {\n mediaEl.addEventListener(type, listener, options);\n // NOTE: Using custom teardown\n mediaEl.addEventListener(\n 'teardown',\n () => {\n mediaEl.removeEventListener(type, listener);\n },\n { once: true }\n );\n};\n\nexport function inSeekableRange(seekable: TimeRanges, duration: number, time: number) {\n if (duration && time > duration) {\n time = duration;\n }\n for (let i = 0; i < seekable.length ?? 0; i++) {\n if (seekable.start(i) <= time && seekable.end(i) >= time) {\n return true;\n }\n }\n return false;\n}\n\nexport const toPlaybackIdParts = (playbackIdWithOptionalParams: string): [string, string?] => {\n const qIndex = playbackIdWithOptionalParams.indexOf('?');\n if (qIndex < 0) return [playbackIdWithOptionalParams];\n const idPart = playbackIdWithOptionalParams.slice(0, qIndex);\n const queryPart = playbackIdWithOptionalParams.slice(qIndex);\n return [idPart, queryPart];\n};\n\nexport const getType = (props: Partial<Pick<MuxMediaProps, 'type' | 'src'>>) => {\n const type = props.type;\n if (type) {\n const upperType = type.toUpperCase();\n return isKeyOf(upperType, MimeTypeShorthandMap) ? MimeTypeShorthandMap[upperType] : type;\n }\n\n const { src } = props;\n if (!src) return '';\n\n return inferMimeTypeFromURL(src);\n};\n\nexport const inferMimeTypeFromURL = (url: string) => {\n let pathname = '';\n try {\n pathname = new URL(url).pathname;\n } catch (e) {\n console.error('invalid url');\n }\n\n const extDelimIdx = pathname.lastIndexOf('.');\n if (extDelimIdx < 0) return '';\n\n const ext = pathname.slice(extDelimIdx + 1);\n const upperExt = ext.toUpperCase();\n\n return isKeyOf(upperExt, ExtensionMimeTypeMap) ? ExtensionMimeTypeMap[upperExt] : '';\n};\n", "import { addEventListenerWithTeardown } from './util';\nimport { PlaybackEngine } from './types';\n\nexport const setupPreload = (\n { preload, src }: Partial<HTMLMediaElement>,\n mediaEl?: HTMLMediaElement | null,\n hls?: PlaybackEngine\n) => {\n if (!mediaEl) return () => undefined;\n\n const updatePreload = (val?: HTMLMediaElement['preload']) => {\n if (val != null && ['', 'none', 'metadata', 'auto'].includes(val)) {\n mediaEl.setAttribute('preload', val);\n } else {\n mediaEl.removeAttribute('preload');\n }\n };\n\n // handle native without hls.js (MSE)\n if (!hls) {\n updatePreload(preload);\n return updatePreload;\n }\n\n let hasLoadedSource = false;\n let hasPlayFired = false;\n\n const originalLength = hls.config.maxBufferLength;\n const originalSize = hls.config.maxBufferSize;\n\n const updateHlsPreload = (val?: HTMLMediaElement['preload']) => {\n // even if it doesn't have an effect on a <video> w/ MSE\n // still update the `preload` attribute.\n updatePreload(val);\n\n const newPreload = val ?? mediaEl.preload;\n if (hasPlayFired || newPreload === 'none') return;\n if (newPreload === 'metadata') {\n // load the least amount of data possible\n hls.config.maxBufferLength = 1;\n hls.config.maxBufferSize = 1;\n } else {\n hls.config.maxBufferLength = originalLength;\n hls.config.maxBufferSize = originalSize;\n }\n\n safeLoadSource();\n };\n\n const safeLoadSource = () => {\n if (!hasLoadedSource && src) {\n hasLoadedSource = true;\n hls.loadSource(src);\n }\n };\n\n addEventListenerWithTeardown(\n mediaEl,\n 'play',\n () => {\n hasPlayFired = true;\n\n // once a user has played, allow for it to load data as normal\n hls.config.maxBufferLength = originalLength;\n hls.config.maxBufferSize = originalSize;\n\n // load the source on first play if needed\n safeLoadSource();\n },\n { once: true }\n );\n\n updateHlsPreload(preload);\n\n return updateHlsPreload;\n};\n", "import Hls from 'hls.js';\n\nexport function setupTracks(\n mediaEl: HTMLMediaElement,\n hls: Pick<Hls, 'on' | 'once' | 'subtitleTracks' | 'subtitleTrack'>\n) {\n hls.on(Hls.Events.NON_NATIVE_TEXT_TRACKS_FOUND, (_type, { tracks }) => {\n tracks.forEach((trackObj) => {\n const baseTrackObj = trackObj.subtitleTrack ?? trackObj.closedCaptions;\n const idx = hls.subtitleTracks.findIndex(({ lang, name, type }) => {\n return lang == baseTrackObj?.lang && name === trackObj.label && type.toLowerCase() === trackObj.kind;\n });\n\n addTextTrack(\n mediaEl,\n trackObj.kind as TextTrackKind,\n trackObj.label,\n baseTrackObj?.lang,\n `${trackObj.kind}${idx}`\n );\n });\n });\n\n const changeHandler = () => {\n if (!hls.subtitleTracks.length) return;\n\n const showingTrack = Array.from(mediaEl.textTracks).find((textTrack) => {\n return textTrack.id && textTrack.mode === 'showing' && ['subtitles', 'captions'].includes(textTrack.kind);\n });\n\n // If hls.subtitleTrack is -1 or its id changed compared to the one that is showing load the new subtitle track.\n const hlsTrackId = `${hls.subtitleTracks[hls.subtitleTrack]?.type.toLowerCase()}${hls.subtitleTrack}`;\n if (showingTrack && (hls.subtitleTrack < 0 || showingTrack?.id !== hlsTrackId)) {\n const idx = hls.subtitleTracks.findIndex(({ lang, name, type }) => {\n return lang == showingTrack.language && name === showingTrack.label && type.toLowerCase() === showingTrack.kind;\n });\n // After the subtitleTrack is set here, hls.js will load the playlist and CUES_PARSED events will be fired below.\n hls.subtitleTrack = idx;\n }\n\n if (showingTrack && showingTrack?.id === hlsTrackId) {\n // Refresh the cues after a texttrack mode change to fix a Chrome bug causing the captions not to render.\n if (showingTrack.cues) {\n Array.from(showingTrack.cues).forEach((cue) => {\n showingTrack.addCue(cue);\n });\n }\n }\n };\n\n mediaEl.textTracks.addEventListener('change', changeHandler);\n\n hls.on(Hls.Events.CUES_PARSED, (_type, { track, cues }) => {\n const textTrack = mediaEl.textTracks.getTrackById(track);\n if (!textTrack) return;\n\n const disabled = textTrack.mode === 'disabled';\n if (disabled) {\n textTrack.mode = 'hidden';\n }\n\n cues.forEach((cue: VTTCue) => {\n if (textTrack.cues?.getCueById(cue.id)) return;\n textTrack.addCue(cue);\n });\n\n if (disabled) {\n textTrack.mode = 'disabled';\n }\n });\n\n // NOTE: Since this is only relevant for hls, using destroying event (CJP).\n hls.once(Hls.Events.DESTROYING, () => {\n mediaEl.textTracks.removeEventListener('change', changeHandler);\n // Use data attribute to identify tracks that should be removed when switching sources/destroying hls.js instance.\n const trackEls: NodeListOf<HTMLTrackElement> = mediaEl.querySelectorAll('track[data-removeondestroy]');\n trackEls.forEach((trackEl) => {\n trackEl.remove();\n });\n });\n\n const forceHiddenThumbnails = () => {\n // Keeping this a forEach in case we want to expand the scope of this.\n Array.from(mediaEl.textTracks).forEach((track) => {\n if (['subtitles', 'caption'].includes(track.kind)) return;\n if (track.label !== 'thumbnails') return;\n if (!track.cues?.length) {\n const trackEl = mediaEl.querySelector('track[label=\"thumbnails\"]');\n // Force a reload of the cues if they've been removed\n const src = trackEl?.getAttribute('src') ?? '';\n trackEl?.removeAttribute('src');\n setTimeout(() => {\n trackEl?.setAttribute('src', src);\n }, 0);\n }\n // Force hidden mode if it's not hidden\n if (track.mode !== 'hidden') {\n track.mode = 'hidden';\n }\n });\n };\n\n // hls.js will forcibly clear all cues from tracks on manifest loads or media attaches.\n // This ensures that we re-load them after it's done that.\n hls.once(Hls.Events.MANIFEST_LOADED, forceHiddenThumbnails);\n hls.once(Hls.Events.MEDIA_ATTACHED, forceHiddenThumbnails);\n}\n\nexport function addTextTrack(\n mediaEl: HTMLMediaElement,\n kind: TextTrackKind,\n label: string,\n lang?: string,\n id?: string\n): TextTrack | undefined {\n const trackEl = document.createElement('track');\n trackEl.kind = kind;\n trackEl.label = label;\n if (lang) {\n // This attribute must be present if the element's kind attribute is in the subtitles state.\n trackEl.srclang = lang;\n }\n if (id) {\n trackEl.id = id;\n }\n trackEl.track.mode = 'disabled';\n // Add data attribute to identify tracks that should be removed when switching sources/destroying hls.js instance.\n trackEl.setAttribute('data-removeondestroy', '');\n mediaEl.append(trackEl);\n return trackEl.track;\n}\n\nexport function removeTextTrack(mediaEl: HTMLMediaElement, track: TextTrack) {\n const trackElement: HTMLTrackElement | undefined = Array.prototype.find.call(\n mediaEl.querySelectorAll('track'),\n (trackEl: HTMLTrackElement) => trackEl.track === track\n );\n trackElement?.remove();\n}\n"],
5
- "mappings": "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",
6
- "names": ["mux", "Hls", "_MediaError", "message", "code", "fatal", "_a", "MediaError", "Hls", "isKeyOf", "k", "o", "AutoplayTypes", "StreamTypes", "PlaybackTypes", "ExtensionMimeTypeMap", "MimeTypeShorthandMap", "shorthandKeys", "allMediaTypes", "addEventListenerWithTeardown", "mediaEl", "type", "listener", "options", "inSeekableRange", "seekable", "duration", "time", "i", "toPlaybackIdParts", "playbackIdWithOptionalParams", "qIndex", "idPart", "queryPart", "getType", "props", "upperType", "isKeyOf", "MimeTypeShorthandMap", "src", "inferMimeTypeFromURL", "url", "pathname", "extDelimIdx", "upperExt", "ExtensionMimeTypeMap", "AutoplayTypeValues", "AutoplayTypes", "isAutoplayValue", "value", "setupAutoplay", "maybeAutoplay", "mediaEl", "hls", "hasPlayed", "isLive", "autoplay", "updateHasPlayed", "addEventListenerWithTeardown", "handleAutoplay", "Hls", "e", "data", "_a", "handleSeek", "newAutoplay", "oldMuted", "restoreMuted", "setupPreload", "preload", "src", "mediaEl", "hls", "updatePreload", "val", "hasLoadedSource", "hasPlayFired", "originalLength", "originalSize", "updateHlsPreload", "newPreload", "safeLoadSource", "addEventListenerWithTeardown", "Hls", "setupTracks", "mediaEl", "hls", "_type", "tracks", "trackObj", "_a", "baseTrackObj", "idx", "lang", "name", "type", "addTextTrack", "changeHandler", "showingTrack", "textTrack", "hlsTrackId", "cue", "track", "cues", "disabled", "trackEl", "forceHiddenThumbnails", "_b", "src", "kind", "label", "id", "removeTextTrack", "trackElement", "_a", "_b", "userAgentStr", "isAndroid", "muxMediaState", "MUX_VIDEO_DOMAIN", "MSE_SUPPORTED", "Hls", "DEFAULT_PREFER_MSE", "generatePlayerInitTime", "mux", "toMuxVideoURL", "playbackId", "domain", "idPart", "queryPart", "toPlaybackIdParts", "getError", "mediaEl", "initialize", "props", "core", "teardown", "nextHlsInstance", "setupHls", "setupMux", "loadMedia", "setAutoplay", "setupAutoplay", "setPreload", "setupPreload", "hls", "handleNativeError", "handleInternalError", "seekInSeekableRange", "useNative", "type", "getType", "ExtensionMimeTypeMap", "canUseNative", "preferPlayback", "preferMse", "PlaybackTypes", "preferNative", "debug", "streamType", "startPosition", "hlsType", "shouldUseNative", "defaultConfig", "streamTypeConfig", "getStreamTypeConfig", "StreamTypes", "isMuxVideoSrc", "src", "customDomain", "base", "hostname", "hlsjs", "env_key", "inferredEnv", "player_init_time", "player_software_name", "player_software_version", "beaconCollectionDomain", "metadata", "muxEmbedErrorTranslator", "error", "_event", "data", "errorCodeMap", "MediaError", "setupTracks", "event", "startTime", "inSeekableRange", "wasAuto", "message", "code", "status"]
4
+ "sourcesContent": ["import mux, { ErrorEvent } from 'mux-embed';\nimport Hls from 'hls.js';\nimport { MediaError } from './errors';\nimport { setupAutoplay } from './autoplay';\nimport { setupPreload } from './preload';\nimport { setupTracks, addTextTrack, removeTextTrack } from './tracks';\nimport { inSeekableRange, toPlaybackIdParts, getType } from './util';\nimport {\n StreamTypes,\n PlaybackTypes,\n ExtensionMimeTypeMap,\n CmcdTypes,\n type ValueOf,\n type PlaybackCore,\n type MuxMediaProps,\n type MuxMediaPropsInternal,\n} from './types';\n\nexport { mux, Hls, MediaError, addTextTrack, removeTextTrack };\nexport * from './types';\n\nconst userAgentStr = globalThis?.navigator?.userAgent ?? '';\nconst isAndroid = userAgentStr.toLowerCase().indexOf('android') !== -1;\nconst muxMediaState: WeakMap<HTMLMediaElement, Partial<MuxMediaProps> & { error?: MediaError }> = new WeakMap();\n\nconst MUX_VIDEO_DOMAIN = 'mux.com';\nconst MSE_SUPPORTED = Hls.isSupported?.();\nconst DEFAULT_PREFER_MSE = isAndroid;\n\nexport const generatePlayerInitTime = () => {\n return mux.utils.now();\n};\n\nexport const generateUUID = mux.utils.generateUUID;\n\nexport const toMuxVideoURL = (playbackId?: string, { domain = MUX_VIDEO_DOMAIN } = {}) => {\n if (!playbackId) return undefined;\n const [idPart, queryPart = ''] = toPlaybackIdParts(playbackId);\n return `https://stream.${domain}/${idPart}.m3u8${queryPart}`;\n};\n\nconst toPlaybackIdFromParameterized = (playbackIdWithParams: string | undefined) => {\n if (!playbackIdWithParams) return undefined;\n const [playbackId] = playbackIdWithParams.split('?');\n // `|| undefined` is here to handle potential invalid cases\n return playbackId || undefined;\n};\n\nconst toPlaybackIdFromSrc = (src: string | undefined) => {\n if (!src || !src.startsWith('https://stream.')) return undefined;\n const [playbackId] = new URL(src).pathname.slice(1).split('.m3u8');\n // `|| undefined` is here to handle potential invalid cases\n return playbackId || undefined;\n};\n\nconst toVideoId = (props: Partial<MuxMediaPropsInternal>) => {\n if (props?.metadata?.video_id) return props.metadata.video_id;\n if (!isMuxVideoSrc(props)) return props.src;\n return toPlaybackIdFromParameterized(props.playbackId) ?? toPlaybackIdFromSrc(props.src) ?? props.src;\n};\n\nexport const getError = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.error;\n};\n\nexport const initialize = (props: Partial<MuxMediaPropsInternal>, mediaEl: HTMLMediaElement, core?: PlaybackCore) => {\n // Automatically tear down previously initialized mux data & hls instance if it exists.\n teardown(mediaEl, core);\n // NOTE: metadata should never be nullish/nil. Adding here for type safety due to current type defs.\n const { metadata = {} } = props;\n const { view_session_id = generateUUID() } = metadata;\n const video_id = toVideoId(props);\n metadata.view_session_id = view_session_id;\n metadata.video_id = video_id;\n props.metadata = metadata;\n\n muxMediaState.set(mediaEl as HTMLMediaElement, {});\n const nextHlsInstance = setupHls(props, mediaEl);\n setupMux(props, mediaEl, nextHlsInstance);\n loadMedia(props, mediaEl, nextHlsInstance);\n\n const setAutoplay = setupAutoplay(props as Pick<MuxMediaProps, 'autoplay'>, mediaEl, nextHlsInstance);\n const setPreload = setupPreload(props as Pick<MuxMediaProps, 'preload' | 'src'>, mediaEl, nextHlsInstance);\n\n return {\n engine: nextHlsInstance,\n setAutoplay,\n setPreload,\n };\n};\n\nexport const teardown = (mediaEl?: HTMLMediaElement | null, core?: PlaybackCore) => {\n const hls = core?.engine;\n if (hls) {\n hls.detachMedia();\n hls.destroy();\n }\n if (mediaEl?.mux && !mediaEl.mux.deleted) {\n mediaEl.mux.destroy();\n delete mediaEl.mux;\n }\n if (mediaEl) {\n mediaEl.removeAttribute('src');\n mediaEl.load();\n mediaEl.removeEventListener('error', handleNativeError);\n mediaEl.removeEventListener('error', handleInternalError);\n mediaEl.removeEventListener('durationchange', seekInSeekableRange);\n muxMediaState.delete(mediaEl);\n mediaEl.dispatchEvent(new Event('teardown'));\n }\n};\n\n/**\n * Returns true if we should use native playback. e.g. progressive files (mp3, mp4, webm) or native HLS on Safari.\n * We should use native playback for hls media sources if we\n *\n * a) can use native playback (excluding Android, it's MSE by default)\n * b) not prefer to use MSE/hls.js if it's supported\n */\nfunction useNative(\n props: Partial<Pick<MuxMediaProps, 'preferPlayback' | 'type'>>,\n mediaEl: Pick<HTMLMediaElement, 'canPlayType'>\n) {\n const type = getType(props);\n const hlsType = type === ExtensionMimeTypeMap.M3U8;\n if (!hlsType) return true;\n\n const canUseNative = !type || (mediaEl.canPlayType(type) ?? true);\n const { preferPlayback } = props;\n\n const preferMse = preferPlayback === PlaybackTypes.MSE;\n const preferNative = preferPlayback === PlaybackTypes.NATIVE;\n const forceMse = MSE_SUPPORTED && (preferMse || DEFAULT_PREFER_MSE);\n\n return canUseNative && (preferNative || !forceMse);\n}\n\nexport const setupHls = (\n props: Partial<\n Pick<\n MuxMediaPropsInternal,\n 'debug' | 'streamType' | 'type' | 'startTime' | 'metadata' | 'experimentalCmcd' | 'preferCmcd'\n >\n >,\n mediaEl: Pick<HTMLMediaElement, 'canPlayType'>\n) => {\n const { debug, streamType, startTime: startPosition = -1, metadata, experimentalCmcd, preferCmcd } = props;\n const type = getType(props);\n const hlsType = type === ExtensionMimeTypeMap.M3U8;\n const shouldUseNative = useNative(props, mediaEl);\n\n // 1. if we are trying to play an hls media source create hls if we should be using it \"under the hood\"\n if (hlsType && !shouldUseNative && MSE_SUPPORTED) {\n const defaultConfig = {\n backBufferLength: 30,\n renderTextTracksNatively: false,\n liveDurationInfinity: true,\n };\n const streamTypeConfig = getStreamTypeConfig(streamType);\n const cmcd = experimentalCmcd\n ? {\n useHeaders: preferCmcd === CmcdTypes.HEADER,\n sessionId: metadata.view_session_id,\n contentId: metadata.video_id,\n }\n : undefined;\n const hls = new Hls({\n // Kind of like preload metadata, but causes spinner.\n // autoStartLoad: false,\n debug,\n startPosition,\n cmcd,\n ...defaultConfig,\n ...streamTypeConfig,\n });\n\n return hls;\n }\n return undefined;\n};\n\nexport const getStreamTypeConfig = (streamType?: ValueOf<StreamTypes>) => {\n // for regular live videos, set backBufferLength to 8\n if ([StreamTypes.LIVE, StreamTypes.DVR].includes(streamType as any)) {\n const liveConfig = {\n backBufferLength: 8,\n };\n\n return liveConfig;\n }\n\n // for LL Live videos, set backBufferLenght to 4 and maxFragLookUpTolerance to 0.001\n if ([StreamTypes.LL_LIVE, StreamTypes.LL_DVR].includes(streamType as any)) {\n const liveConfig = {\n backBufferLength: 4,\n maxFragLookUpTolerance: 0.001,\n };\n\n return liveConfig;\n }\n\n return {};\n};\n\nexport const isMuxVideoSrc = ({\n playbackId,\n src,\n customDomain,\n}: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'src' | 'customDomain'>>) => {\n if (!!playbackId) return true;\n // having no playback id and no src string should never actually happen, but could\n if (typeof src !== 'string') return false;\n // Include base for relative paths\n const base = window?.location.href;\n const hostname = new URL(src, base).hostname.toLocaleLowerCase();\n\n return hostname.includes(MUX_VIDEO_DOMAIN) || (!!customDomain && hostname.includes(customDomain.toLocaleLowerCase()));\n};\n\nexport const setupMux = (\n props: Partial<\n Pick<\n MuxMediaPropsInternal,\n | 'envKey'\n | 'playerInitTime'\n | 'beaconCollectionDomain'\n | 'errorTranslator'\n | 'metadata'\n | 'debug'\n | 'playerSoftwareName'\n | 'playerSoftwareVersion'\n | 'playbackId'\n | 'src'\n | 'customDomain'\n | 'disableCookies'\n >\n >,\n mediaEl: HTMLMediaElement,\n hlsjs?: Hls\n) => {\n const { envKey: env_key } = props;\n const inferredEnv = isMuxVideoSrc(props);\n\n if (env_key || inferredEnv) {\n const {\n playerInitTime: player_init_time,\n playerSoftwareName: player_software_name,\n playerSoftwareVersion: player_software_version,\n beaconCollectionDomain,\n debug,\n disableCookies,\n } = props;\n\n const metadata = {\n ...props.metadata,\n video_title: props?.metadata?.video_title || undefined,\n };\n\n const muxEmbedErrorTranslator = (error: ErrorEvent) => {\n // mux-embed auto tracks fatal hls.js errors, turn it off.\n // playback-core will emit errors with a numeric code manually to mux-embed.\n if (typeof error.player_error_code === 'string') return false;\n\n if (typeof props.errorTranslator === 'function') {\n return props.errorTranslator(error);\n }\n\n return error;\n };\n\n mux.monitor(mediaEl, {\n debug,\n beaconCollectionDomain,\n hlsjs,\n Hls: hlsjs ? Hls : undefined,\n automaticErrorTracking: false,\n errorTranslator: muxEmbedErrorTranslator,\n disableCookies,\n data: {\n ...(env_key ? { env_key } : {}),\n // Metadata fields\n player_software_name,\n // NOTE: Adding this because there appears to be some instability on whether\n // player_software_name or player_software \"wins\" for Mux Data (CJP)\n player_software: player_software_name,\n player_software_version,\n player_init_time,\n // Use any metadata passed in programmatically (which may override the defaults above)\n ...metadata,\n },\n });\n }\n};\n\nexport const loadMedia = (\n props: Partial<Pick<MuxMediaProps, 'preferPlayback' | 'src' | 'type' | 'startTime' | 'streamType' | 'autoplay'>>,\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n | 'config'\n | 'on'\n | 'once'\n | 'startLoad'\n | 'stopLoad'\n | 'recoverMediaError'\n | 'destroy'\n | 'loadSource'\n | 'attachMedia'\n | 'liveSyncPosition'\n | 'subtitleTracks'\n | 'subtitleTrack'\n >\n) => {\n const shouldUseNative = useNative(props, mediaEl);\n const { src } = props;\n if (mediaEl && shouldUseNative) {\n if (typeof src === 'string') {\n mediaEl.setAttribute('src', src);\n if (props.startTime) {\n (muxMediaState.get(mediaEl) ?? {}).startTime = props.startTime;\n // seekable is set to the range of the entire video once durationchange fires\n mediaEl.addEventListener('durationchange', seekInSeekableRange, { once: true });\n }\n } else {\n mediaEl.removeAttribute('src');\n }\n\n mediaEl.addEventListener('error', handleNativeError);\n mediaEl.addEventListener('error', handleInternalError);\n } else if (hls && src) {\n hls.on(Hls.Events.ERROR, (_event, data) => {\n // if (data.fatal) {\n // switch (data.type) {\n // case Hls.ErrorTypes.NETWORK_ERROR:\n // // try to recover network error\n // console.error(\"fatal network error encountered, try to recover\");\n // hls.startLoad();\n // break;\n // case Hls.ErrorTypes.MEDIA_ERROR:\n // console.error(\"fatal media error encountered, try to recover\");\n // hls.recoverMediaError();\n // break;\n // default:\n // // cannot recover\n // console.error(\n // \"unrecoverable fatal error encountered, cannot recover (check logs for more info)\"\n // );\n // hls.destroy();\n // break;\n // }\n // }\n\n const errorCodeMap: Record<string, number> = {\n [Hls.ErrorTypes.NETWORK_ERROR]: MediaError.MEDIA_ERR_NETWORK,\n [Hls.ErrorTypes.MEDIA_ERROR]: MediaError.MEDIA_ERR_DECODE,\n };\n const error = new MediaError('', errorCodeMap[data.type]);\n error.fatal = data.fatal;\n error.data = data;\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n });\n mediaEl.addEventListener('error', handleInternalError);\n\n setupTracks(mediaEl, hls);\n\n hls.attachMedia(mediaEl);\n } else {\n console.error(\n \"It looks like the video you're trying to play will not work on this system! If possible, try upgrading to the newest versions of your browser or software.\"\n );\n }\n};\n\nfunction seekInSeekableRange(event: Event) {\n const mediaEl = event.target as HTMLMediaElement;\n const startTime = muxMediaState.get(mediaEl)?.startTime;\n if (!startTime) return;\n\n if (inSeekableRange(mediaEl.seekable, mediaEl.duration, startTime)) {\n // Setting preload to `none` from `auto` was required on iOS to fix a bug\n // that caused no `timeupdate` events to fire after seeking \u00AF\\_(\u30C4)_/\u00AF\n const wasAuto = mediaEl.preload === 'auto';\n if (wasAuto) {\n mediaEl.preload = 'none';\n }\n\n mediaEl.currentTime = startTime;\n\n if (wasAuto) {\n mediaEl.preload = 'auto';\n }\n }\n}\n\nasync function handleNativeError(event: Event) {\n // Return if the event was created or modified by a script or dispatched\n // via EventTarget.dispatchEvent() preventing an infinite loop.\n if (!event.isTrusted) return;\n\n // Stop immediate propagation of the native error event, re-dispatch below!\n event.stopImmediatePropagation();\n\n const mediaEl = event.target as HTMLMediaElement;\n // Safari sometimes throws an error event with a null error.\n if (!mediaEl?.error) return;\n\n const { message, code } = mediaEl.error;\n const error = new MediaError(message, code);\n\n if (mediaEl.src && (code !== MediaError.MEDIA_ERR_DECODE || code !== undefined)) {\n // Attempt to get the response code from the video src url.\n try {\n const { status } = await fetch(mediaEl.src as RequestInfo);\n // Use the same hls.js data structure.\n error.data = { response: { code: status } };\n } catch {}\n }\n\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n}\n\n/**\n * Use a event listener instead of a function call when dispatching the Custom error\n * event so consumers are still able to disable or intercept this error event.\n * @param {Event} event\n */\nfunction handleInternalError(event: Event) {\n if (!(event instanceof CustomEvent) || !(event.detail instanceof MediaError)) return;\n\n const mediaEl = event.target as HTMLMediaElement;\n const error = event.detail;\n // Prevent tracking non-fatal errors in Mux data.\n if (!error || !error.fatal) return;\n\n (muxMediaState.get(mediaEl) ?? {}).error = error;\n\n // Only pass valid mux-embed props: player_error_code, player_error_message\n mediaEl.mux?.emit('error', {\n player_error_code: error.code,\n player_error_message: error.message,\n });\n}\n", "export class MediaError extends Error {\n static MEDIA_ERR_ABORTED = 1;\n static MEDIA_ERR_NETWORK = 2;\n static MEDIA_ERR_DECODE = 3;\n static MEDIA_ERR_SRC_NOT_SUPPORTED = 4;\n static MEDIA_ERR_ENCRYPTED = 5;\n // @see https://docs.mux.com/guides/data/monitor-html5-video-element#customize-error-tracking-behavior\n static MEDIA_ERR_CUSTOM = 100;\n\n static defaultMessages: Record<number, string> = {\n 1: 'You aborted the media playback',\n 2: 'A network error caused the media download to fail.',\n 3: 'A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.',\n 4: 'An unsupported error occurred. The server or network failed, or your browser does not support this format.',\n 5: 'The media is encrypted and there are no keys to decrypt it.',\n };\n\n name: string;\n code: number;\n fatal: boolean;\n data?: any;\n\n constructor(message?: string, code: number = MediaError.MEDIA_ERR_CUSTOM, fatal?: boolean) {\n super(message);\n this.name = 'MediaError';\n this.code = code;\n this.fatal = fatal ?? (code >= MediaError.MEDIA_ERR_NETWORK && code <= MediaError.MEDIA_ERR_ENCRYPTED);\n\n if (!this.message) {\n this.message = MediaError.defaultMessages[this.code] ?? '';\n }\n }\n}\n", "import Hls from 'hls.js';\nimport { addEventListenerWithTeardown } from './util';\nimport { ValueOf, Autoplay, AutoplayTypes, PlaybackEngine } from './types';\n\nconst AutoplayTypeValues = Object.values(AutoplayTypes);\nexport const isAutoplayValue = (value: unknown): value is Autoplay => {\n return (\n typeof value === 'boolean' ||\n (typeof value === 'string' && AutoplayTypeValues.includes(value as ValueOf<AutoplayTypes>))\n );\n};\n\n// Given a video element, will listen to lifecycle events to determine important\n// things like whether the video is live or whether the video has played\n// and then handles autoplaying the video as appropraite.\n// It works with both the native video element or hls.js.\n// This returns a method UpdateAutoplay, that allows the user to change\n// the value of the autoplay attribute and it will react appropriately.\nexport const setupAutoplay = (\n { autoplay: maybeAutoplay }: { autoplay?: Autoplay },\n mediaEl: HTMLMediaElement,\n hls?: PlaybackEngine\n) => {\n let hasPlayed = false;\n let isLive = false;\n let autoplay: Autoplay = isAutoplayValue(maybeAutoplay) ? maybeAutoplay : !!maybeAutoplay;\n\n const updateHasPlayed = () => {\n // hasPlayed\n\n if (!hasPlayed) {\n addEventListenerWithTeardown(\n mediaEl,\n 'playing',\n () => {\n hasPlayed = true;\n },\n { once: true }\n );\n }\n };\n\n updateHasPlayed();\n\n // on `loadstart`\n // hasPlayed should default to false\n // we should try and autoplay\n addEventListenerWithTeardown(\n mediaEl,\n 'loadstart',\n () => {\n hasPlayed = false;\n updateHasPlayed();\n handleAutoplay(mediaEl, autoplay);\n },\n { once: true }\n );\n\n // on `loadedmetadata` we can check whether we're live in the case of native playback\n addEventListenerWithTeardown(\n mediaEl,\n 'loadstart',\n () => {\n // only update isLive here if we're using native playback\n if (!hls) {\n isLive = !Number.isFinite(mediaEl.duration);\n }\n handleAutoplay(mediaEl, autoplay);\n },\n { once: true }\n );\n\n // determine if we're live for hls.js\n if (hls) {\n hls.once(Hls.Events.LEVEL_LOADED, (e: any, data: any) => {\n isLive = data.details.live ?? false;\n });\n }\n\n // When we are not auto-playing, we should seek to the live sync position\n // This will seek first play event of *any* live video including event-type,\n // which probably shouldn't seek\n if (!autoplay) {\n const handleSeek = () => {\n // don't seek if we're not live\n if (!isLive) {\n return;\n }\n // seek to either hls.js's liveSyncPosition or the native seekable end\n if (hls?.liveSyncPosition) {\n mediaEl.currentTime = hls.liveSyncPosition;\n } else {\n if (Number.isFinite(mediaEl.seekable.end(0))) {\n mediaEl.currentTime = mediaEl.seekable.end(0);\n }\n }\n };\n if (hls) {\n addEventListenerWithTeardown(\n mediaEl,\n 'play',\n () => {\n if (mediaEl.preload === 'metadata') {\n hls.once(Hls.Events.LEVEL_UPDATED, handleSeek);\n } else {\n handleSeek();\n }\n },\n { once: true }\n );\n }\n }\n\n // this method allows us to update the value of autoplay\n // and try autoplaying appropriately.\n const updateAutoplay = (newAutoplay?: Autoplay) => {\n if (!hasPlayed) {\n autoplay = isAutoplayValue(newAutoplay) ? newAutoplay : !!newAutoplay;\n handleAutoplay(mediaEl, autoplay);\n }\n };\n\n return updateAutoplay;\n};\n\nexport const handleAutoplay = (mediaEl: HTMLMediaElement, autoplay: Autoplay) => {\n if (!autoplay) {\n return;\n }\n\n const oldMuted = mediaEl.muted;\n const restoreMuted = () => (mediaEl.muted = oldMuted);\n\n switch (autoplay) {\n // ANY:\n // try to play with current options\n // if it fails, mute and try playing again\n // if that fails, restore muted state and don't try playing again\n case AutoplayTypes.ANY:\n mediaEl.play().catch(() => {\n mediaEl.muted = true;\n mediaEl.play().catch(restoreMuted);\n });\n break;\n\n // MUTED:\n // mute the player and then try playing\n // if that fails, restore muted state\n case AutoplayTypes.MUTED:\n mediaEl.muted = true;\n mediaEl.play().catch(restoreMuted);\n break;\n\n // Default or if autoplay is a boolean attribute:\n // Try playing the video and catch the failed autoplay warning\n default: // eslint-disable-next-line\n mediaEl.play().catch(() => {});\n break;\n }\n};\n", "import { Options } from 'mux-embed';\nimport Hls, { HlsConfig } from 'hls.js';\n\ntype KeyTypes = string | number | symbol;\n\n// Type Guard to determine if a given key is actually a key of some object of type T\nexport const isKeyOf = <T = any>(k: KeyTypes, o: T): k is keyof T => {\n return k in o;\n};\n\nexport type ValueOf<T> = T[keyof T];\nexport type Metadata = Partial<Options['data']>;\nexport type PlaybackEngine = Hls;\n\nexport type PlaybackCore = {\n engine?: PlaybackEngine;\n setAutoplay: (autoplay?: Autoplay) => void;\n setPreload: (preload?: HTMLMediaElement['preload']) => void;\n};\n\n// TODO add INVIEW_MUTED, INVIEW_ANY\nexport type AutoplayTypes = {\n ANY: 'any';\n MUTED: 'muted';\n};\n\nexport const AutoplayTypes: AutoplayTypes = {\n ANY: 'any',\n MUTED: 'muted',\n};\n\nexport type Autoplay = boolean | ValueOf<AutoplayTypes>;\n\nexport type StreamTypes = {\n VOD: 'on-demand';\n ON_DEMAND: 'on-demand';\n LIVE: 'live';\n LL_LIVE: 'll-live';\n DVR: 'live:dvr';\n LL_DVR: 'll-live:dvr';\n};\n\nexport const StreamTypes: StreamTypes = {\n VOD: 'on-demand',\n ON_DEMAND: 'on-demand',\n LIVE: 'live',\n LL_LIVE: 'll-live',\n DVR: 'live:dvr',\n LL_DVR: 'll-live:dvr',\n};\n\nexport type PlaybackTypes = {\n MSE: 'mse';\n NATIVE: 'native';\n};\n\nexport const PlaybackTypes: PlaybackTypes = {\n MSE: 'mse',\n NATIVE: 'native',\n};\n\nexport type CmcdTypes = {\n HEADER: 'header';\n QUERY: 'query';\n};\n\nexport const CmcdTypes: CmcdTypes = {\n HEADER: 'header',\n QUERY: 'query',\n};\n\nexport const CmcdTypeValues = Object.values(CmcdTypes);\n\nexport type ExtensionMimeTypeMap = {\n M3U8: 'application/vnd.apple.mpegurl';\n MP4: 'video/mp4';\n};\n\nexport const ExtensionMimeTypeMap: ExtensionMimeTypeMap = {\n M3U8: 'application/vnd.apple.mpegurl',\n MP4: 'video/mp4',\n};\n\nexport type MimeTypeShorthandMap = {\n HLS: ExtensionMimeTypeMap['M3U8'];\n};\n\nexport const MimeTypeShorthandMap: MimeTypeShorthandMap = {\n HLS: ExtensionMimeTypeMap.M3U8,\n};\n\nexport const shorthandKeys = Object.keys(MimeTypeShorthandMap);\n\nexport type MediaTypes =\n | ValueOf<ExtensionMimeTypeMap>\n | keyof MimeTypeShorthandMap\n /** @TODO Figure out a way to \"downgrade\" derived types below to early TS syntax (e.g. 3.4) instead of explicit versions here (CJP) */\n | 'hls';\n// | `${Lowercase<keyof MimeTypeShorthandMap>}`\n// | `${Uppercase<keyof MimeTypeShorthandMap>}`;\n\nexport const allMediaTypes = [\n ...(Object.values(ExtensionMimeTypeMap) as ValueOf<ExtensionMimeTypeMap>[]),\n /** @TODO Figure out a way to \"downgrade\" derived types below to early TS syntax (e.g. 3.4) instead of explicit versions here (CJP) */\n 'hls',\n 'HLS',\n // ...(shorthandKeys as (keyof MimeTypeShorthandMap)[]),\n // ...(shorthandKeys.map((k) => k.toUpperCase()) as `${Uppercase<keyof MimeTypeShorthandMap>}`[]),\n // ...(shorthandKeys.map((k) => k.toLowerCase()) as `${Lowercase<keyof MimeTypeShorthandMap>}`[]),\n] as MediaTypes[];\n\nexport type MuxMediaPropTypes = {\n envKey: Options['data']['env_key'];\n debug: Options['debug'] & Hls['config']['debug'];\n metadata: Partial<Options['data']>;\n customDomain: string;\n beaconCollectionDomain: Options['beaconCollectionDomain'];\n errorTranslator: Options['errorTranslator'];\n disableCookies: Options['disableCookies'];\n playbackId: string;\n playerInitTime: Options['data']['player_init_time'];\n preferPlayback: ValueOf<PlaybackTypes> | undefined;\n type: MediaTypes;\n streamType: ValueOf<StreamTypes>;\n startTime: HlsConfig['startPosition'];\n autoPlay?: Autoplay;\n autoplay?: Autoplay;\n preferCmcd: ValueOf<CmcdTypes> | undefined;\n experimentalCmcd?: boolean;\n};\n\nexport type HTMLMediaElementProps = Partial<Pick<HTMLMediaElement, 'src' | 'preload'>>;\n\nexport type MuxMediaProps = HTMLMediaElementProps & MuxMediaPropTypes;\nexport type MuxMediaPropsInternal = MuxMediaProps & {\n playerSoftwareName: Options['data']['player_software_name'];\n playerSoftwareVersion: Options['data']['player_software_version'];\n};\n", "import { isKeyOf, ExtensionMimeTypeMap, MimeTypeShorthandMap, type MuxMediaProps } from './types';\n\ntype addEventListenerWithTeardown = <K extends keyof HTMLMediaElementEventMap>(\n mediaEl: HTMLMediaElement,\n type: K,\n listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions\n) => void;\n\n// Adds an event listener to a media element that will be removed when an 'teardown' event is dispatched.\n// Using this instead of 'emptied' as that can fire on initial load based on prior state of the media element\n// Will be fired as a result of (directly or indirectly) invoking playback-core's `teardown()` function.\nexport const addEventListenerWithTeardown: addEventListenerWithTeardown = (mediaEl, type, listener, options) => {\n mediaEl.addEventListener(type, listener, options);\n // NOTE: Using custom teardown\n mediaEl.addEventListener(\n 'teardown',\n () => {\n mediaEl.removeEventListener(type, listener);\n },\n { once: true }\n );\n};\n\nexport function inSeekableRange(seekable: TimeRanges, duration: number, time: number) {\n if (duration && time > duration) {\n time = duration;\n }\n for (let i = 0; i < seekable.length ?? 0; i++) {\n if (seekable.start(i) <= time && seekable.end(i) >= time) {\n return true;\n }\n }\n return false;\n}\n\nexport const toPlaybackIdParts = (playbackIdWithOptionalParams: string): [string, string?] => {\n const qIndex = playbackIdWithOptionalParams.indexOf('?');\n if (qIndex < 0) return [playbackIdWithOptionalParams];\n const idPart = playbackIdWithOptionalParams.slice(0, qIndex);\n const queryPart = playbackIdWithOptionalParams.slice(qIndex);\n return [idPart, queryPart];\n};\n\nexport const getType = (props: Partial<Pick<MuxMediaProps, 'type' | 'src'>>) => {\n const type = props.type;\n if (type) {\n const upperType = type.toUpperCase();\n return isKeyOf(upperType, MimeTypeShorthandMap) ? MimeTypeShorthandMap[upperType] : type;\n }\n\n const { src } = props;\n if (!src) return '';\n\n return inferMimeTypeFromURL(src);\n};\n\nexport const inferMimeTypeFromURL = (url: string) => {\n let pathname = '';\n try {\n pathname = new URL(url).pathname;\n } catch (e) {\n console.error('invalid url');\n }\n\n const extDelimIdx = pathname.lastIndexOf('.');\n if (extDelimIdx < 0) return '';\n\n const ext = pathname.slice(extDelimIdx + 1);\n const upperExt = ext.toUpperCase();\n\n return isKeyOf(upperExt, ExtensionMimeTypeMap) ? ExtensionMimeTypeMap[upperExt] : '';\n};\n", "import { addEventListenerWithTeardown } from './util';\nimport { PlaybackEngine } from './types';\n\nexport const setupPreload = (\n { preload, src }: Partial<HTMLMediaElement>,\n mediaEl: HTMLMediaElement,\n hls?: PlaybackEngine\n) => {\n const updatePreload = (val?: HTMLMediaElement['preload']) => {\n if (val != null && ['', 'none', 'metadata', 'auto'].includes(val)) {\n mediaEl.setAttribute('preload', val);\n } else {\n mediaEl.removeAttribute('preload');\n }\n };\n\n // handle native without hls.js (MSE)\n if (!hls) {\n updatePreload(preload);\n return updatePreload;\n }\n\n let hasLoadedSource = false;\n let hasPlayFired = false;\n\n const originalLength = hls.config.maxBufferLength;\n const originalSize = hls.config.maxBufferSize;\n\n const updateHlsPreload = (val?: HTMLMediaElement['preload']) => {\n // even if it doesn't have an effect on a <video> w/ MSE\n // still update the `preload` attribute.\n updatePreload(val);\n\n const newPreload = val ?? mediaEl.preload;\n if (hasPlayFired || newPreload === 'none') return;\n if (newPreload === 'metadata') {\n // load the least amount of data possible\n hls.config.maxBufferLength = 1;\n hls.config.maxBufferSize = 1;\n } else {\n hls.config.maxBufferLength = originalLength;\n hls.config.maxBufferSize = originalSize;\n }\n\n safeLoadSource();\n };\n\n const safeLoadSource = () => {\n if (!hasLoadedSource && src) {\n hasLoadedSource = true;\n hls.loadSource(src);\n }\n };\n\n addEventListenerWithTeardown(\n mediaEl,\n 'play',\n () => {\n hasPlayFired = true;\n\n // once a user has played, allow for it to load data as normal\n hls.config.maxBufferLength = originalLength;\n hls.config.maxBufferSize = originalSize;\n\n // load the source on first play if needed\n safeLoadSource();\n },\n { once: true }\n );\n\n updateHlsPreload(preload);\n\n return updateHlsPreload;\n};\n", "import Hls from 'hls.js';\n\nexport function setupTracks(\n mediaEl: HTMLMediaElement,\n hls: Pick<Hls, 'on' | 'once' | 'subtitleTracks' | 'subtitleTrack'>\n) {\n hls.on(Hls.Events.NON_NATIVE_TEXT_TRACKS_FOUND, (_type, { tracks }) => {\n tracks.forEach((trackObj) => {\n const baseTrackObj = trackObj.subtitleTrack ?? trackObj.closedCaptions;\n const idx = hls.subtitleTracks.findIndex(({ lang, name, type }) => {\n return lang == baseTrackObj?.lang && name === trackObj.label && type.toLowerCase() === trackObj.kind;\n });\n\n addTextTrack(\n mediaEl,\n trackObj.kind as TextTrackKind,\n trackObj.label,\n baseTrackObj?.lang,\n `${trackObj.kind}${idx}`\n );\n });\n });\n\n const changeHandler = () => {\n if (!hls.subtitleTracks.length) return;\n\n const showingTrack = Array.from(mediaEl.textTracks).find((textTrack) => {\n return textTrack.id && textTrack.mode === 'showing' && ['subtitles', 'captions'].includes(textTrack.kind);\n });\n\n // If hls.subtitleTrack is -1 or its id changed compared to the one that is showing load the new subtitle track.\n const hlsTrackId = `${hls.subtitleTracks[hls.subtitleTrack]?.type.toLowerCase()}${hls.subtitleTrack}`;\n if (showingTrack && (hls.subtitleTrack < 0 || showingTrack?.id !== hlsTrackId)) {\n const idx = hls.subtitleTracks.findIndex(({ lang, name, type }) => {\n return lang == showingTrack.language && name === showingTrack.label && type.toLowerCase() === showingTrack.kind;\n });\n // After the subtitleTrack is set here, hls.js will load the playlist and CUES_PARSED events will be fired below.\n hls.subtitleTrack = idx;\n }\n\n if (showingTrack && showingTrack?.id === hlsTrackId) {\n // Refresh the cues after a texttrack mode change to fix a Chrome bug causing the captions not to render.\n if (showingTrack.cues) {\n Array.from(showingTrack.cues).forEach((cue) => {\n showingTrack.addCue(cue);\n });\n }\n }\n };\n\n mediaEl.textTracks.addEventListener('change', changeHandler);\n\n hls.on(Hls.Events.CUES_PARSED, (_type, { track, cues }) => {\n const textTrack = mediaEl.textTracks.getTrackById(track);\n if (!textTrack) return;\n\n const disabled = textTrack.mode === 'disabled';\n if (disabled) {\n textTrack.mode = 'hidden';\n }\n\n cues.forEach((cue: VTTCue) => {\n if (textTrack.cues?.getCueById(cue.id)) return;\n textTrack.addCue(cue);\n });\n\n if (disabled) {\n textTrack.mode = 'disabled';\n }\n });\n\n // NOTE: Since this is only relevant for hls, using destroying event (CJP).\n hls.once(Hls.Events.DESTROYING, () => {\n mediaEl.textTracks.removeEventListener('change', changeHandler);\n // Use data attribute to identify tracks that should be removed when switching sources/destroying hls.js instance.\n const trackEls: NodeListOf<HTMLTrackElement> = mediaEl.querySelectorAll('track[data-removeondestroy]');\n trackEls.forEach((trackEl) => {\n trackEl.remove();\n });\n });\n\n const forceHiddenThumbnails = () => {\n // Keeping this a forEach in case we want to expand the scope of this.\n Array.from(mediaEl.textTracks).forEach((track) => {\n if (['subtitles', 'caption'].includes(track.kind)) return;\n if (track.label !== 'thumbnails') return;\n if (!track.cues?.length) {\n const trackEl = mediaEl.querySelector('track[label=\"thumbnails\"]');\n // Force a reload of the cues if they've been removed\n const src = trackEl?.getAttribute('src') ?? '';\n trackEl?.removeAttribute('src');\n setTimeout(() => {\n trackEl?.setAttribute('src', src);\n }, 0);\n }\n // Force hidden mode if it's not hidden\n if (track.mode !== 'hidden') {\n track.mode = 'hidden';\n }\n });\n };\n\n // hls.js will forcibly clear all cues from tracks on manifest loads or media attaches.\n // This ensures that we re-load them after it's done that.\n hls.once(Hls.Events.MANIFEST_LOADED, forceHiddenThumbnails);\n hls.once(Hls.Events.MEDIA_ATTACHED, forceHiddenThumbnails);\n}\n\nexport function addTextTrack(\n mediaEl: HTMLMediaElement,\n kind: TextTrackKind,\n label: string,\n lang?: string,\n id?: string\n): TextTrack | undefined {\n const trackEl = document.createElement('track');\n trackEl.kind = kind;\n trackEl.label = label;\n if (lang) {\n // This attribute must be present if the element's kind attribute is in the subtitles state.\n trackEl.srclang = lang;\n }\n if (id) {\n trackEl.id = id;\n }\n trackEl.track.mode = 'disabled';\n // Add data attribute to identify tracks that should be removed when switching sources/destroying hls.js instance.\n trackEl.setAttribute('data-removeondestroy', '');\n mediaEl.append(trackEl);\n return trackEl.track;\n}\n\nexport function removeTextTrack(mediaEl: HTMLMediaElement, track: TextTrack) {\n const trackElement: HTMLTrackElement | undefined = Array.prototype.find.call(\n mediaEl.querySelectorAll('track'),\n (trackEl: HTMLTrackElement) => trackEl.track === track\n );\n trackElement?.remove();\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["mux", "Hls", "_MediaError", "message", "code", "fatal", "_a", "MediaError", "Hls", "isKeyOf", "k", "o", "AutoplayTypes", "StreamTypes", "PlaybackTypes", "CmcdTypes", "CmcdTypeValues", "ExtensionMimeTypeMap", "MimeTypeShorthandMap", "shorthandKeys", "allMediaTypes", "addEventListenerWithTeardown", "mediaEl", "type", "listener", "options", "inSeekableRange", "seekable", "duration", "time", "i", "toPlaybackIdParts", "playbackIdWithOptionalParams", "qIndex", "idPart", "queryPart", "getType", "props", "upperType", "isKeyOf", "MimeTypeShorthandMap", "src", "inferMimeTypeFromURL", "url", "pathname", "extDelimIdx", "upperExt", "ExtensionMimeTypeMap", "AutoplayTypeValues", "AutoplayTypes", "isAutoplayValue", "value", "setupAutoplay", "maybeAutoplay", "mediaEl", "hls", "hasPlayed", "isLive", "autoplay", "updateHasPlayed", "addEventListenerWithTeardown", "handleAutoplay", "Hls", "e", "data", "_a", "handleSeek", "newAutoplay", "oldMuted", "restoreMuted", "setupPreload", "preload", "src", "mediaEl", "hls", "updatePreload", "val", "hasLoadedSource", "hasPlayFired", "originalLength", "originalSize", "updateHlsPreload", "newPreload", "safeLoadSource", "addEventListenerWithTeardown", "Hls", "setupTracks", "mediaEl", "hls", "_type", "tracks", "trackObj", "_a", "baseTrackObj", "idx", "lang", "name", "type", "addTextTrack", "changeHandler", "showingTrack", "textTrack", "hlsTrackId", "cue", "track", "cues", "disabled", "trackEl", "forceHiddenThumbnails", "_b", "src", "kind", "label", "id", "removeTextTrack", "trackElement", "_a", "_b", "userAgentStr", "isAndroid", "muxMediaState", "MUX_VIDEO_DOMAIN", "MSE_SUPPORTED", "Hls", "DEFAULT_PREFER_MSE", "generatePlayerInitTime", "mux", "generateUUID", "toMuxVideoURL", "playbackId", "domain", "idPart", "queryPart", "toPlaybackIdParts", "toPlaybackIdFromParameterized", "playbackIdWithParams", "toPlaybackIdFromSrc", "src", "toVideoId", "props", "_c", "isMuxVideoSrc", "getError", "mediaEl", "initialize", "core", "teardown", "metadata", "view_session_id", "video_id", "nextHlsInstance", "setupHls", "setupMux", "loadMedia", "setAutoplay", "setupAutoplay", "setPreload", "setupPreload", "hls", "handleNativeError", "handleInternalError", "seekInSeekableRange", "useNative", "type", "getType", "ExtensionMimeTypeMap", "canUseNative", "preferPlayback", "preferMse", "PlaybackTypes", "preferNative", "debug", "streamType", "startPosition", "experimentalCmcd", "preferCmcd", "hlsType", "shouldUseNative", "defaultConfig", "streamTypeConfig", "getStreamTypeConfig", "cmcd", "CmcdTypes", "StreamTypes", "customDomain", "base", "hostname", "hlsjs", "env_key", "inferredEnv", "player_init_time", "player_software_name", "player_software_version", "beaconCollectionDomain", "disableCookies", "muxEmbedErrorTranslator", "error", "_event", "data", "errorCodeMap", "MediaError", "setupTracks", "event", "startTime", "inSeekableRange", "wasAuto", "message", "code", "status"]
7
7
  }