@mux/playback-core 0.26.0 → 0.27.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
- "sources": ["../src/index.ts", "../src/hls.ts", "../src/errors.ts", "../src/types.ts", "../src/util.ts", "../src/autoplay.ts", "../src/preload.ts", "../src/media-tracks.ts", "../src/text-tracks.ts", "../src/pdt.ts"],
4
- "sourcesContent": ["import type {\n ValueOf,\n PlaybackCore,\n MuxMediaProps,\n MuxMediaPropsInternal,\n MaxResolutionValue,\n MinResolutionValue,\n RenditionOrderValue,\n} from './types';\nimport mux, { ErrorEvent } from 'mux-embed';\nimport Hls from './hls';\nimport type { HlsInterface } from './hls';\nimport { MediaError } from './errors';\nimport { setupAutoplay } from './autoplay';\nimport { setupPreload } from './preload';\nimport { setupMediaTracks } from './media-tracks';\nimport {\n setupTextTracks,\n addTextTrack,\n removeTextTrack,\n getTextTrack,\n addCuePoints,\n getCuePoints,\n getActiveCuePoint,\n setupCuePoints,\n addChapters,\n getChapters,\n getActiveChapter,\n setupChapters,\n} from './text-tracks';\nimport { getStartDate, getCurrentPdt } from './pdt';\nimport {\n inSeekableRange,\n toPlaybackIdParts,\n getType,\n toStreamTypeFromPlaylistType,\n toTargetLiveWindowFromPlaylistType,\n addEventListenerWithTeardown,\n} from './util';\nimport { StreamTypes, PlaybackTypes, ExtensionMimeTypeMap, CmcdTypes, HlsPlaylistTypes, MediaTypes } from './types';\nimport type { HlsConfig } from 'hls.js';\n// import { MediaKeySessionContext } from 'hls.js';\nexport {\n mux,\n Hls,\n MediaError,\n addTextTrack,\n removeTextTrack,\n getTextTrack,\n addCuePoints,\n getCuePoints,\n getActiveCuePoint,\n setupCuePoints,\n addChapters,\n getChapters,\n getActiveChapter,\n setupChapters,\n getStartDate,\n getCurrentPdt,\n};\nexport * from './types';\n\nconst DRMType = {\n FAIRPLAY: 'fairplay',\n PLAYREADY: 'playready',\n WIDEVINE: 'widevine',\n} as const;\n\ntype DRMTypeValue = (typeof DRMType)[keyof typeof DRMType];\nexport const toDRMTypeFromKeySystem = (keySystem: string): DRMTypeValue | undefined => {\n if (keySystem.includes('fps')) return DRMType.FAIRPLAY;\n if (keySystem.includes('playready')) return DRMType.PLAYREADY;\n if (keySystem.includes('widevine')) return DRMType.WIDEVINE;\n return undefined;\n};\n\nexport const getMediaPlaylistLinesFromMultivariantPlaylistSrc = async (src: string) => {\n return fetch(src)\n .then((resp) => resp.text())\n .then((multivariantPlaylistStr) => {\n const mediaPlaylistUrl = multivariantPlaylistStr.split('\\n').find((_line, idx, lines) => {\n return idx && lines[idx - 1].startsWith('#EXT-X-STREAM-INF');\n }) as string;\n\n return fetch(mediaPlaylistUrl)\n .then((resp) => resp.text())\n .then((mediaPlaylistStr) => mediaPlaylistStr.split('\\n'));\n });\n};\n\nexport const getStreamInfoFromPlaylistLines = (playlistLines: string[]) => {\n const typeLine = playlistLines.find((line) => line.startsWith('#EXT-X-PLAYLIST-TYPE')) ?? '';\n const playlistType = typeLine.split(':')[1]?.trim() as HlsPlaylistTypes;\n const streamType = toStreamTypeFromPlaylistType(playlistType);\n const targetLiveWindow = toTargetLiveWindowFromPlaylistType(playlistType);\n\n // Computation of the live edge start offset per media-ui-extensions proposal. See: https://github.com/video-dev/media-ui-extensions/blob/main/proposals/0007-live-edge.md#recommended-computation-for-rfc8216bis12-aka-hls (CJP)\n let liveEdgeStartOffset = undefined;\n\n if (streamType === StreamTypes.LIVE) {\n // Required if playlist contains one or more EXT-X-PART tags. See: https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-12#section-4.4.3.7 (CJP)\n const partInfLine = playlistLines.find((line) => line.startsWith('#EXT-X-PART-INF'));\n const lowLatency = !!partInfLine;\n\n if (lowLatency) {\n // The EXT-X-PART-INF only has one in-spec named attribute, PART-TARGET, which is required,\n // so parsing & casting presumptuously here. See spec link above for more info. (CJP)\n const partTarget = +partInfLine.split(':')[1].split('=')[1];\n liveEdgeStartOffset = partTarget * 2;\n } else {\n // This is required for all media playlists. See: https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-12#section-4.4.3.1 (CJP)\n const targetDurationLine = playlistLines.find((line) => line.startsWith('#EXT-X-TARGETDURATION')) as string;\n // EXT-X-TARGETDURATION has exactly one unnamed attribute that represents the target duration value, which is required,\n // so parsing and casting presumptuously here. See spec link above for more info. (CJP)\n const targetDurationValue = targetDurationLine?.split(':')?.[1];\n // NOTE: Defaulting here and using optional chaining above since some people are seeing RTEs on iPhones under edge cases.\n // Identifying root cause would be ideal, but this will at least avoid the RTE. (CJP)\n const targetDuration = +(targetDurationValue ?? 6);\n liveEdgeStartOffset = targetDuration * 3;\n }\n }\n\n return {\n streamType,\n targetLiveWindow,\n liveEdgeStartOffset,\n };\n};\n\nexport const getStreamInfoFromSrcAndType = async (src: string, type?: MediaTypes | '') => {\n if (type === ExtensionMimeTypeMap.MP4) {\n return {\n streamType: StreamTypes.ON_DEMAND,\n targetLiveWindow: Number.NaN,\n liveEdgeStartOffset: undefined,\n };\n }\n\n if (type === ExtensionMimeTypeMap.M3U8) {\n const playlistLines = await getMediaPlaylistLinesFromMultivariantPlaylistSrc(src);\n return getStreamInfoFromPlaylistLines(playlistLines);\n }\n\n // Unknown or undefined type.\n console.error(`Media type ${type} is an unrecognized or unsupported type for src ${src}.`);\n return {\n streamType: undefined,\n targetLiveWindow: undefined,\n liveEdgeStartOffset: undefined,\n };\n};\n\nexport const updateStreamInfoFromSrc = async (\n src: string,\n mediaEl: HTMLMediaElement,\n type: MediaTypes | '' = getType({ src })\n) => {\n const { streamType, targetLiveWindow, liveEdgeStartOffset } = await getStreamInfoFromSrcAndType(src, type);\n\n (muxMediaState.get(mediaEl) ?? {}).liveEdgeStartOffset = liveEdgeStartOffset;\n\n (muxMediaState.get(mediaEl) ?? {}).targetLiveWindow = targetLiveWindow;\n mediaEl.dispatchEvent(new CustomEvent('targetlivewindowchange', { composed: true, bubbles: true }));\n\n (muxMediaState.get(mediaEl) ?? {}).streamType = streamType;\n mediaEl.dispatchEvent(new CustomEvent('streamtypechange', { composed: true, bubbles: true }));\n};\n\nexport const getStreamInfoFromHlsjsLevelDetails = (levelDetails: any) => {\n const playlistType: HlsPlaylistTypes = levelDetails.type as HlsPlaylistTypes;\n\n const streamType = toStreamTypeFromPlaylistType(playlistType);\n const targetLiveWindow = toTargetLiveWindowFromPlaylistType(playlistType);\n let liveEdgeStartOffset = undefined;\n const lowLatency = !!levelDetails.partList?.length;\n if (streamType === StreamTypes.LIVE) {\n liveEdgeStartOffset = lowLatency ? levelDetails.partTarget * 2 : levelDetails.targetduration * 3;\n }\n\n return {\n streamType,\n targetLiveWindow,\n liveEdgeStartOffset,\n lowLatency,\n };\n};\n\nexport const updateStreamInfoFromHlsjsLevelDetails = (\n levelDetails: any,\n mediaEl: HTMLMediaElement,\n hls: Pick<Hls, 'config' | 'userConfig' | 'liveSyncPosition'>\n) => {\n const { streamType, targetLiveWindow, liveEdgeStartOffset, lowLatency } =\n getStreamInfoFromHlsjsLevelDetails(levelDetails);\n\n if (streamType === StreamTypes.LIVE) {\n // Update hls.js config for live/ll-live\n if (lowLatency) {\n hls.config.backBufferLength = hls.userConfig.backBufferLength ?? 4;\n hls.config.maxFragLookUpTolerance = hls.userConfig.maxFragLookUpTolerance ?? 0.001;\n // For ll-hls, ensure that up switches are weighted the same as down switches to mitigate\n // cases of getting stuck at lower bitrates.\n hls.config.abrBandWidthUpFactor = hls.userConfig.abrBandWidthUpFactor ?? hls.config.abrBandWidthFactor;\n } else {\n hls.config.backBufferLength = hls.userConfig.backBufferLength ?? 8;\n }\n\n // Proxy `seekable.end()` to constrain based on rules in\n // https://github.com/video-dev/media-ui-extensions/blob/main/proposals/0007-live-edge.md#property-constraint-on-htmlmediaelementseekableend-to-model-seekable-live-edge\n const seekable: TimeRanges = Object.freeze({\n get length() {\n return mediaEl.seekable.length;\n },\n start(index: number) {\n return mediaEl.seekable.start(index);\n },\n end(index: number) {\n // Defer to native seekable for:\n // 1) \"out of range\" cases\n // 2) \"finite duration\" media (whether live/\"DVR\" that has ended or on demand)\n if (index > this.length || index < 0 || Number.isFinite(mediaEl.duration)) return mediaEl.seekable.end(index);\n // Otherwise rely on the live sync position (but still fall back to native seekable when nullish)\n return hls.liveSyncPosition ?? mediaEl.seekable.end(index);\n },\n });\n (muxMediaState.get(mediaEl) ?? {}).seekable = seekable;\n }\n\n (muxMediaState.get(mediaEl) ?? {}).liveEdgeStartOffset = liveEdgeStartOffset;\n\n (muxMediaState.get(mediaEl) ?? {}).targetLiveWindow = targetLiveWindow;\n mediaEl.dispatchEvent(new CustomEvent('targetlivewindowchange', { composed: true, bubbles: true }));\n\n (muxMediaState.get(mediaEl) ?? {}).streamType = streamType;\n mediaEl.dispatchEvent(new CustomEvent('streamtypechange', { composed: true, bubbles: true }));\n};\n\ndeclare global {\n interface NavigatorUAData {\n platform: string;\n mobile: boolean;\n brands: Array<{ brand: string; version: string }>;\n }\n\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nconst userAgentStr = globalThis?.navigator?.userAgent ?? '';\nconst userAgentPlatform = globalThis?.navigator?.userAgentData?.platform ?? '';\n\n// NOTE: Our primary *goal* with this is to detect \"non-Apple-OS\" platforms which may also support\n// native HLS playback. Our primary concern with any check for this is \"false negatives\" where we\n// identify an \"Apple-OS\" as a \"non-Apple-OS\". As such, instead of having logic to attempt to identify\n// \"!isAppleOS\", we opt to target known platforms that can support both native playback and MSE/hls.js.\n// For now, these are \"Android or Android-like\" platforms. If we end up matching platforms other than\n// Android (or e.g. forks thereof), this is fine so long as it doesn't include Apple-OS platforms.\n// Below are two strategies:\n// 1. UA string parsing - here, we're extra cautious to only match if the UA string explicitly includes 'android'.\n// This is prone to false negatives (aka \"Android or Android-like\" platforms that yield false), since\n// detection using UA strings is intentionally and notoriously unreliable (See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent)\n// and Google is even officially attempting to lock this down even more for security and privacy reasons\n// (See: https://developers.google.com/privacy-sandbox/blog/user-agent-reduction-android-model-and-version)\n// 2. userAgentData.platform checking - here, we're matching either 'android' or 'x11', and could add more matches in the future\n// While still prone to false negatives, we can be a bit more aggressive with matches here for a few reasons.\n// First, navigator.userAgentData is still experimental, is only supported on a subset of Chromium browsers,\n// and neither Mozilla nor Webkit have even established an official browser support position. In other words,\n// Apple-OS Safari and even other Apple-OS browsers (including Chrome) will typically not even support this\n// feature, and, if and when they do, the purpose of this new API is to avoid obfuscatory information, so\n// we should be able to better trust userAgentData.platform to not result in erroneous matches.\nconst isAndroidLike =\n userAgentStr.toLowerCase().includes('android') ||\n ['x11', 'android'].some((platformStr) => userAgentPlatform.toLowerCase().includes(platformStr));\n\n// NOTE: Exporting for testing\nexport const muxMediaState: WeakMap<\n HTMLMediaElement,\n Partial<MuxMediaProps> & { seekable?: TimeRanges; liveEdgeStartOffset?: number }\n> = new WeakMap();\n\nconst MUX_VIDEO_DOMAIN = 'mux.com';\nconst MSE_SUPPORTED = Hls.isSupported?.();\nconst DEFAULT_PREFER_MSE = isAndroidLike;\n\nexport const generatePlayerInitTime = () => {\n return mux.utils.now();\n};\n\nexport const generateUUID = mux.utils.generateUUID;\n\ntype MuxVideoURLProps = Partial<{\n playbackId: string;\n customDomain: string;\n maxResolution: MaxResolutionValue;\n minResolution: MinResolutionValue;\n renditionOrder: RenditionOrderValue;\n programStartTime: number;\n programEndTime: number;\n tokens: Partial<{\n playback: string;\n storyboard: string;\n thumbnail: string;\n }>;\n extraSourceParams: Record<string, any>;\n}>;\n\nexport const toMuxVideoURL = ({\n playbackId: playbackIdWithParams,\n customDomain: domain = MUX_VIDEO_DOMAIN,\n maxResolution,\n minResolution,\n renditionOrder,\n programStartTime,\n programEndTime,\n tokens: { playback: token } = {},\n extraSourceParams = {},\n}: MuxVideoURLProps = {}) => {\n if (!playbackIdWithParams) return undefined;\n const [playbackId, queryPart = ''] = toPlaybackIdParts(playbackIdWithParams);\n const url = new URL(`https://stream.${domain}/${playbackId}.m3u8${queryPart}`);\n /*\n * All identified query params here can only be added to public\n * playback IDs. In order to use these features with signed URLs\n * the query param must be added to the signing token.\n *\n * */\n if (token || url.searchParams.has('token')) {\n url.searchParams.forEach((_, key) => {\n if (key != 'token') url.searchParams.delete(key);\n });\n if (token) url.searchParams.set('token', token);\n } else {\n if (maxResolution) {\n url.searchParams.set('max_resolution', maxResolution);\n }\n if (minResolution) {\n url.searchParams.set('min_resolution', minResolution);\n if (maxResolution && +maxResolution.slice(0, -1) < +minResolution.slice(0, -1)) {\n console.error(\n 'minResolution must be <= maxResolution',\n 'minResolution',\n minResolution,\n 'maxResolution',\n maxResolution\n );\n }\n }\n if (renditionOrder) {\n url.searchParams.set('rendition_order', renditionOrder);\n }\n if (programStartTime) {\n url.searchParams.set('program_start_time', `${programStartTime}`);\n }\n if (programEndTime) {\n url.searchParams.set('program_end_time', `${programEndTime}`);\n }\n Object.entries(extraSourceParams).forEach(([k, v]) => {\n if (v == undefined) return;\n url.searchParams.set(k, v);\n });\n }\n return url.toString();\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\nexport const 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 getStreamType = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.streamType ?? StreamTypes.UNKNOWN;\n};\n\nexport const getTargetLiveWindow = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.targetLiveWindow ?? Number.NaN;\n};\n\nexport const getSeekable = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.seekable ?? mediaEl.seekable;\n};\n\nexport const getLiveEdgeStart = (mediaEl: HTMLMediaElement) => {\n const liveEdgeStartOffset = muxMediaState.get(mediaEl)?.liveEdgeStartOffset;\n if (typeof liveEdgeStartOffset !== 'number') return Number.NaN;\n const seekable = getSeekable(mediaEl);\n // We aren't guaranteed that seekable is ready before invoking this, so handle that case.\n if (!seekable.length) return Number.NaN;\n return seekable.end(seekable.length - 1) - liveEdgeStartOffset;\n};\n\nconst DEFAULT_ENDED_MOE = 0.034;\n\nconst isApproximatelyEqual = (x: number, y: number, moe = DEFAULT_ENDED_MOE) => Math.abs(x - y) <= moe;\nconst isApproximatelyGTE = (x: number, y: number, moe = DEFAULT_ENDED_MOE) => x > y || isApproximatelyEqual(x, y, moe);\n\nexport const isPseudoEnded = (mediaEl: HTMLMediaElement, moe = DEFAULT_ENDED_MOE) => {\n return mediaEl.paused && isApproximatelyGTE(mediaEl.currentTime, mediaEl.duration, moe);\n};\n\nexport const isStuckOnLastFragment = (\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n /** Should we add audio fragments logic here, too? (CJP) */\n // | 'audioTrack'\n // | 'audioTracks'\n 'levels' | 'currentLevel'\n >\n) => {\n if (!hls || !mediaEl.buffered.length) return undefined;\n if (mediaEl.readyState > 2) return false;\n const videoLevelDetails =\n hls.currentLevel >= 0\n ? hls.levels?.[hls.currentLevel]?.details\n : hls.levels.find((level) => !!level.details)?.details;\n\n // Don't define for live streams (for now).\n if (!videoLevelDetails || videoLevelDetails.live) return undefined;\n\n const { fragments } = videoLevelDetails;\n\n // Don't give a definitive true|false before we have no fragments (for now).\n if (!fragments?.length) return undefined;\n\n // Do a cheap check up front to see if we're close to the end.\n // For more on TARGET_DURATION, see https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-14#section-4.4.3.1 (CJP)\n if (mediaEl.currentTime < mediaEl.duration - (videoLevelDetails.targetduration + 0.5)) return false;\n\n const lastFragment = fragments[fragments.length - 1];\n\n // We're not yet playing the last fragment, so we can't be stuck on it.\n if (mediaEl.currentTime <= lastFragment.start) return false;\n\n const lastFragmentMidpoint = lastFragment.start + lastFragment.duration / 2;\n const lastBufferedStart = mediaEl.buffered.start(mediaEl.buffered.length - 1);\n const lastBufferedEnd = mediaEl.buffered.end(mediaEl.buffered.length - 1);\n\n // True if we've already buffered (half of) the last fragment\n const lastFragmentInBuffer = lastFragmentMidpoint > lastBufferedStart && lastFragmentMidpoint < lastBufferedEnd;\n // If we haven't buffered half already, assume we're still waiting to fetch+buffer the fragment, otherwise,\n // since we already checked the ready state, this means we're stuck on the last segment, and should pretend we're ended!\n return lastFragmentInBuffer;\n};\n\nexport const getEnded = (\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n /** Should we add audio fragments logic here, too? (CJP) */\n // | 'audioTrack'\n // | 'audioTracks'\n 'levels' | 'currentLevel'\n >\n) => {\n // Since looping media never truly ends, don't apply pseudo-ended logic\n // Also, trust when the HTMLMediaElement says we have ended (only apply pseudo-ended logic when it reports false)\n if (mediaEl.ended || mediaEl.loop) return mediaEl.ended;\n // Externalize conversion to boolean for \"under-determined cases\" here (See isStuckOnLastFragment() for details)\n if (hls && !!isStuckOnLastFragment(mediaEl, hls)) return true;\n return isPseudoEnded(mediaEl);\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 // Used to signal DRM Type to Mux Data. See, e.g. `getDRMConfig()`\n const drmTypeCb = (drmType?: string) => {\n mediaEl.mux?.emit('hb', { view_drm_type: drmType });\n };\n\n props.drmTypeCb = drmTypeCb;\n\n muxMediaState.set(mediaEl as HTMLMediaElement, {});\n const nextHlsInstance = setupHls(props, mediaEl);\n const setPreload = setupPreload(props as Pick<MuxMediaProps, 'preload' | 'src'>, mediaEl, nextHlsInstance);\n setupMux(props, mediaEl, nextHlsInstance);\n loadMedia(props, mediaEl, nextHlsInstance);\n setupCuePoints(mediaEl);\n setupChapters(mediaEl);\n const setAutoplay = setupAutoplay(props as Pick<MuxMediaProps, 'autoplay'>, 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'\n | 'streamType'\n | 'type'\n | 'startTime'\n | 'metadata'\n | 'preferCmcd'\n | '_hlsConfig'\n | 'drmToken'\n | 'drmTypeCb'\n >\n >,\n mediaEl: Pick<HTMLMediaElement, 'canPlayType'>\n) => {\n const { debug, streamType, startTime: startPosition = -1, metadata, preferCmcd, _hlsConfig = {} } = 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 capLevelToPlayerSize: true,\n capLevelOnFPSDrop: true,\n };\n const streamTypeConfig = getStreamTypeConfig(streamType);\n const drmConfig = getDRMConfig(props);\n // NOTE: `metadata.view_session_id` & `metadata.video_id` are guaranteed here (CJP)\n const cmcd =\n preferCmcd !== CmcdTypes.NONE\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 xhrSetup: (xhr, url) => {\n if (preferCmcd && preferCmcd !== CmcdTypes.QUERY) return;\n const urlObj = new URL(url);\n if (!urlObj.searchParams.has('CMCD')) return;\n const cmcdVal = (urlObj.searchParams.get('CMCD')?.split(',') ?? [])\n .filter((cmcdKVStr) => cmcdKVStr.startsWith('sid') || cmcdKVStr.startsWith('cid'))\n .join(',');\n urlObj.searchParams.set('CMCD', cmcdVal);\n\n xhr.open('GET', urlObj);\n },\n ...defaultConfig,\n ...streamTypeConfig,\n ...drmConfig,\n ..._hlsConfig,\n }) as HlsInterface;\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 (streamType === StreamTypes.LIVE) {\n const liveConfig = {\n backBufferLength: 8,\n };\n\n return liveConfig;\n }\n\n return {};\n};\n\nexport const getDRMConfig = (\n props: Partial<Pick<MuxMediaPropsInternal, 'src' | 'playbackId' | 'drmToken' | 'customDomain' | 'drmTypeCb'>>\n): Partial<HlsConfig> => {\n const {\n drmToken,\n src,\n playbackId = toPlaybackIdFromSrc(src), // Since Mux Player typically sets `src` instead of `playbackId`, fall back to it here (CJP)\n drmTypeCb,\n } = props;\n if (!drmToken || !playbackId) return {};\n return {\n emeEnabled: true,\n drmSystems: {\n 'com.apple.fps': {\n licenseUrl: toLicenseKeyURL(props, 'fairplay'),\n serverCertificateUrl: toAppCertURL(props, 'fairplay'),\n },\n 'com.widevine.alpha': {\n licenseUrl: toLicenseKeyURL(props, 'widevine'),\n },\n 'com.microsoft.playready': {\n licenseUrl: toLicenseKeyURL(props, 'playready'),\n },\n },\n requestMediaKeySystemAccessFunc: (keySystem, supportedConfigurations) => {\n if (keySystem === 'com.widevine.alpha') {\n supportedConfigurations = [\n // NOTE: For widevine, by default we'll duplicate the key system configs but add L1-level\n // security to the first set of duplicates so the key system will \"prefer\" that\n // if/when available. (CJP)\n // See, e.g.: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess#supportedconfigurations\n ...supportedConfigurations.map((mediaKeySystemConfig) => {\n const videoCapabilities = mediaKeySystemConfig.videoCapabilities?.map((capability) => {\n return {\n ...capability,\n robustness: 'HW_SECURE_ALL',\n };\n });\n return {\n ...mediaKeySystemConfig,\n videoCapabilities,\n };\n }),\n ...supportedConfigurations,\n ];\n }\n return navigator.requestMediaKeySystemAccess(keySystem, supportedConfigurations).then((value) => {\n const drmType = toDRMTypeFromKeySystem(keySystem);\n drmTypeCb?.(drmType);\n return value;\n });\n },\n };\n};\n\nexport const getAppCertificate = async (appCertificateUrl: string) => {\n const resp = await fetch(appCertificateUrl);\n const body = await resp.arrayBuffer();\n return body;\n};\n\nexport const getLicenseKey = async (message: ArrayBuffer, licenseServerUrl: string) => {\n const licenseResponse = await fetch(licenseServerUrl, {\n method: 'POST',\n headers: { 'Content-type': 'application/octet-stream' },\n body: message,\n });\n const keyBuffer = await licenseResponse.arrayBuffer();\n return new Uint8Array(keyBuffer);\n};\n\nexport const setupNativeFairplayDRM = (\n props: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'drmToken' | 'customDomain' | 'drmTypeCb'>>,\n mediaEl: HTMLMediaElement\n) => {\n const onFpEncrypted = async (event: MediaEncryptedEvent) => {\n try {\n const initDataType = event.initDataType;\n if (initDataType !== 'skd') {\n console.error(`Received unexpected initialization data type \"${initDataType}\"`);\n return;\n }\n\n if (!mediaEl.mediaKeys) {\n const access = await navigator\n .requestMediaKeySystemAccess('com.apple.fps', [\n {\n initDataTypes: [initDataType],\n videoCapabilities: [{ contentType: 'application/vnd.apple.mpegurl', robustness: '' }],\n distinctiveIdentifier: 'not-allowed',\n persistentState: 'not-allowed',\n sessionTypes: ['temporary'],\n },\n ])\n .then((value) => {\n props.drmTypeCb?.(DRMType.FAIRPLAY);\n return value;\n });\n\n const keys = await access.createMediaKeys();\n\n const fairPlayAppCert = await getAppCertificate(toAppCertURL(props, 'fairplay'));\n await keys.setServerCertificate(fairPlayAppCert);\n await mediaEl.setMediaKeys(keys);\n }\n\n const initData = event.initData;\n if (initData == null) {\n console.error(`Could not start encrypted playback due to missing initData in ${event.type} event`);\n return;\n }\n\n const session = (mediaEl.mediaKeys as MediaKeys).createSession();\n session.generateRequest(initDataType, initData);\n const message = await new Promise<MediaKeyMessageEvent['message']>((resolve) => {\n session.addEventListener(\n 'message',\n (messageEvent) => {\n resolve(messageEvent.message);\n },\n { once: true }\n );\n });\n\n const response = await getLicenseKey(message, toLicenseKeyURL(props, 'fairplay'));\n await session.update(response);\n return session;\n } catch (e) {\n console.error(`Could not start encrypted playback due to exception \"${e}\"`);\n }\n };\n\n addEventListenerWithTeardown(mediaEl, 'encrypted', onFpEncrypted);\n};\n\nexport const toLicenseKeyURL = (\n {\n playbackId,\n drmToken: token,\n customDomain = MUX_VIDEO_DOMAIN,\n }: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'drmToken' | 'customDomain'>>,\n scheme: 'widevine' | 'playready' | 'fairplay'\n) => {\n // NOTE: Mux Video currently doesn't support custom domains for license/DRM endpoints, but\n // customDomain can also be used for internal use cases, so treat that as an exception case for now. (CJP)\n const domain = customDomain.toLocaleLowerCase().endsWith(MUX_VIDEO_DOMAIN) ? customDomain : MUX_VIDEO_DOMAIN;\n return `https://license.${domain}/license/${scheme}/${playbackId}?token=${token}`;\n};\n\nexport const toAppCertURL = (\n {\n playbackId,\n drmToken: token,\n customDomain = MUX_VIDEO_DOMAIN,\n }: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'drmToken' | 'customDomain'>>,\n scheme: 'widevine' | 'playready' | 'fairplay'\n) => {\n // NOTE: Mux Video currently doesn't support custom domains for license/DRM endpoints, but\n // customDomain can also be used for internal use cases, so treat that as an exception case for now. (CJP)\n const domain = customDomain.toLocaleLowerCase().endsWith(MUX_VIDEO_DOMAIN) ? customDomain : MUX_VIDEO_DOMAIN;\n return `https://license.${domain}/appcert/${scheme}/${playbackId}?token=${token}`;\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 | 'disableTracking'\n >\n >,\n mediaEl: HTMLMediaElement,\n hlsjs?: HlsInterface\n) => {\n const { envKey: env_key, disableTracking } = props;\n const inferredEnv = isMuxVideoSrc(props);\n\n if (!disableTracking && (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<\n Pick<\n MuxMediaProps,\n | 'preferPlayback'\n | 'src'\n | 'type'\n | 'startTime'\n | 'streamType'\n | 'autoplay'\n | 'playbackId'\n | 'drmToken'\n | 'customDomain'\n >\n >,\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n | 'config'\n | 'on'\n | 'once'\n | 'off'\n | 'trigger'\n | 'startLoad'\n | 'stopLoad'\n | 'recoverMediaError'\n | 'destroy'\n | 'loadSource'\n | 'attachMedia'\n | 'liveSyncPosition'\n | 'subtitleTracks'\n | 'subtitleTrack'\n | 'userConfig'\n | 'audioTrack'\n | 'audioTracks'\n | 'autoLevelEnabled'\n | 'nextLevel'\n | 'levels'\n | 'currentLevel'\n >\n) => {\n const shouldUseNative = useNative(props, mediaEl);\n const { src } = props;\n\n const maybeDispatchEndedCallback = () => {\n // We want to early bail if the underlying media element is already in an ended state,\n // since that means it will have already fired the ended event.\n // Do the \"cheaper\" check first\n if (mediaEl.ended) return;\n const pseudoEnded = getEnded(mediaEl, hls);\n if (!pseudoEnded) return;\n\n if (isStuckOnLastFragment(mediaEl, hls)) {\n // Nudge the playhead in this case.\n mediaEl.currentTime = mediaEl.buffered.end(mediaEl.buffered.length - 1);\n } else {\n mediaEl.dispatchEvent(new Event('ended'));\n }\n };\n\n let prevSeekableStart: number;\n let prevSeekableEnd: number;\n\n const seekableChange = () => {\n const nextSeekableStart = getSeekable(mediaEl)?.start(0);\n const nextSeekableEnd = getSeekable(mediaEl)?.end(0);\n if (prevSeekableEnd !== nextSeekableEnd || prevSeekableStart !== nextSeekableStart) {\n mediaEl.dispatchEvent(new CustomEvent('seekablechange', { composed: true }));\n }\n prevSeekableStart = nextSeekableStart;\n prevSeekableEnd = nextSeekableEnd;\n };\n\n // Make sure we track transitions from infinite to finite durations for seekable changes as well.\n addEventListenerWithTeardown(mediaEl, 'durationchange', seekableChange);\n\n if (mediaEl && shouldUseNative) {\n const type = getType(props);\n if (typeof src === 'string') {\n // NOTE: This should only be invoked after stream type has been\n // derived after stream type has been determined.\n const setupSeekableChangePoll = () => {\n // Only monitor for seekable updates if StreamType is \"live\" and duration is not finite.\n if (getStreamType(mediaEl) !== StreamTypes.LIVE || Number.isFinite(mediaEl.duration)) return;\n\n // Use 1 second since in this context we don't know what the rate of updates\n // should/will be.\n // NOTE: We *could* derive the interval rate if we wanted to add logic to our playlist parsing to\n // account for the per-spec rate of media playlist GETs. See:\n // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-14#section-6.3.4 (CJP)\n const intervalId = setInterval(seekableChange, 1000);\n\n // Make sure we clean up after ourselves.\n mediaEl.addEventListener(\n 'teardown',\n () => {\n clearInterval(intervalId);\n },\n { once: true }\n );\n\n // Assume we're done updating seekable when the duration is finite, which\n // occurs when e.g. an HLS playlist is ended (`#EXT-X-ENDLIST`).\n addEventListenerWithTeardown(mediaEl, 'durationchange', () => {\n if (!Number.isFinite(mediaEl.duration)) return;\n clearInterval(intervalId);\n });\n };\n if (mediaEl.preload === 'none') {\n // NOTE: Previously, we relied on the 'loadstart' event to fetch & parse playlists for stream\n // info for native playback scenarios. Unfortunately, per spec this event will be dispatched\n // regardless of the preload state and regardless of whether or not fetching of the src media\n // has, in fact, begun. In order to respect the provided preferences and avoid eager loading\n // while still attempting to begin fetching playlists for stream info as early as possible when\n // media *will* be loaded, we will do a \"first to the finish line\" on both the 'play' event,\n // which will be dispatched earlier *if* it is the event that initiates media loading, and the\n // 'loadedmetadata' event, which is dispatched only after the media has finished loading metadata,\n // but will reliably correlate with media loading. (CJP)\n // For more, see: Steps 7 & 8 of 'the resource selection algorithm' from \u00A74.8.11.5 Loading the\n // media resource in the HTML Living Standard\n // (https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm)\n const playHandler = () => {\n updateStreamInfoFromSrc(src, mediaEl, type).then(setupSeekableChangePoll);\n mediaEl.removeEventListener('loadedmetadata', loadedMetadataHandler);\n };\n const loadedMetadataHandler = () => {\n updateStreamInfoFromSrc(src, mediaEl, type).then(setupSeekableChangePoll);\n mediaEl.removeEventListener('play', playHandler);\n };\n addEventListenerWithTeardown(mediaEl, 'play', playHandler, { once: true });\n addEventListenerWithTeardown(mediaEl, 'loadedmetadata', loadedMetadataHandler, { once: true });\n } else {\n updateStreamInfoFromSrc(src, mediaEl, type).then(setupSeekableChangePoll);\n }\n\n // NOTE: Currently use drmToken to signal that playback is expected to be DRM-protected\n if (props.drmToken) {\n setupNativeFairplayDRM(props, mediaEl);\n }\n\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 mediaEl.addEventListener(\n 'emptied',\n () => {\n const trackEls: NodeListOf<HTMLTrackElement> = mediaEl.querySelectorAll('track[data-removeondestroy]');\n trackEls.forEach((trackEl) => {\n trackEl.remove();\n });\n },\n { once: true }\n );\n\n addEventListenerWithTeardown(mediaEl, 'pause', maybeDispatchEndedCallback);\n // NOTE: Browsers do not consistently fire an 'ended' event upon seeking to the\n // end of the media while already paused. This was due to an ambiguity in the\n // HTML specification, but is now more explicit.\n // See: https://html.spec.whatwg.org/multipage/media.html#reaches-the-end (CJP)\n addEventListenerWithTeardown(mediaEl, 'seeked', maybeDispatchEndedCallback);\n\n addEventListenerWithTeardown(mediaEl, 'play', () => {\n if (mediaEl.ended) return;\n if (!isApproximatelyGTE(mediaEl.currentTime, mediaEl.duration)) return;\n // If we were \"pseudo-ended\" before playback was attempted, seek back to the\n // beginning to \"replay\", like \"real\" ended behavior.\n mediaEl.currentTime = mediaEl.seekable.length ? mediaEl.seekable.start(0) : 0;\n });\n } else if (hls && src) {\n hls.once(Hls.Events.LEVEL_LOADED, (_evt, data) => {\n updateStreamInfoFromHlsjsLevelDetails(data.details, mediaEl, hls);\n seekableChange();\n // Only monitor for seekable updates if StreamType is \"live\" and duration is not finite.\n if (getStreamType(mediaEl) === StreamTypes.LIVE && !Number.isFinite(mediaEl.duration)) {\n hls.on(Hls.Events.LEVEL_UPDATED, seekableChange);\n\n // Assume we're done updating seekable when the duration is finite, which\n // occurs when e.g. an HLS playlist is ended (`#EXT-X-ENDLIST`).\n addEventListenerWithTeardown(mediaEl, 'durationchange', () => {\n if (!Number.isFinite(mediaEl.duration)) return;\n hls.off(Hls.Events.LEVELS_UPDATED, seekableChange);\n });\n }\n });\n\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 addEventListenerWithTeardown(mediaEl, 'waiting', maybeDispatchEndedCallback);\n\n setupMediaTracks(props as HTMLMediaElement, hls);\n setupTextTracks(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 as unknown as HTMLMediaElement['error'];\n\n // Only pass valid mux-embed props: player_error_code, player_error_message, player_error_context\n mediaEl.mux?.emit('error', {\n player_error_code: error.code,\n player_error_message: error.message,\n player_error_context: error.context,\n });\n}\n", "import Hls from 'hls.js';\nimport type HlsClassType from 'hls.js';\nexport default Hls;\nexport type HlsInterface = HlsClassType;\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 context?: string;\n fatal: boolean;\n data?: any;\n\n constructor(message?: string, code: number = MediaError.MEDIA_ERR_CUSTOM, fatal?: boolean, context?: string) {\n super(message);\n this.name = 'MediaError';\n this.code = code;\n this.context = context;\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", "/* eslint @typescript-eslint/triple-slash-reference: \"off\" */\n/// <reference path=\"../../../node_modules/mux-embed/dist/types/mux-embed.d.ts\" preserve=\"true\" />\nimport type { Options } from 'mux-embed';\nimport type { MediaError } from './errors';\nimport type { HlsConfig } from 'hls.js';\nimport type Hls from 'hls.js';\n\ntype KeyTypes = string | number | symbol;\ntype Maybe<T> = T | null | undefined;\n\nconst isNil = (x: unknown): x is null | undefined => x == undefined;\n\n// Type Guard to determine if a given key is actually a key of some object of type T\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport const isKeyOf = <T extends {} = any>(k: KeyTypes, o: Maybe<T>): k is keyof T => {\n if (isNil(o)) return false;\n return k in o;\n};\n\nexport type ValueOf<T> = T[keyof T];\nexport type Metadata = Partial<Required<Options>['data']>;\ntype MetaData = Metadata;\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 HlsPlaylistTypes = 'VOD' | 'EVENT' | null | undefined;\n\nexport type StreamTypes = {\n ON_DEMAND: 'on-demand';\n LIVE: 'live';\n UNKNOWN: 'unknown';\n};\n\nexport const StreamTypes: StreamTypes = {\n ON_DEMAND: 'on-demand',\n LIVE: 'live',\n UNKNOWN: 'unknown',\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 NONE: 'none';\n};\n\nexport const CmcdTypes: CmcdTypes = {\n HEADER: 'header',\n QUERY: 'query',\n NONE: 'none',\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\n// Both cuepoints and chapters have optional end times\n// so support both joined up and sparse cue placements\ntype CueLike<T = any> = {\n startTime: number;\n endTime?: number;\n value: T;\n};\nexport type CuePoint<T = any> =\n | CueLike<T> // new shape\n | { time: number; value: T }; // legacy shape, still supported for now\nexport type Chapter = CueLike<string>;\n\nexport const MaxResolution = {\n upTo720p: '720p',\n upTo1080p: '1080p',\n upTo1440p: '1440p',\n upTo2160p: '2160p',\n} as const;\n\nexport const MinResolution = {\n noLessThan480p: '480p',\n noLessThan540p: '540p',\n noLessThan720p: '720p',\n noLessThan1080p: '1080p',\n noLessThan1440p: '1440p',\n noLessThan2160p: '2160p',\n} as const;\n\nexport const RenditionOrder = {\n DESCENDING: 'desc',\n} as const;\n\nexport type MaxResolutionValue = ValueOf<typeof MaxResolution>;\nexport type MinResolutionValue = ValueOf<typeof MinResolution>;\nexport type RenditionOrderValue = ValueOf<typeof RenditionOrder>;\n\nexport type MuxMediaPropTypes = {\n _hlsConfig?: Partial<HlsConfig>;\n autoPlay?: Autoplay;\n autoplay?: Autoplay;\n beaconCollectionDomain: Options['beaconCollectionDomain'];\n customDomain: string;\n debug: Options['debug'] & Hls['config']['debug'];\n disableCookies: Options['disableCookies'];\n disableTracking: boolean;\n drmToken?: string;\n envKey: MetaData['env_key'];\n error?: HTMLMediaElement['error'] | MediaError;\n errorTranslator: Options['errorTranslator'];\n liveEdgeStart: number;\n maxResolution: MaxResolutionValue;\n metadata: Partial<Options['data']>;\n minResolution: MinResolutionValue;\n playbackId: string;\n playerInitTime: MetaData['player_init_time'];\n preferCmcd: ValueOf<CmcdTypes> | undefined;\n preferPlayback: ValueOf<PlaybackTypes> | undefined;\n programStartTime: number;\n programEndTime: number;\n renditionOrder: RenditionOrderValue;\n startTime: Hls['config']['startPosition'];\n streamType: ValueOf<StreamTypes>;\n targetLiveWindow: number;\n tokens: Partial<{ drm: string; playback: string; storyboard: string; thumbnail: string }>;\n type: MediaTypes;\n};\n\nexport type HTMLMediaElementProps = Partial<Pick<HTMLMediaElement, 'src' | 'preload' | 'error' | 'seekable'>>;\n\nexport type MuxMediaProps = HTMLMediaElementProps & MuxMediaPropTypes;\nexport type MuxMediaPropsInternal = MuxMediaProps & {\n playerSoftwareName: MetaData['player_software_name'];\n playerSoftwareVersion: MetaData['player_software_version'];\n drmTypeCb?: (drmType: Metadata['view_drm_type']) => void;\n};\n", "import { isKeyOf, ExtensionMimeTypeMap, MimeTypeShorthandMap, StreamTypes } from './types';\nimport type { HlsPlaylistTypes, MuxMediaProps } from './types';\n\ntype addEventListenerWithTeardown = <\n K extends keyof HTMLMediaElementEventMap,\n T extends EventTarget = HTMLMediaElement,\n>(\n mediaEl: HTMLMediaElement,\n type: K,\n listener: (this: T, ev: HTMLMediaElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n target?: T | HTMLMediaElement\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 = (\n mediaEl,\n type,\n listener,\n options,\n target = mediaEl\n) => {\n /** @TODO fix types (hard problem due to lack of explicit relationship between Element and EventMap definitions) */\n // @ts-ignore\n target.addEventListener(type, listener, options);\n // NOTE: Using custom teardown\n mediaEl.addEventListener(\n 'teardown',\n () => {\n /** @TODO fix types (hard problem due to lack of explicit relationship between Element and EventMap definitions) */\n // @ts-ignore\n target.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; 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 toStreamTypeFromPlaylistType = (playlistType: HlsPlaylistTypes) => {\n return playlistType === 'VOD' ? StreamTypes.ON_DEMAND : StreamTypes.LIVE;\n};\n\nexport const toTargetLiveWindowFromPlaylistType = (playlistType: HlsPlaylistTypes) => {\n if (playlistType === 'EVENT') return Number.POSITIVE_INFINITY;\n if (playlistType === 'VOD') return Number.NaN;\n return 0;\n};\n\nexport const inferMimeTypeFromURL = (url: string) => {\n let pathname = '';\n try {\n pathname = new URL(url).pathname;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\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 { ValueOf, Autoplay, AutoplayTypes, PlaybackEngine, MuxMediaPropsInternal, StreamTypes } from './types';\nimport Hls from './hls';\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 props: Partial<MuxMediaPropsInternal>,\n mediaEl: HTMLMediaElement,\n hls?: PlaybackEngine\n) => {\n const { autoplay: maybeAutoplay } = props;\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 // defer to streamType if set (including inferred)\n if (props.streamType && props.streamType !== StreamTypes.UNKNOWN) {\n isLive = props.streamType === StreamTypes.LIVE;\n } else {\n isLive = !Number.isFinite(mediaEl.duration);\n }\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 // defer to streamType if set (including inferred)\n if (props.streamType && props.streamType !== StreamTypes.UNKNOWN) {\n isLive = props.streamType === StreamTypes.LIVE;\n } else {\n isLive = data.details.live ?? false;\n }\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 or if a `startTime` has been explicitly set\n if (!isLive || Number.isFinite(props.startTime)) {\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 { 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';\n\nexport function setupMediaTracks(\n customMediaEl: HTMLMediaElement,\n hls: Pick<\n Hls,\n 'audioTrack' | 'audioTracks' | 'autoLevelEnabled' | 'nextLevel' | 'levels' | 'on' | 'once' | 'off' | 'trigger'\n >\n) {\n if (!('videoTracks' in customMediaEl)) return;\n\n // Create a map to save the unique id's we create for each level and rendition.\n // hls.js uses the levels array index primarily but we'll use the id to have a\n // 1 to 1 relation from rendition to level.\n const levelIdMap = new WeakMap();\n\n hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {\n removeAllMediaTracks();\n\n const videoTrack = customMediaEl.addVideoTrack('main');\n videoTrack.selected = true;\n\n for (const [id, level] of data.levels.entries()) {\n const videoRendition = videoTrack.addRendition(\n level.url[0],\n level.width,\n level.height,\n level.videoCodec,\n level.bitrate\n );\n\n // The returned levels all have an id of `0`, save the id in a WeakMap.\n levelIdMap.set(level, `${id}`);\n videoRendition.id = `${id}`;\n }\n });\n\n hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, function (event, data) {\n removeAudioTracks();\n\n for (const a of data.audioTracks) {\n // hls.js doesn't return a `kind` property for audio tracks yet.\n const kind = a.default ? 'main' : 'alternative';\n const audioTrack = customMediaEl.addAudioTrack(kind, a.name, a.lang);\n audioTrack.id = `${a.id}`;\n\n if (a.default) {\n audioTrack.enabled = true;\n }\n }\n });\n\n customMediaEl.audioTracks.addEventListener('change', () => {\n // Cast to number, hls.js uses numeric id's.\n const audioTrackId = +[...customMediaEl.audioTracks].find((t) => t.enabled)?.id;\n const availableIds = hls.audioTracks.map((t) => t.id);\n if (audioTrackId != hls.audioTrack && availableIds.includes(audioTrackId)) {\n hls.audioTrack = audioTrackId;\n }\n });\n\n // Fired when a level is removed after calling `removeLevel()`\n hls.on(Hls.Events.LEVELS_UPDATED, function (event, data) {\n const videoTrack = customMediaEl.videoTracks[customMediaEl.videoTracks.selectedIndex ?? 0];\n if (!videoTrack) return;\n\n const levelIds: string[] = data.levels.map((l) => levelIdMap.get(l));\n\n for (const rendition of customMediaEl.videoRenditions) {\n if (rendition.id && !levelIds.includes(rendition.id)) {\n videoTrack.removeRendition(rendition);\n }\n }\n });\n\n // hls.js doesn't support enabling multiple renditions.\n //\n // 1. if all renditions are enabled it's auto selection.\n // 2. if 1 of the renditions is disabled we assume a selection was made\n // and lock it to the first rendition that is enabled.\n const switchRendition = (event: Event) => {\n // @ts-ignore\n const level = event.target.selectedIndex as number;\n if (level != hls.nextLevel) {\n smoothSwitch(level);\n }\n };\n\n // Workaround for issue changing renditions on an alternative audio track.\n // https://github.com/video-dev/hls.js/issues/5749#issuecomment-1684629437\n const smoothSwitch = (levelIndex: number) => {\n const currentTime = customMediaEl.currentTime;\n let flushedFwdBuffer = false;\n\n const callback = (event: string, data: { endOffset: number }) => {\n flushedFwdBuffer ||= !Number.isFinite(data.endOffset);\n };\n\n hls.on(Hls.Events.BUFFER_FLUSHING, callback);\n hls.nextLevel = levelIndex;\n hls.off(Hls.Events.BUFFER_FLUSHING, callback);\n\n if (!flushedFwdBuffer) {\n hls.trigger(Hls.Events.BUFFER_FLUSHING, {\n startOffset: currentTime + 10,\n endOffset: Infinity,\n type: 'video',\n });\n }\n };\n\n customMediaEl.videoRenditions?.addEventListener('change', switchRendition);\n\n const removeVideoTracks = () => {\n for (const videoTrack of customMediaEl.videoTracks) {\n customMediaEl.removeVideoTrack(videoTrack);\n }\n };\n\n const removeAudioTracks = () => {\n for (const audioTrack of customMediaEl.audioTracks) {\n customMediaEl.removeAudioTrack(audioTrack);\n }\n };\n\n const removeAllMediaTracks = () => {\n removeVideoTracks();\n removeAudioTracks();\n };\n\n // NOTE: Since this is only relevant for hls, using destroying event (CJP).\n hls.once(Hls.Events.DESTROYING, removeAllMediaTracks);\n}\n", "import Hls from './hls';\nimport { CuePoint, Chapter } from './types';\nimport { addEventListenerWithTeardown } from './util';\n\ntype Config = { label: string };\n\n// Shared utils\n\n// Extracts the start time from a cuepoint, considering legacy \"time\" prop\nconst cuePointStart = (cuePoint: CuePoint): number => {\n if ('time' in cuePoint) {\n return cuePoint.time;\n }\n return cuePoint.startTime;\n};\n\nexport function setupTextTracks(\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 {\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 = ['subtitles', 'captions'].includes(kind) ? 'disabled' : 'hidden';\n\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\n return trackEl.track as TextTrack;\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\nexport function getTextTrack(mediaEl: HTMLMediaElement, label: string, kind: TextTrackKind) {\n return Array.from(mediaEl.querySelectorAll('track')).find((trackEl) => {\n return trackEl.track.label === label && trackEl.track.kind === kind;\n })?.track;\n}\n\nexport async function addCuesToTextTrack<T = any>(\n mediaEl: HTMLMediaElement,\n cues: CuePoint<T>[] | Chapter[],\n label: string,\n kind: TextTrackKind\n) {\n // If the track has already been created/added, use it.\n let track = getTextTrack(mediaEl, label, kind);\n if (!track) {\n // Otherwise, create a new one\n track = addTextTrack(mediaEl, kind, label);\n track.mode = 'hidden';\n // Wait a tick before providing a newly created track. Otherwise e.g. cues disappear when using track.addCue().\n await new Promise((resolve) => setTimeout(() => resolve(undefined), 0));\n }\n\n if (track.mode !== 'hidden') {\n track.mode = 'hidden';\n }\n\n // Copy cuePoints to ensure sort is not mutative\n [...cues]\n // Sort descending to ensure last cuepoints are added as cues first. This is done\n // so the track's cue's can be used for reference when determining an appropriate\n // endTime, allowing support of multiple invocations of addCuePoints\n .sort((cuePointA, cuePointB) => cuePointStart(cuePointB) - cuePointStart(cuePointA))\n .forEach((cuePoint) => {\n const value = cuePoint.value;\n const startTime = cuePointStart(cuePoint);\n\n if ('endTime' in cuePoint && cuePoint.endTime != undefined) {\n track?.addCue(\n new VTTCue(\n startTime,\n cuePoint.endTime,\n kind === 'chapters' ? (value as string) : JSON.stringify(value ?? null)\n )\n );\n } else {\n // find the cue that starts immediately after the cuePoint's time\n const cueAfterIndex = Array.prototype.findIndex.call(track?.cues, (cue) => cue.startTime >= startTime);\n const cueAfter = track?.cues?.[cueAfterIndex];\n const endTime = cueAfter\n ? cueAfter.startTime\n : Number.isFinite(mediaEl.duration)\n ? mediaEl.duration\n : Number.MAX_SAFE_INTEGER;\n\n // Adjust the endTime of the already added previous cue,\n // if present, so it does not overlap with the newly added cue.\n const previousCue = track?.cues?.[cueAfterIndex - 1];\n if (previousCue) {\n previousCue.endTime = startTime;\n }\n track?.addCue(\n new VTTCue(startTime, endTime, kind === 'chapters' ? (value as string) : JSON.stringify(value ?? null))\n );\n }\n });\n\n // NOTE: this doesn't naturally fire when we update the list\n // of cue points (without changing the active cue). We manually\n // fire this to force the state manager to reflect the new change\n mediaEl.textTracks.dispatchEvent(\n new Event('change', {\n bubbles: true,\n composed: true,\n })\n );\n\n return track;\n}\n\n// Cuepoints\n\nconst DEFAULT_CUEPOINTS_TRACK_LABEL = 'cuepoints';\nexport const DefaultCuePointsConfig: Config = Object.freeze({ label: DEFAULT_CUEPOINTS_TRACK_LABEL });\n\nexport async function addCuePoints<T>(\n mediaEl: HTMLMediaElement,\n cuePoints: CuePoint<T>[],\n cuePointsConfig: Config = DefaultCuePointsConfig\n) {\n return addCuesToTextTrack(mediaEl, cuePoints, cuePointsConfig.label, 'metadata');\n}\n\nconst toCuePoint = (cue: VTTCue) => ({\n time: cue.startTime,\n value: JSON.parse(cue.text),\n});\n\nexport function getCuePoints(\n mediaEl: HTMLMediaElement,\n cuePointsConfig: Config = { label: DEFAULT_CUEPOINTS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, cuePointsConfig.label, 'metadata');\n if (!track?.cues) return [];\n return Array.from(track.cues, (cue) => toCuePoint(cue as VTTCue));\n}\n\nexport function getActiveCuePoint(\n mediaEl: HTMLMediaElement,\n cuePointsConfig: Config = { label: DEFAULT_CUEPOINTS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, cuePointsConfig.label, 'metadata');\n if (!track?.activeCues?.length) return undefined;\n if (track.activeCues.length === 1) return toCuePoint(track.activeCues[0] as VTTCue);\n // NOTE: There is a bug in Chromium where there may be \"lingering activeCues\" even\n // after the playhead is no longer within their [startTime, endTime) bounds. This\n // accounts for those cases (CJP)\n const { currentTime } = mediaEl;\n const actualActiveCue = Array.prototype.find.call(track.activeCues ?? [], ({ startTime, endTime }) => {\n return startTime <= currentTime && endTime > currentTime;\n }) as VTTCue | undefined;\n if (!actualActiveCue) {\n return toCuePoint(track.activeCues[0] as VTTCue);\n }\n return toCuePoint(actualActiveCue);\n}\n\nexport async function setupCuePoints(mediaEl: HTMLMediaElement, cuePointsConfig: Config = DefaultCuePointsConfig) {\n return new Promise((resolve) => {\n addEventListenerWithTeardown(mediaEl, 'loadstart', async () => {\n const track = await addCuePoints(mediaEl, [], cuePointsConfig);\n addEventListenerWithTeardown(\n mediaEl,\n 'cuechange',\n () => {\n const activeCuePoint = getActiveCuePoint(mediaEl);\n if (activeCuePoint) {\n const evt = new CustomEvent('cuepointchange', {\n composed: true,\n bubbles: true,\n detail: activeCuePoint,\n });\n mediaEl.dispatchEvent(evt);\n }\n },\n {},\n track\n );\n resolve(track);\n });\n });\n}\n\n/**\n * Chapters\n */\n\nconst DEFAULT_CHAPTERS_TRACK_LABEL = 'chapters';\nexport const DefaultChaptersConfig: Config = Object.freeze({ label: DEFAULT_CHAPTERS_TRACK_LABEL });\n\nconst vttCueToChapter = (cue: VTTCue) => ({\n startTime: cue.startTime,\n endTime: cue.endTime,\n value: cue.text,\n});\n\nexport async function addChapters(\n mediaEl: HTMLMediaElement,\n chapters: Chapter[],\n chaptersConfig: Config = DefaultChaptersConfig\n) {\n return addCuesToTextTrack(mediaEl, chapters, chaptersConfig.label, 'chapters');\n}\n\nexport function getChapters(\n mediaEl: HTMLMediaElement,\n chaptersConfig: Config = { label: DEFAULT_CHAPTERS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, chaptersConfig.label, 'chapters');\n if (!track?.cues?.length) return [];\n return Array.from(track.cues, (cue) => vttCueToChapter(cue as VTTCue));\n}\n\nexport function getActiveChapter(\n mediaEl: HTMLMediaElement,\n chaptersConfig: Config = { label: DEFAULT_CHAPTERS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, chaptersConfig.label, 'chapters');\n if (!track?.activeCues?.length) return undefined;\n if (track.activeCues.length === 1) return vttCueToChapter(track.activeCues[0] as VTTCue);\n // NOTE: There is a bug in Chromium where there may be \"lingering activeCues\" even\n // after the playhead is no longer within their [startTime, endTime) bounds. This\n // accounts for those cases (CJP)\n const { currentTime } = mediaEl;\n const actualActiveCue = Array.prototype.find.call(track.activeCues ?? [], ({ startTime, endTime }) => {\n return startTime <= currentTime && endTime > currentTime;\n }) as VTTCue | undefined;\n if (!actualActiveCue) {\n return vttCueToChapter(track.activeCues[0] as VTTCue);\n }\n return vttCueToChapter(actualActiveCue);\n}\n\nexport async function setupChapters(mediaEl: HTMLMediaElement, chaptersConfig: Config = DefaultChaptersConfig) {\n return new Promise((resolve) => {\n addEventListenerWithTeardown(mediaEl, 'loadstart', async () => {\n const track = await addChapters(mediaEl, [], chaptersConfig);\n\n addEventListenerWithTeardown(\n mediaEl,\n 'cuechange',\n () => {\n const activeCuePoint = getActiveChapter(mediaEl);\n if (activeCuePoint) {\n const evt = new CustomEvent('chapterchange', {\n composed: true,\n bubbles: true,\n detail: activeCuePoint,\n });\n mediaEl.dispatchEvent(evt);\n }\n },\n {},\n track\n );\n\n resolve(track);\n });\n });\n}\n", "import { PlaybackEngine } from './types';\n\ntype MediaWithPDT = HTMLMediaElement & { getStartDate?: () => Date };\n\nexport function getStartDate(mediaEl: MediaWithPDT, hls: PlaybackEngine | undefined) {\n if (hls) {\n const playingDate = hls.playingDate;\n\n if (playingDate != null) {\n // If the video is very long and the currentTime will transition day boundaries,\n // this may end up not being accurate\n return new Date(playingDate.getTime() - mediaEl.currentTime * 1000);\n }\n }\n\n if (typeof mediaEl.getStartDate === 'function') {\n return mediaEl.getStartDate();\n }\n\n return new Date(NaN);\n}\n\nexport function getCurrentPdt(mediaEl: MediaWithPDT, hls: PlaybackEngine | undefined) {\n if (hls && hls.playingDate) {\n return hls.playingDate;\n }\n\n if (typeof mediaEl.getStartDate === 'function') {\n const startDate = mediaEl.getStartDate();\n\n // If the video is very long and the currentTime will transition day boundaries,\n // this may end up not being accurate\n return new Date(startDate.getTime() + mediaEl.currentTime * 1000);\n }\n\n return new Date(NaN);\n}\n"],
5
- "mappings": "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",
6
- "names": ["src_exports", "__export", "AutoplayTypes", "CmcdTypeValues", "CmcdTypes", "ExtensionMimeTypeMap", "hls_default", "MaxResolution", "MediaError", "MimeTypeShorthandMap", "MinResolution", "PlaybackTypes", "RenditionOrder", "StreamTypes", "addChapters", "addCuePoints", "addTextTrack", "allMediaTypes", "generatePlayerInitTime", "generateUUID", "getActiveChapter", "getActiveCuePoint", "getAppCertificate", "getChapters", "getCuePoints", "getCurrentPdt", "getDRMConfig", "getEnded", "getError", "getLicenseKey", "getLiveEdgeStart", "getMediaPlaylistLinesFromMultivariantPlaylistSrc", "getSeekable", "getStartDate", "getStreamInfoFromHlsjsLevelDetails", "getStreamInfoFromPlaylistLines", "getStreamInfoFromSrcAndType", "getStreamType", "getStreamTypeConfig", "getTargetLiveWindow", "getTextTrack", "initialize", "isKeyOf", "isMuxVideoSrc", "isPseudoEnded", "isStuckOnLastFragment", "loadMedia", "mux", "muxMediaState", "removeTextTrack", "setupChapters", "setupCuePoints", "setupHls", "setupMux", "setupNativeFairplayDRM", "shorthandKeys", "teardown", "toAppCertURL", "toDRMTypeFromKeySystem", "toLicenseKeyURL", "toMuxVideoURL", "toPlaybackIdFromSrc", "updateStreamInfoFromHlsjsLevelDetails", "updateStreamInfoFromSrc", "__toCommonJS", "import_mux_embed", "import_hls", "hls_default", "Hls", "_MediaError", "message", "code", "fatal", "context", "_a", "MediaError", "isNil", "x", "isKeyOf", "k", "o", "AutoplayTypes", "StreamTypes", "PlaybackTypes", "CmcdTypes", "CmcdTypeValues", "ExtensionMimeTypeMap", "MimeTypeShorthandMap", "shorthandKeys", "allMediaTypes", "MaxResolution", "MinResolution", "RenditionOrder", "addEventListenerWithTeardown", "mediaEl", "type", "listener", "options", "target", "inSeekableRange", "seekable", "duration", "time", "i", "toPlaybackIdParts", "playbackIdWithOptionalParams", "qIndex", "idPart", "queryPart", "getType", "props", "upperType", "isKeyOf", "MimeTypeShorthandMap", "src", "inferMimeTypeFromURL", "toStreamTypeFromPlaylistType", "playlistType", "StreamTypes", "toTargetLiveWindowFromPlaylistType", "url", "pathname", "extDelimIdx", "upperExt", "ExtensionMimeTypeMap", "AutoplayTypeValues", "AutoplayTypes", "isAutoplayValue", "value", "setupAutoplay", "props", "mediaEl", "hls", "maybeAutoplay", "hasPlayed", "isLive", "autoplay", "updateHasPlayed", "addEventListenerWithTeardown", "handleAutoplay", "StreamTypes", "hls_default", "e", "data", "_a", "handleSeek", "newAutoplay", "oldMuted", "restoreMuted", "setupPreload", "preload", "src", "mediaEl", "hls", "updatePreload", "val", "hasLoadedSource", "hasPlayFired", "originalLength", "originalSize", "updateHlsPreload", "newPreload", "safeLoadSource", "addEventListenerWithTeardown", "setupMediaTracks", "customMediaEl", "hls", "_a", "levelIdMap", "hls_default", "event", "data", "removeAllMediaTracks", "videoTrack", "id", "level", "videoRendition", "removeAudioTracks", "a", "kind", "audioTrack", "audioTrackId", "t", "availableIds", "levelIds", "l", "rendition", "switchRendition", "smoothSwitch", "levelIndex", "currentTime", "flushedFwdBuffer", "callback", "removeVideoTracks", "cuePointStart", "cuePoint", "setupTextTracks", "mediaEl", "hls", "hls_default", "_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", "getTextTrack", "addCuesToTextTrack", "resolve", "cuePointA", "cuePointB", "value", "startTime", "cueAfterIndex", "cueAfter", "endTime", "previousCue", "DEFAULT_CUEPOINTS_TRACK_LABEL", "DefaultCuePointsConfig", "addCuePoints", "cuePoints", "cuePointsConfig", "toCuePoint", "getCuePoints", "getActiveCuePoint", "currentTime", "actualActiveCue", "setupCuePoints", "addEventListenerWithTeardown", "activeCuePoint", "evt", "DEFAULT_CHAPTERS_TRACK_LABEL", "DefaultChaptersConfig", "vttCueToChapter", "addChapters", "chapters", "chaptersConfig", "getChapters", "getActiveChapter", "setupChapters", "getStartDate", "mediaEl", "hls", "playingDate", "getCurrentPdt", "startDate", "DRMType", "toDRMTypeFromKeySystem", "keySystem", "getMediaPlaylistLinesFromMultivariantPlaylistSrc", "src", "resp", "multivariantPlaylistStr", "mediaPlaylistUrl", "_line", "idx", "lines", "mediaPlaylistStr", "getStreamInfoFromPlaylistLines", "playlistLines", "_a", "_b", "_c", "playlistType", "line", "streamType", "toStreamTypeFromPlaylistType", "targetLiveWindow", "toTargetLiveWindowFromPlaylistType", "liveEdgeStartOffset", "StreamTypes", "partInfLine", "targetDurationLine", "targetDurationValue", "getStreamInfoFromSrcAndType", "type", "ExtensionMimeTypeMap", "updateStreamInfoFromSrc", "mediaEl", "getType", "muxMediaState", "getStreamInfoFromHlsjsLevelDetails", "levelDetails", "lowLatency", "updateStreamInfoFromHlsjsLevelDetails", "hls", "_d", "_e", "_f", "_g", "_h", "seekable", "index", "userAgentStr", "userAgentPlatform", "isAndroidLike", "platformStr", "MUX_VIDEO_DOMAIN", "MSE_SUPPORTED", "hls_default", "DEFAULT_PREFER_MSE", "generatePlayerInitTime", "mux", "generateUUID", "toMuxVideoURL", "playbackIdWithParams", "domain", "maxResolution", "minResolution", "renditionOrder", "programStartTime", "programEndTime", "token", "extraSourceParams", "playbackId", "queryPart", "toPlaybackIdParts", "url", "_", "key", "k", "v", "toPlaybackIdFromParameterized", "toPlaybackIdFromSrc", "toVideoId", "props", "isMuxVideoSrc", "getError", "getStreamType", "getTargetLiveWindow", "getSeekable", "getLiveEdgeStart", "DEFAULT_ENDED_MOE", "isApproximatelyEqual", "x", "y", "moe", "isApproximatelyGTE", "isPseudoEnded", "isStuckOnLastFragment", "videoLevelDetails", "level", "fragments", "lastFragment", "lastFragmentMidpoint", "lastBufferedStart", "lastBufferedEnd", "getEnded", "initialize", "core", "teardown", "metadata", "view_session_id", "video_id", "drmTypeCb", "drmType", "nextHlsInstance", "setupHls", "setPreload", "setupPreload", "setupMux", "loadMedia", "setupCuePoints", "setupChapters", "setAutoplay", "setupAutoplay", "handleNativeError", "handleInternalError", "seekInSeekableRange", "useNative", "canUseNative", "preferPlayback", "preferMse", "PlaybackTypes", "preferNative", "debug", "startPosition", "preferCmcd", "_hlsConfig", "hlsType", "shouldUseNative", "defaultConfig", "streamTypeConfig", "getStreamTypeConfig", "drmConfig", "getDRMConfig", "cmcd", "CmcdTypes", "xhr", "urlObj", "cmcdVal", "cmcdKVStr", "drmToken", "toLicenseKeyURL", "toAppCertURL", "supportedConfigurations", "mediaKeySystemConfig", "videoCapabilities", "capability", "value", "getAppCertificate", "appCertificateUrl", "getLicenseKey", "message", "licenseServerUrl", "keyBuffer", "setupNativeFairplayDRM", "addEventListenerWithTeardown", "event", "initDataType", "keys", "fairPlayAppCert", "initData", "session", "resolve", "messageEvent", "response", "e", "customDomain", "scheme", "base", "hostname", "hlsjs", "env_key", "disableTracking", "inferredEnv", "player_init_time", "player_software_name", "player_software_version", "beaconCollectionDomain", "disableCookies", "muxEmbedErrorTranslator", "error", "maybeDispatchEndedCallback", "prevSeekableStart", "prevSeekableEnd", "seekableChange", "nextSeekableStart", "nextSeekableEnd", "setupSeekableChangePoll", "intervalId", "playHandler", "loadedMetadataHandler", "trackEl", "_evt", "data", "_event", "errorCodeMap", "MediaError", "setupMediaTracks", "setupTextTracks", "startTime", "inSeekableRange", "wasAuto", "code", "status"]
3
+ "sources": ["../src/index.ts", "../src/hls.ts", "../src/errors.ts", "../src/types.ts", "../lang/en.json", "../src/util.ts", "../src/autoplay.ts", "../src/preload.ts", "../src/media-tracks.ts", "../src/text-tracks.ts", "../src/pdt.ts", "../src/request-errors.ts"],
4
+ "sourcesContent": ["import type { ValueOf, PlaybackCore, MuxMediaProps, MuxMediaPropsInternal, MuxMediaPropTypes } from './types';\nimport mux, { ErrorEvent } from 'mux-embed';\nimport Hls from './hls';\nimport type { HlsInterface } from './hls';\nimport { MediaError, MuxErrorCategory, MuxErrorCode, errorCategoryToTokenNameOrPrefix } from './errors';\nimport { setupAutoplay } from './autoplay';\nimport { setupPreload } from './preload';\nimport { setupMediaTracks } from './media-tracks';\nimport {\n setupTextTracks,\n addTextTrack,\n removeTextTrack,\n getTextTrack,\n addCuePoints,\n getCuePoints,\n getActiveCuePoint,\n setupCuePoints,\n addChapters,\n getChapters,\n getActiveChapter,\n setupChapters,\n} from './text-tracks';\nimport { getStartDate, getCurrentPdt } from './pdt';\nimport {\n inSeekableRange,\n toPlaybackIdParts,\n getType,\n toStreamTypeFromPlaylistType,\n toTargetLiveWindowFromPlaylistType,\n addEventListenerWithTeardown,\n i18n,\n parseJwt,\n} from './util';\nimport { StreamTypes, PlaybackTypes, ExtensionMimeTypeMap, CmcdTypes, HlsPlaylistTypes, MediaTypes } from './types';\nimport { ErrorDetails, ErrorTypes, type ErrorData, type HlsConfig } from 'hls.js';\nimport { getErrorFromResponse, MuxJWTAud } from './request-errors';\n// import { MediaKeySessionContext } from 'hls.js';\nexport {\n mux,\n Hls,\n MediaError,\n MuxErrorCategory,\n MuxErrorCode,\n errorCategoryToTokenNameOrPrefix,\n MuxJWTAud,\n addTextTrack,\n removeTextTrack,\n getTextTrack,\n addCuePoints,\n getCuePoints,\n getActiveCuePoint,\n setupCuePoints,\n addChapters,\n getChapters,\n getActiveChapter,\n setupChapters,\n getStartDate,\n getCurrentPdt,\n toPlaybackIdParts,\n i18n,\n parseJwt,\n};\nexport * from './types';\n\nconst DRMType = {\n FAIRPLAY: 'fairplay',\n PLAYREADY: 'playready',\n WIDEVINE: 'widevine',\n} as const;\n\ntype DRMTypeValue = (typeof DRMType)[keyof typeof DRMType];\nexport const toDRMTypeFromKeySystem = (keySystem: string): DRMTypeValue | undefined => {\n if (keySystem.includes('fps')) return DRMType.FAIRPLAY;\n if (keySystem.includes('playready')) return DRMType.PLAYREADY;\n if (keySystem.includes('widevine')) return DRMType.WIDEVINE;\n return undefined;\n};\n\nexport const getMediaPlaylistLinesFromMultivariantPlaylistSrc = async (src: string) => {\n return fetch(src)\n .then((resp) => {\n if (resp.status !== 200) {\n return Promise.reject(resp);\n }\n return resp.text();\n })\n .then((multivariantPlaylistStr) => {\n const mediaPlaylistUrl = multivariantPlaylistStr.split('\\n').find((_line, idx, lines) => {\n return idx && lines[idx - 1].startsWith('#EXT-X-STREAM-INF');\n }) as string;\n\n return fetch(mediaPlaylistUrl)\n .then((resp) => {\n if (resp.status !== 200) {\n return Promise.reject(resp);\n }\n return resp.text();\n })\n .then((mediaPlaylistStr) => mediaPlaylistStr.split('\\n'));\n });\n};\n\nexport const getStreamInfoFromPlaylistLines = (playlistLines: string[]) => {\n const typeLine = playlistLines.find((line) => line.startsWith('#EXT-X-PLAYLIST-TYPE')) ?? '';\n const playlistType = typeLine.split(':')[1]?.trim() as HlsPlaylistTypes;\n const streamType = toStreamTypeFromPlaylistType(playlistType);\n const targetLiveWindow = toTargetLiveWindowFromPlaylistType(playlistType);\n\n // Computation of the live edge start offset per media-ui-extensions proposal. See: https://github.com/video-dev/media-ui-extensions/blob/main/proposals/0007-live-edge.md#recommended-computation-for-rfc8216bis12-aka-hls (CJP)\n let liveEdgeStartOffset = undefined;\n\n if (streamType === StreamTypes.LIVE) {\n // Required if playlist contains one or more EXT-X-PART tags. See: https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-12#section-4.4.3.7 (CJP)\n const partInfLine = playlistLines.find((line) => line.startsWith('#EXT-X-PART-INF'));\n const lowLatency = !!partInfLine;\n\n if (lowLatency) {\n // The EXT-X-PART-INF only has one in-spec named attribute, PART-TARGET, which is required,\n // so parsing & casting presumptuously here. See spec link above for more info. (CJP)\n const partTarget = +partInfLine.split(':')[1].split('=')[1];\n liveEdgeStartOffset = partTarget * 2;\n } else {\n // This is required for all media playlists. See: https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-12#section-4.4.3.1 (CJP)\n const targetDurationLine = playlistLines.find((line) => line.startsWith('#EXT-X-TARGETDURATION')) as string;\n // EXT-X-TARGETDURATION has exactly one unnamed attribute that represents the target duration value, which is required,\n // so parsing and casting presumptuously here. See spec link above for more info. (CJP)\n const targetDurationValue = targetDurationLine?.split(':')?.[1];\n // NOTE: Defaulting here and using optional chaining above since some people are seeing RTEs on iPhones under edge cases.\n // Identifying root cause would be ideal, but this will at least avoid the RTE. (CJP)\n const targetDuration = +(targetDurationValue ?? 6);\n liveEdgeStartOffset = targetDuration * 3;\n }\n }\n\n return {\n streamType,\n targetLiveWindow,\n liveEdgeStartOffset,\n };\n};\n\nexport const getStreamInfoFromSrcAndType = async (src: string, type?: MediaTypes | '') => {\n if (type === ExtensionMimeTypeMap.MP4) {\n return {\n streamType: StreamTypes.ON_DEMAND,\n targetLiveWindow: Number.NaN,\n liveEdgeStartOffset: undefined,\n };\n }\n\n if (type === ExtensionMimeTypeMap.M3U8) {\n const playlistLines = await getMediaPlaylistLinesFromMultivariantPlaylistSrc(src);\n return getStreamInfoFromPlaylistLines(playlistLines);\n }\n\n // Unknown or undefined type.\n console.error(`Media type ${type} is an unrecognized or unsupported type for src ${src}.`);\n return {\n streamType: undefined,\n targetLiveWindow: undefined,\n liveEdgeStartOffset: undefined,\n };\n};\n\nexport const updateStreamInfoFromSrc = async (\n src: string,\n mediaEl: HTMLMediaElement,\n type: MediaTypes | '' = getType({ src })\n) => {\n const { streamType, targetLiveWindow, liveEdgeStartOffset } = await getStreamInfoFromSrcAndType(src, type);\n\n (muxMediaState.get(mediaEl) ?? {}).liveEdgeStartOffset = liveEdgeStartOffset;\n\n (muxMediaState.get(mediaEl) ?? {}).targetLiveWindow = targetLiveWindow;\n mediaEl.dispatchEvent(new CustomEvent('targetlivewindowchange', { composed: true, bubbles: true }));\n\n (muxMediaState.get(mediaEl) ?? {}).streamType = streamType;\n mediaEl.dispatchEvent(new CustomEvent('streamtypechange', { composed: true, bubbles: true }));\n};\n\nexport const getStreamInfoFromHlsjsLevelDetails = (levelDetails: any) => {\n const playlistType: HlsPlaylistTypes = levelDetails.type as HlsPlaylistTypes;\n\n const streamType = toStreamTypeFromPlaylistType(playlistType);\n const targetLiveWindow = toTargetLiveWindowFromPlaylistType(playlistType);\n let liveEdgeStartOffset = undefined;\n const lowLatency = !!levelDetails.partList?.length;\n if (streamType === StreamTypes.LIVE) {\n liveEdgeStartOffset = lowLatency ? levelDetails.partTarget * 2 : levelDetails.targetduration * 3;\n }\n\n return {\n streamType,\n targetLiveWindow,\n liveEdgeStartOffset,\n lowLatency,\n };\n};\n\nexport const updateStreamInfoFromHlsjsLevelDetails = (\n levelDetails: any,\n mediaEl: HTMLMediaElement,\n hls: Pick<Hls, 'config' | 'userConfig' | 'liveSyncPosition'>\n) => {\n const { streamType, targetLiveWindow, liveEdgeStartOffset, lowLatency } =\n getStreamInfoFromHlsjsLevelDetails(levelDetails);\n\n if (streamType === StreamTypes.LIVE) {\n // Update hls.js config for live/ll-live\n if (lowLatency) {\n hls.config.backBufferLength = hls.userConfig.backBufferLength ?? 4;\n hls.config.maxFragLookUpTolerance = hls.userConfig.maxFragLookUpTolerance ?? 0.001;\n // For ll-hls, ensure that up switches are weighted the same as down switches to mitigate\n // cases of getting stuck at lower bitrates.\n hls.config.abrBandWidthUpFactor = hls.userConfig.abrBandWidthUpFactor ?? hls.config.abrBandWidthFactor;\n } else {\n hls.config.backBufferLength = hls.userConfig.backBufferLength ?? 8;\n }\n\n // Proxy `seekable.end()` to constrain based on rules in\n // https://github.com/video-dev/media-ui-extensions/blob/main/proposals/0007-live-edge.md#property-constraint-on-htmlmediaelementseekableend-to-model-seekable-live-edge\n const seekable: TimeRanges = Object.freeze({\n get length() {\n return mediaEl.seekable.length;\n },\n start(index: number) {\n return mediaEl.seekable.start(index);\n },\n end(index: number) {\n // Defer to native seekable for:\n // 1) \"out of range\" cases\n // 2) \"finite duration\" media (whether live/\"DVR\" that has ended or on demand)\n if (index > this.length || index < 0 || Number.isFinite(mediaEl.duration)) return mediaEl.seekable.end(index);\n // Otherwise rely on the live sync position (but still fall back to native seekable when nullish)\n return hls.liveSyncPosition ?? mediaEl.seekable.end(index);\n },\n });\n (muxMediaState.get(mediaEl) ?? {}).seekable = seekable;\n }\n\n (muxMediaState.get(mediaEl) ?? {}).liveEdgeStartOffset = liveEdgeStartOffset;\n\n (muxMediaState.get(mediaEl) ?? {}).targetLiveWindow = targetLiveWindow;\n mediaEl.dispatchEvent(new CustomEvent('targetlivewindowchange', { composed: true, bubbles: true }));\n\n (muxMediaState.get(mediaEl) ?? {}).streamType = streamType;\n mediaEl.dispatchEvent(new CustomEvent('streamtypechange', { composed: true, bubbles: true }));\n};\n\ndeclare global {\n interface NavigatorUAData {\n platform: string;\n mobile: boolean;\n brands: Array<{ brand: string; version: string }>;\n }\n\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\nconst userAgentStr = globalThis?.navigator?.userAgent ?? '';\nconst userAgentPlatform = globalThis?.navigator?.userAgentData?.platform ?? '';\n\n// NOTE: Our primary *goal* with this is to detect \"non-Apple-OS\" platforms which may also support\n// native HLS playback. Our primary concern with any check for this is \"false negatives\" where we\n// identify an \"Apple-OS\" as a \"non-Apple-OS\". As such, instead of having logic to attempt to identify\n// \"!isAppleOS\", we opt to target known platforms that can support both native playback and MSE/hls.js.\n// For now, these are \"Android or Android-like\" platforms. If we end up matching platforms other than\n// Android (or e.g. forks thereof), this is fine so long as it doesn't include Apple-OS platforms.\n// Below are two strategies:\n// 1. UA string parsing - here, we're extra cautious to only match if the UA string explicitly includes 'android'.\n// This is prone to false negatives (aka \"Android or Android-like\" platforms that yield false), since\n// detection using UA strings is intentionally and notoriously unreliable (See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent)\n// and Google is even officially attempting to lock this down even more for security and privacy reasons\n// (See: https://developers.google.com/privacy-sandbox/blog/user-agent-reduction-android-model-and-version)\n// 2. userAgentData.platform checking - here, we're matching either 'android' or 'x11', and could add more matches in the future\n// While still prone to false negatives, we can be a bit more aggressive with matches here for a few reasons.\n// First, navigator.userAgentData is still experimental, is only supported on a subset of Chromium browsers,\n// and neither Mozilla nor Webkit have even established an official browser support position. In other words,\n// Apple-OS Safari and even other Apple-OS browsers (including Chrome) will typically not even support this\n// feature, and, if and when they do, the purpose of this new API is to avoid obfuscatory information, so\n// we should be able to better trust userAgentData.platform to not result in erroneous matches.\nconst isAndroidLike =\n userAgentStr.toLowerCase().includes('android') ||\n ['x11', 'android'].some((platformStr) => userAgentPlatform.toLowerCase().includes(platformStr));\n\n// NOTE: Exporting for testing\nexport const muxMediaState: WeakMap<\n HTMLMediaElement,\n Partial<MuxMediaProps> & { seekable?: TimeRanges; liveEdgeStartOffset?: number }\n> = new WeakMap();\n\nconst MUX_VIDEO_DOMAIN = 'mux.com';\nconst MSE_SUPPORTED = Hls.isSupported?.();\nconst DEFAULT_PREFER_MSE = isAndroidLike;\n\nexport const generatePlayerInitTime = () => {\n return mux.utils.now();\n};\n\nexport const generateUUID = mux.utils.generateUUID;\n\ntype MuxVideoURLProps = Partial<\n Pick<\n MuxMediaPropTypes,\n | 'playbackId'\n | 'customDomain'\n | 'maxResolution'\n | 'minResolution'\n | 'renditionOrder'\n | 'programStartTime'\n | 'programEndTime'\n | 'assetStartTime'\n | 'assetEndTime'\n | 'tokens'\n | 'playbackToken'\n | 'extraSourceParams'\n >\n>;\n\nexport const toMuxVideoURL = ({\n playbackId: playbackIdWithParams,\n customDomain: domain = MUX_VIDEO_DOMAIN,\n maxResolution,\n minResolution,\n renditionOrder,\n programStartTime,\n programEndTime,\n assetStartTime,\n assetEndTime,\n // Normalizes different ways of providing playback token\n playbackToken,\n tokens: { playback: token = playbackToken } = {},\n extraSourceParams = {},\n}: MuxVideoURLProps = {}) => {\n if (!playbackIdWithParams) return undefined;\n // Normalizes different ways of providing playback id\n const [playbackId, queryPart = ''] = toPlaybackIdParts(playbackIdWithParams);\n const url = new URL(`https://stream.${domain}/${playbackId}.m3u8${queryPart}`);\n /*\n * All identified query params here can only be added to public\n * playback IDs. In order to use these features with signed URLs\n * the query param must be added to the signing token.\n *\n * */\n if (token || url.searchParams.has('token')) {\n url.searchParams.forEach((_, key) => {\n if (key != 'token') url.searchParams.delete(key);\n });\n if (token) url.searchParams.set('token', token);\n } else {\n if (maxResolution) {\n url.searchParams.set('max_resolution', maxResolution);\n }\n if (minResolution) {\n url.searchParams.set('min_resolution', minResolution);\n if (maxResolution && +maxResolution.slice(0, -1) < +minResolution.slice(0, -1)) {\n console.error(\n 'minResolution must be <= maxResolution',\n 'minResolution',\n minResolution,\n 'maxResolution',\n maxResolution\n );\n }\n }\n if (renditionOrder) {\n url.searchParams.set('rendition_order', renditionOrder);\n }\n if (programStartTime) {\n url.searchParams.set('program_start_time', `${programStartTime}`);\n }\n if (programEndTime) {\n url.searchParams.set('program_end_time', `${programEndTime}`);\n }\n if (assetStartTime) {\n url.searchParams.set('asset_start_time', `${assetStartTime}`);\n }\n if (assetEndTime) {\n url.searchParams.set('asset_end_time', `${assetEndTime}`);\n }\n Object.entries(extraSourceParams).forEach(([k, v]) => {\n if (v == undefined) return;\n url.searchParams.set(k, v);\n });\n }\n return url.toString();\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\nexport const 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 getStreamType = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.streamType ?? StreamTypes.UNKNOWN;\n};\n\nexport const getTargetLiveWindow = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.targetLiveWindow ?? Number.NaN;\n};\n\nexport const getSeekable = (mediaEl: HTMLMediaElement) => {\n return muxMediaState.get(mediaEl)?.seekable ?? mediaEl.seekable;\n};\n\nexport const getLiveEdgeStart = (mediaEl: HTMLMediaElement) => {\n const liveEdgeStartOffset = muxMediaState.get(mediaEl)?.liveEdgeStartOffset;\n if (typeof liveEdgeStartOffset !== 'number') return Number.NaN;\n const seekable = getSeekable(mediaEl);\n // We aren't guaranteed that seekable is ready before invoking this, so handle that case.\n if (!seekable.length) return Number.NaN;\n return seekable.end(seekable.length - 1) - liveEdgeStartOffset;\n};\n\nconst DEFAULT_ENDED_MOE = 0.034;\n\nconst isApproximatelyEqual = (x: number, y: number, moe = DEFAULT_ENDED_MOE) => Math.abs(x - y) <= moe;\nconst isApproximatelyGTE = (x: number, y: number, moe = DEFAULT_ENDED_MOE) => x > y || isApproximatelyEqual(x, y, moe);\n\nexport const isPseudoEnded = (mediaEl: HTMLMediaElement, moe = DEFAULT_ENDED_MOE) => {\n return mediaEl.paused && isApproximatelyGTE(mediaEl.currentTime, mediaEl.duration, moe);\n};\n\nexport const isStuckOnLastFragment = (\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n /** Should we add audio fragments logic here, too? (CJP) */\n // | 'audioTrack'\n // | 'audioTracks'\n 'levels' | 'currentLevel'\n >\n) => {\n if (!hls || !mediaEl.buffered.length) return undefined;\n if (mediaEl.readyState > 2) return false;\n const videoLevelDetails =\n hls.currentLevel >= 0\n ? hls.levels?.[hls.currentLevel]?.details\n : hls.levels.find((level) => !!level.details)?.details;\n\n // Don't define for live streams (for now).\n if (!videoLevelDetails || videoLevelDetails.live) return undefined;\n\n const { fragments } = videoLevelDetails;\n\n // Don't give a definitive true|false before we have no fragments (for now).\n if (!fragments?.length) return undefined;\n\n // Do a cheap check up front to see if we're close to the end.\n // For more on TARGET_DURATION, see https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-14#section-4.4.3.1 (CJP)\n if (mediaEl.currentTime < mediaEl.duration - (videoLevelDetails.targetduration + 0.5)) return false;\n\n const lastFragment = fragments[fragments.length - 1];\n\n // We're not yet playing the last fragment, so we can't be stuck on it.\n if (mediaEl.currentTime <= lastFragment.start) return false;\n\n const lastFragmentMidpoint = lastFragment.start + lastFragment.duration / 2;\n const lastBufferedStart = mediaEl.buffered.start(mediaEl.buffered.length - 1);\n const lastBufferedEnd = mediaEl.buffered.end(mediaEl.buffered.length - 1);\n\n // True if we've already buffered (half of) the last fragment\n const lastFragmentInBuffer = lastFragmentMidpoint > lastBufferedStart && lastFragmentMidpoint < lastBufferedEnd;\n // If we haven't buffered half already, assume we're still waiting to fetch+buffer the fragment, otherwise,\n // since we already checked the ready state, this means we're stuck on the last segment, and should pretend we're ended!\n return lastFragmentInBuffer;\n};\n\nexport const getEnded = (\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n /** Should we add audio fragments logic here, too? (CJP) */\n // | 'audioTrack'\n // | 'audioTracks'\n 'levels' | 'currentLevel'\n >\n) => {\n // Since looping media never truly ends, don't apply pseudo-ended logic\n // Also, trust when the HTMLMediaElement says we have ended (only apply pseudo-ended logic when it reports false)\n if (mediaEl.ended || mediaEl.loop) return mediaEl.ended;\n // Externalize conversion to boolean for \"under-determined cases\" here (See isStuckOnLastFragment() for details)\n if (hls && !!isStuckOnLastFragment(mediaEl, hls)) return true;\n return isPseudoEnded(mediaEl);\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 // Used to signal DRM Type to Mux Data. See, e.g. `getDRMConfig()`\n const drmTypeCb = (drmType?: string) => {\n mediaEl.mux?.emit('hb', { view_drm_type: drmType });\n };\n\n props.drmTypeCb = drmTypeCb;\n\n muxMediaState.set(mediaEl as HTMLMediaElement, {});\n const nextHlsInstance = setupHls(props, mediaEl);\n const setPreload = setupPreload(props as Pick<MuxMediaProps, 'preload' | 'src'>, mediaEl, nextHlsInstance);\n setupMux(props, mediaEl, nextHlsInstance);\n loadMedia(props, mediaEl, nextHlsInstance);\n setupCuePoints(mediaEl);\n setupChapters(mediaEl);\n const setAutoplay = setupAutoplay(props as Pick<MuxMediaProps, 'autoplay'>, 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' | 'preferCmcd' | '_hlsConfig' | 'tokens' | 'drmTypeCb'\n >\n >,\n mediaEl: Pick<HTMLMediaElement, 'canPlayType'>\n) => {\n const { debug, streamType, startTime: startPosition = -1, metadata, preferCmcd, _hlsConfig = {} } = 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 capLevelToPlayerSize: true,\n capLevelOnFPSDrop: true,\n };\n const streamTypeConfig = getStreamTypeConfig(streamType);\n const drmConfig = getDRMConfig(props);\n // NOTE: `metadata.view_session_id` & `metadata.video_id` are guaranteed here (CJP)\n const cmcd =\n preferCmcd !== CmcdTypes.NONE\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 xhrSetup: (xhr, url) => {\n if (preferCmcd && preferCmcd !== CmcdTypes.QUERY) return;\n const urlObj = new URL(url);\n if (!urlObj.searchParams.has('CMCD')) return;\n const cmcdVal = (urlObj.searchParams.get('CMCD')?.split(',') ?? [])\n .filter((cmcdKVStr) => cmcdKVStr.startsWith('sid') || cmcdKVStr.startsWith('cid'))\n .join(',');\n urlObj.searchParams.set('CMCD', cmcdVal);\n\n xhr.open('GET', urlObj);\n },\n ...defaultConfig,\n ...streamTypeConfig,\n ...drmConfig,\n ..._hlsConfig,\n }) as HlsInterface;\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 (streamType === StreamTypes.LIVE) {\n const liveConfig = {\n backBufferLength: 8,\n };\n\n return liveConfig;\n }\n\n return {};\n};\n\nexport const getDRMConfig = (\n props: Partial<Pick<MuxMediaPropsInternal, 'src' | 'playbackId' | 'tokens' | 'customDomain' | 'drmTypeCb'>>\n): Partial<HlsConfig> => {\n const {\n tokens: { drm: drmToken } = {},\n playbackId: playbackIdWithOptionalParams, // Since Mux Player typically sets `src` instead of `playbackId`, fall back to it here (CJP)\n drmTypeCb,\n } = props;\n const playbackId = toPlaybackIdFromParameterized(playbackIdWithOptionalParams);\n if (!drmToken || !playbackId) return {};\n return {\n emeEnabled: true,\n drmSystems: {\n 'com.apple.fps': {\n licenseUrl: toLicenseKeyURL(props, 'fairplay'),\n serverCertificateUrl: toAppCertURL(props, 'fairplay'),\n },\n 'com.widevine.alpha': {\n licenseUrl: toLicenseKeyURL(props, 'widevine'),\n },\n 'com.microsoft.playready': {\n licenseUrl: toLicenseKeyURL(props, 'playready'),\n },\n },\n requestMediaKeySystemAccessFunc: (keySystem, supportedConfigurations) => {\n if (keySystem === 'com.widevine.alpha') {\n supportedConfigurations = [\n // NOTE: For widevine, by default we'll duplicate the key system configs but add L1-level\n // security to the first set of duplicates so the key system will \"prefer\" that\n // if/when available. (CJP)\n // See, e.g.: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess#supportedconfigurations\n ...supportedConfigurations.map((mediaKeySystemConfig) => {\n const videoCapabilities = mediaKeySystemConfig.videoCapabilities?.map((capability) => {\n return {\n ...capability,\n robustness: 'HW_SECURE_ALL',\n };\n });\n return {\n ...mediaKeySystemConfig,\n videoCapabilities,\n };\n }),\n ...supportedConfigurations,\n ];\n }\n return navigator.requestMediaKeySystemAccess(keySystem, supportedConfigurations).then((value) => {\n const drmType = toDRMTypeFromKeySystem(keySystem);\n drmTypeCb?.(drmType);\n return value;\n });\n },\n };\n};\n\nexport const getAppCertificate = async (appCertificateUrl: string) => {\n const resp = await fetch(appCertificateUrl);\n if (resp.status !== 200) {\n return Promise.reject(resp);\n }\n const body = await resp.arrayBuffer();\n return body;\n};\n\nexport const getLicenseKey = async (message: ArrayBuffer, licenseServerUrl: string) => {\n const resp = await fetch(licenseServerUrl, {\n method: 'POST',\n headers: { 'Content-type': 'application/octet-stream' },\n body: message,\n });\n if (resp.status !== 200) {\n return Promise.reject(resp);\n }\n const keyBuffer = await resp.arrayBuffer();\n return new Uint8Array(keyBuffer);\n};\n\nexport const setupNativeFairplayDRM = (\n props: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'tokens' | 'playbackToken' | 'customDomain' | 'drmTypeCb'>>,\n mediaEl: HTMLMediaElement\n) => {\n const onFpEncrypted = async (event: MediaEncryptedEvent) => {\n try {\n const initDataType = event.initDataType;\n if (initDataType !== 'skd') {\n console.error(`Received unexpected initialization data type \"${initDataType}\"`);\n return;\n }\n\n if (!mediaEl.mediaKeys) {\n const access = await navigator\n .requestMediaKeySystemAccess('com.apple.fps', [\n {\n initDataTypes: [initDataType],\n videoCapabilities: [{ contentType: 'application/vnd.apple.mpegurl', robustness: '' }],\n distinctiveIdentifier: 'not-allowed',\n persistentState: 'not-allowed',\n sessionTypes: ['temporary'],\n },\n ])\n .then((value) => {\n props.drmTypeCb?.(DRMType.FAIRPLAY);\n return value;\n })\n .catch(() => {\n const message = i18n(\n 'Cannot play DRM-protected content with current security configuration on this browser. Try playing in another browser.'\n );\n // Should we flag this as a business exception?\n const mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_UNSUPPORTED_KEY_SYSTEM;\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: mediaError,\n })\n );\n });\n\n if (!access) return;\n\n const keys = await access.createMediaKeys();\n\n try {\n const fairPlayAppCert = await getAppCertificate(toAppCertURL(props, 'fairplay')).catch((errOrResp) => {\n if (errOrResp instanceof Response) {\n const mediaError = getErrorFromResponse(errOrResp, MuxErrorCategory.DRM, props);\n console.error('mediaError', mediaError?.message, mediaError?.context);\n if (mediaError) {\n return Promise.reject(mediaError);\n }\n // NOTE: This should never happen. Adding for exhaustiveness (CJP).\n return Promise.reject(new Error('Unexpected error in app cert request'));\n }\n return Promise.reject(errOrResp);\n });\n await keys.setServerCertificate(fairPlayAppCert).catch(() => {\n const message = i18n(\n 'Your server certificate failed when attempting to set it. This may be an issue with a no longer valid certificate.'\n );\n const mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_UPDATE_SERVER_CERT_FAILED;\n return Promise.reject(mediaError);\n });\n // @ts-ignore\n } catch (error: Error | MediaError) {\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n return;\n }\n await mediaEl.setMediaKeys(keys);\n }\n\n const initData = event.initData;\n if (initData == null) {\n console.error(`Could not start encrypted playback due to missing initData in ${event.type} event`);\n return;\n }\n\n const session = (mediaEl.mediaKeys as MediaKeys).createSession();\n session.addEventListener('keystatuseschange', () => {\n // recheck key statuses\n // NOTE: As an improvement, we could also add checks for a status of 'expired' and\n // attempt to renew the license here (CJP)\n session.keyStatuses.forEach((mediaKeyStatus) => {\n let mediaError;\n if (mediaKeyStatus === 'internal-error') {\n const message = i18n(\n 'The DRM Content Decryption Module system had an internal failure. Try reloading the page, upading your browser, or playing in another browser.'\n );\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_CDM_ERROR;\n } else if (mediaKeyStatus === 'output-restricted' || mediaKeyStatus === 'output-downscaled') {\n const message = i18n(\n 'DRM playback is being attempted in an environment that is not sufficiently secure. User may see black screen.'\n );\n // NOTE: When encountered, this is a non-fatal error (though it's certainly interruptive of standard playback experience). (CJP)\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, false);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_OUTPUT_RESTRICTED;\n }\n\n if (mediaError) {\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: mediaError,\n })\n );\n }\n });\n });\n const message = await Promise.all([\n session.generateRequest(initDataType, initData).catch(() => {\n // eslint-disable-next-line no-shadow\n const message = i18n(\n 'Failed to generate a DRM license request. This may be an issue with the player or your protected content.'\n );\n const mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_GENERATE_REQUEST_FAILED;\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: mediaError,\n })\n );\n }),\n new Promise<MediaKeyMessageEvent['message']>((resolve) => {\n session.addEventListener(\n 'message',\n (messageEvent) => {\n resolve(messageEvent.message);\n },\n { once: true }\n );\n }),\n ]).then(([, messageEventMsg]) => messageEventMsg);\n session.generateRequest(initDataType, initData);\n\n const response = await getLicenseKey(message, toLicenseKeyURL(props, 'fairplay')).catch((errOrResp) => {\n if (errOrResp instanceof Response) {\n const mediaError = getErrorFromResponse(errOrResp, MuxErrorCategory.DRM, props);\n console.error('mediaError', mediaError?.message, mediaError?.context);\n if (mediaError) {\n return Promise.reject(mediaError);\n }\n // NOTE: This should never happen. Adding for exhaustiveness (CJP).\n return Promise.reject(new Error('Unexpected error in license key request'));\n }\n return Promise.reject(errOrResp);\n });\n await session.update(response).catch(() => {\n // eslint-disable-next-line no-shadow\n const message = i18n(\n 'Failed to update DRM license. This may be an issue with the player or your protected content.'\n );\n const mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_UPDATE_LICENSE_FAILED;\n return Promise.reject(mediaError);\n });\n // @ts-ignore\n } catch (error: Error | MediaError) {\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n return;\n }\n };\n\n addEventListenerWithTeardown(mediaEl, 'encrypted', onFpEncrypted);\n};\n\nexport const toLicenseKeyURL = (\n {\n playbackId: playbackIdWithParams,\n tokens: { drm: token } = {},\n customDomain = MUX_VIDEO_DOMAIN,\n }: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'tokens' | 'customDomain'>>,\n scheme: 'widevine' | 'playready' | 'fairplay'\n) => {\n const playbackId = toPlaybackIdFromParameterized(playbackIdWithParams);\n // NOTE: Mux Video currently doesn't support custom domains for license/DRM endpoints, but\n // customDomain can also be used for internal use cases, so treat that as an exception case for now. (CJP)\n const domain = customDomain.toLocaleLowerCase().endsWith(MUX_VIDEO_DOMAIN) ? customDomain : MUX_VIDEO_DOMAIN;\n return `https://license.${domain}/license/${scheme}/${playbackId}?token=${token}`;\n};\n\nexport const toAppCertURL = (\n {\n playbackId: playbackIdWithParams,\n tokens: { drm: token } = {},\n customDomain = MUX_VIDEO_DOMAIN,\n }: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'tokens' | 'customDomain'>>,\n scheme: 'widevine' | 'playready' | 'fairplay'\n) => {\n const playbackId = toPlaybackIdFromParameterized(playbackIdWithParams);\n // NOTE: Mux Video currently doesn't support custom domains for license/DRM endpoints, but\n // customDomain can also be used for internal use cases, so treat that as an exception case for now. (CJP)\n const domain = customDomain.toLocaleLowerCase().endsWith(MUX_VIDEO_DOMAIN) ? customDomain : MUX_VIDEO_DOMAIN;\n return `https://license.${domain}/appcert/${scheme}/${playbackId}?token=${token}`;\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 | 'disableTracking'\n >\n >,\n mediaEl: HTMLMediaElement,\n hlsjs?: HlsInterface\n) => {\n const { envKey: env_key, disableTracking } = props;\n const inferredEnv = isMuxVideoSrc(props);\n\n if (!disableTracking && (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<\n Pick<\n MuxMediaProps,\n | 'preferPlayback'\n | 'src'\n | 'type'\n | 'startTime'\n | 'streamType'\n | 'autoplay'\n | 'playbackId'\n | 'tokens'\n | 'customDomain'\n >\n >,\n mediaEl: HTMLMediaElement,\n hls?: Pick<\n Hls,\n | 'config'\n | 'on'\n | 'once'\n | 'off'\n | 'trigger'\n | 'startLoad'\n | 'stopLoad'\n | 'recoverMediaError'\n | 'destroy'\n | 'loadSource'\n | 'attachMedia'\n | 'liveSyncPosition'\n | 'subtitleTracks'\n | 'subtitleTrack'\n | 'userConfig'\n | 'audioTrack'\n | 'audioTracks'\n | 'autoLevelEnabled'\n | 'nextLevel'\n | 'levels'\n | 'currentLevel'\n >\n) => {\n const shouldUseNative = useNative(props, mediaEl);\n const { src } = props;\n\n const maybeDispatchEndedCallback = () => {\n // We want to early bail if the underlying media element is already in an ended state,\n // since that means it will have already fired the ended event.\n // Do the \"cheaper\" check first\n if (mediaEl.ended) return;\n const pseudoEnded = getEnded(mediaEl, hls);\n if (!pseudoEnded) return;\n\n if (isStuckOnLastFragment(mediaEl, hls)) {\n // Nudge the playhead in this case.\n mediaEl.currentTime = mediaEl.buffered.end(mediaEl.buffered.length - 1);\n } else {\n mediaEl.dispatchEvent(new Event('ended'));\n }\n };\n\n let prevSeekableStart: number | undefined;\n let prevSeekableEnd: number | undefined;\n\n const seekableChange = () => {\n const seekableTimeRanges = getSeekable(mediaEl);\n let nextSeekableStart: number | undefined;\n let nextSeekableEnd: number | undefined;\n if (seekableTimeRanges.length > 0) {\n nextSeekableStart = seekableTimeRanges.start(0);\n nextSeekableEnd = seekableTimeRanges.end(0);\n }\n if (prevSeekableEnd !== nextSeekableEnd || prevSeekableStart !== nextSeekableStart) {\n mediaEl.dispatchEvent(new CustomEvent('seekablechange', { composed: true }));\n }\n prevSeekableStart = nextSeekableStart;\n prevSeekableEnd = nextSeekableEnd;\n };\n\n // Make sure we track transitions from infinite to finite durations for seekable changes as well.\n addEventListenerWithTeardown(mediaEl, 'durationchange', seekableChange);\n\n if (mediaEl && shouldUseNative) {\n const type = getType(props);\n if (typeof src === 'string') {\n // NOTE: This should only be invoked after stream type has been\n // derived after stream type has been determined.\n const setupSeekableChangePoll = () => {\n // Only monitor for seekable updates if StreamType is \"live\" and duration is not finite.\n if (getStreamType(mediaEl) !== StreamTypes.LIVE || Number.isFinite(mediaEl.duration)) return;\n\n // Use 1 second since in this context we don't know what the rate of updates\n // should/will be.\n // NOTE: We *could* derive the interval rate if we wanted to add logic to our playlist parsing to\n // account for the per-spec rate of media playlist GETs. See:\n // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-14#section-6.3.4 (CJP)\n const intervalId = setInterval(seekableChange, 1000);\n\n // Make sure we clean up after ourselves.\n mediaEl.addEventListener(\n 'teardown',\n () => {\n clearInterval(intervalId);\n },\n { once: true }\n );\n\n // Assume we're done updating seekable when the duration is finite, which\n // occurs when e.g. an HLS playlist is ended (`#EXT-X-ENDLIST`).\n addEventListenerWithTeardown(mediaEl, 'durationchange', () => {\n if (!Number.isFinite(mediaEl.duration)) return;\n clearInterval(intervalId);\n });\n };\n const setupNativeStreamInfo = async () => {\n return updateStreamInfoFromSrc(src, mediaEl, type)\n .then(setupSeekableChangePoll)\n .catch((errOrResp: Response | Error) => {\n if (errOrResp instanceof Response) {\n const mediaError = getErrorFromResponse(errOrResp, MuxErrorCategory.VIDEO, props);\n if (mediaError) {\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: mediaError,\n })\n );\n return;\n }\n } else if (errOrResp instanceof Error) {\n // mediaEl.dispatchEvent(new MediaError())\n }\n });\n };\n if (mediaEl.preload === 'none') {\n // NOTE: Previously, we relied on the 'loadstart' event to fetch & parse playlists for stream\n // info for native playback scenarios. Unfortunately, per spec this event will be dispatched\n // regardless of the preload state and regardless of whether or not fetching of the src media\n // has, in fact, begun. In order to respect the provided preferences and avoid eager loading\n // while still attempting to begin fetching playlists for stream info as early as possible when\n // media *will* be loaded, we will do a \"first to the finish line\" on both the 'play' event,\n // which will be dispatched earlier *if* it is the event that initiates media loading, and the\n // 'loadedmetadata' event, which is dispatched only after the media has finished loading metadata,\n // but will reliably correlate with media loading. (CJP)\n // For more, see: Steps 7 & 8 of 'the resource selection algorithm' from \u00A74.8.11.5 Loading the\n // media resource in the HTML Living Standard\n // (https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm)\n const playHandler = () => {\n setupNativeStreamInfo();\n mediaEl.removeEventListener('loadedmetadata', loadedMetadataHandler);\n };\n const loadedMetadataHandler = () => {\n setupNativeStreamInfo();\n mediaEl.removeEventListener('play', playHandler);\n };\n addEventListenerWithTeardown(mediaEl, 'play', playHandler, { once: true });\n addEventListenerWithTeardown(mediaEl, 'loadedmetadata', loadedMetadataHandler, { once: true });\n } else {\n setupNativeStreamInfo();\n }\n\n // NOTE: Currently use drmToken to signal that playback is expected to be DRM-protected\n if (props.tokens?.drm) {\n setupNativeFairplayDRM(props, mediaEl);\n } else {\n // If we end up receiving an encrypted event in this case, that means the media is DRM-protected\n // but a token was not provided.\n addEventListenerWithTeardown(\n mediaEl,\n 'encrypted',\n () => {\n const message = i18n('Attempting to play DRM-protected content without providing a DRM token.');\n const mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_MISSING_TOKEN;\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: mediaError,\n })\n );\n },\n { once: true }\n );\n }\n\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 mediaEl.addEventListener(\n 'emptied',\n () => {\n const trackEls: NodeListOf<HTMLTrackElement> = mediaEl.querySelectorAll('track[data-removeondestroy]');\n trackEls.forEach((trackEl) => {\n trackEl.remove();\n });\n },\n { once: true }\n );\n\n addEventListenerWithTeardown(mediaEl, 'pause', maybeDispatchEndedCallback);\n // NOTE: Browsers do not consistently fire an 'ended' event upon seeking to the\n // end of the media while already paused. This was due to an ambiguity in the\n // HTML specification, but is now more explicit.\n // See: https://html.spec.whatwg.org/multipage/media.html#reaches-the-end (CJP)\n addEventListenerWithTeardown(mediaEl, 'seeked', maybeDispatchEndedCallback);\n\n addEventListenerWithTeardown(mediaEl, 'play', () => {\n if (mediaEl.ended) return;\n if (!isApproximatelyGTE(mediaEl.currentTime, mediaEl.duration)) return;\n // If we were \"pseudo-ended\" before playback was attempted, seek back to the\n // beginning to \"replay\", like \"real\" ended behavior.\n mediaEl.currentTime = mediaEl.seekable.length ? mediaEl.seekable.start(0) : 0;\n });\n } else if (hls && src) {\n hls.once(Hls.Events.LEVEL_LOADED, (_evt, data) => {\n updateStreamInfoFromHlsjsLevelDetails(data.details, mediaEl, hls);\n seekableChange();\n // Only monitor for seekable updates if StreamType is \"live\" and duration is not finite.\n if (getStreamType(mediaEl) === StreamTypes.LIVE && !Number.isFinite(mediaEl.duration)) {\n hls.on(Hls.Events.LEVEL_UPDATED, seekableChange);\n\n // Assume we're done updating seekable when the duration is finite, which\n // occurs when e.g. an HLS playlist is ended (`#EXT-X-ENDLIST`).\n addEventListenerWithTeardown(mediaEl, 'durationchange', () => {\n if (!Number.isFinite(mediaEl.duration)) return;\n hls.off(Hls.Events.LEVELS_UPDATED, seekableChange);\n });\n }\n });\n\n hls.on(Hls.Events.ERROR, (_event, data) => {\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: getErrorFromHlsErrorData(data, props),\n })\n );\n });\n mediaEl.addEventListener('error', handleInternalError);\n addEventListenerWithTeardown(mediaEl, 'waiting', maybeDispatchEndedCallback);\n\n setupMediaTracks(props as HTMLMediaElement, hls);\n setupTextTracks(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 // This accounts for cases where native playback is being used but\n // a non-200 response occurs on the request for the playback-id's playlist.\n // In this case, we currently already fetch the playlist in parallel (for\n // things like inferring the stream type, live edge start window, etc.),\n // so we'll wait briefly for that response to translate to a more accurate\n // error.\n if (\n mediaEl.src &&\n code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED &&\n mediaEl.readyState === HTMLMediaElement.HAVE_NOTHING\n ) {\n setTimeout(() => {\n const ourError = getError(mediaEl) ?? mediaEl.error;\n // If the code is (still) MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED,\n // assume it's an (unlikely) case where we did, in fact, encounter\n // media that is unsupported.\n if (ourError?.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {\n mediaEl.dispatchEvent(\n new CustomEvent('error', {\n detail: error,\n })\n );\n }\n // Since a parallel request for the source should be initiated to determine\n // stream info (e.g. streamType) at roughly the same time as when the source\n // is loaded by the media element, we should be able to keep this timeout short.\n // NOTE: Although there is a case where the parallel request may happen later\n // (namely, after metadata is loaded), this should be mutually exclusive from\n // the case we're accounting for here, since unsupported media should not\n // ever get metadata loaded in the first place. (CJP)\n }, 500);\n return;\n }\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);\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 | CustomEvent<MediaError>) {\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 as unknown as HTMLMediaElement['error'];\n\n // Only pass valid mux-embed props: player_error_code, player_error_message, player_error_context\n mediaEl.mux?.emit('error', {\n player_error_code: error.code,\n player_error_message: error.message,\n player_error_context: error.context,\n });\n}\n\nconst getErrorFromHlsErrorData = (\n data: ErrorData,\n props: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'drmToken' | 'playbackToken' | 'tokens'>>\n) => {\n console.error('getErrorFromHlsErrorData()', data);\n const ErrorCodeMap: Partial<Record<ValueOf<typeof Hls.ErrorTypes>, 0 | 1 | 2 | 3 | 4 | 5>> = {\n [Hls.ErrorTypes.NETWORK_ERROR]: MediaError.MEDIA_ERR_NETWORK,\n [Hls.ErrorTypes.MEDIA_ERROR]: MediaError.MEDIA_ERR_DECODE,\n [Hls.ErrorTypes.KEY_SYSTEM_ERROR]: MediaError.MEDIA_ERR_ENCRYPTED,\n } as const;\n\n // eslint-disable-next-line no-shadow\n const hlsErrorDataToErrorCode = (data: ErrorData) => {\n if (\n [\n ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED,\n ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED,\n ].includes(data.details)\n ) {\n return MediaError.MEDIA_ERR_NETWORK;\n }\n return ErrorCodeMap[data.type];\n };\n\n // eslint-disable-next-line no-shadow\n const hlsErrorDataToCategory = (data: ErrorData) => {\n if (data.type === ErrorTypes.KEY_SYSTEM_ERROR) return MuxErrorCategory.DRM;\n if (data.type === ErrorTypes.NETWORK_ERROR) return MuxErrorCategory.VIDEO;\n };\n\n let mediaError: MediaError;\n const errorCode = hlsErrorDataToErrorCode(data);\n if (errorCode === MediaError.MEDIA_ERR_NETWORK && data.response) {\n const category = hlsErrorDataToCategory(data) ?? MuxErrorCategory.VIDEO;\n mediaError = getErrorFromResponse(data.response, category, props) ?? new MediaError('', errorCode);\n } else if (errorCode === MediaError.MEDIA_ERR_ENCRYPTED) {\n if (data.details === ErrorDetails.KEY_SYSTEM_NO_CONFIGURED_LICENSE) {\n const message = i18n('Attempting to play DRM-protected content without providing a DRM token.');\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, data.fatal);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_MISSING_TOKEN;\n } else if (data.details === ErrorDetails.KEY_SYSTEM_NO_ACCESS) {\n /** @TODO For UI message add suggestion to try another browser */\n const message = i18n(\n 'Cannot play DRM-protected content with current security configuration on this browser. Try playing in another browser.'\n );\n // Should we flag this as a business exception?\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, data.fatal);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_UNSUPPORTED_KEY_SYSTEM;\n } else if (data.details === ErrorDetails.KEY_SYSTEM_NO_SESSION) {\n const message = i18n(\n 'Failed to generate a DRM license request. This may be an issue with the player or your protected content.'\n );\n // NOTE: For some reason, perhaps due to issues with EXT-X-KEY parsing, hls.js defines this as a non-fatal error.\n // For us, we should be able to assume it is instead fatal. (CJP)\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, true);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_GENERATE_REQUEST_FAILED;\n } else if (data.details === ErrorDetails.KEY_SYSTEM_SESSION_UPDATE_FAILED) {\n const message = i18n(\n 'Failed to update DRM license. This may be an issue with the player or your protected content.'\n );\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, data.fatal);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_UPDATE_LICENSE_FAILED;\n } else if (data.details === ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED) {\n const message = i18n(\n 'Your server certificate failed when attempting to set it. This may be an issue with a no longer valid certificate.'\n );\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, data.fatal);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_UPDATE_SERVER_CERT_FAILED;\n } else if (data.details === ErrorDetails.KEY_SYSTEM_STATUS_INTERNAL_ERROR) {\n const message = i18n(\n 'The DRM Content Decryption Module system had an internal failure. Try reloading the page, upading your browser, or playing in another browser.'\n );\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, data.fatal);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_CDM_ERROR;\n } else if (data.details === ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED) {\n const message = i18n(\n 'DRM playback is being attempted in an environment that is not sufficiently secure. User may see black screen.'\n );\n // NOTE: When encountered, this is a non-fatal error (though it's certainly interruptive of standard playback experience). (CJP)\n mediaError = new MediaError(message, MediaError.MEDIA_ERR_ENCRYPTED, false);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_OUTPUT_RESTRICTED;\n } else {\n mediaError = new MediaError(data.error.message, MediaError.MEDIA_ERR_ENCRYPTED, data.fatal);\n mediaError.errorCategory = MuxErrorCategory.DRM;\n mediaError.muxCode = MuxErrorCode.ENCRYPTED_ERROR;\n }\n } else {\n mediaError = new MediaError('', errorCode, data.fatal);\n }\n if (!mediaError.context) {\n mediaError.context =\n `${data.url ? `url: ${data.url}\\n` : ''}` +\n `${\n data.response && (data.response.code || data.response.text)\n ? `response: ${data.response.code}, ${data.response.text}\\n`\n : ''\n }` +\n `${data.reason ? `failure reason: ${data.reason}\\n` : ''}` +\n `${data.level ? `level: ${data.level}\\n` : ''}` +\n `${data.parent ? `parent stream controller: ${data.parent}\\n` : ''}` +\n `${data.buffer ? `buffer length: ${data.buffer}\\n` : ''}` +\n `${data.error ? `error: ${data.error}\\n` : ''}` +\n `${data.event ? `event: ${data.event}\\n` : ''}` +\n `${data.err ? `error message: ${data.err?.message}\\n` : ''}`;\n }\n mediaError.data = data;\n return mediaError;\n};\n", "import Hls from 'hls.js';\nimport type HlsClassType from 'hls.js';\nexport default Hls;\nexport type HlsInterface = HlsClassType;\n", "// Identifies what kind of request was made that resulted in an error\nexport const MuxErrorCategory = {\n VIDEO: 'video',\n THUMBNAIL: 'thumbnail',\n STORYBOARD: 'storyboard',\n DRM: 'drm',\n} as const;\n\nexport const MuxErrorCode = {\n NOT_AN_ERROR: 0,\n NETWORK_OFFLINE: 2000002,\n NETWORK_UNKNOWN_ERROR: 2000000,\n NETWORK_NO_STATUS: 2000001,\n NETWORK_INVALID_URL: 2400000,\n NETWORK_NOT_FOUND: 2404000,\n NETWORK_NOT_READY: 2412000,\n NETWORK_GENERIC_SERVER_FAIL: 2500000,\n NETWORK_TOKEN_MISSING: 2403201,\n NETWORK_TOKEN_MALFORMED: 2412202,\n NETWORK_TOKEN_EXPIRED: 2403210,\n NETWORK_TOKEN_AUD_MISSING: 2403221,\n NETWORK_TOKEN_AUD_MISMATCH: 2403222,\n NETWORK_TOKEN_SUB_MISMATCH: 2403232,\n ENCRYPTED_ERROR: 5000000, // Generic\n ENCRYPTED_UNSUPPORTED_KEY_SYSTEM: 5000001,\n ENCRYPTED_GENERATE_REQUEST_FAILED: 5000002,\n ENCRYPTED_UPDATE_LICENSE_FAILED: 5000003,\n ENCRYPTED_UPDATE_SERVER_CERT_FAILED: 5000004,\n ENCRYPTED_CDM_ERROR: 5000005,\n ENCRYPTED_OUTPUT_RESTRICTED: 5000006,\n ENCRYPTED_MISSING_TOKEN: 5000002,\n} as const;\n\nexport type MuxErrorCategory = typeof MuxErrorCategory;\nexport type MuxErrorCode = typeof MuxErrorCode;\n\nexport type MuxErrorCategoryValue = MuxErrorCategory[keyof MuxErrorCategory];\nexport type MuxErrorCodeValue = MuxErrorCode[keyof MuxErrorCode];\n\nexport const errorCategoryToTokenNameOrPrefix = (category: MuxErrorCategoryValue) => {\n if (category === MuxErrorCategory.VIDEO) return 'playback';\n return category;\n};\n\nexport class MediaError extends Error {\n static MEDIA_ERR_ABORTED = 1 as const;\n static MEDIA_ERR_NETWORK = 2 as const;\n static MEDIA_ERR_DECODE = 3 as const;\n static MEDIA_ERR_SRC_NOT_SUPPORTED = 4 as const;\n static MEDIA_ERR_ENCRYPTED = 5 as const;\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 public muxCode?: MuxErrorCodeValue;\n public errorCategory?: MuxErrorCategoryValue;\n context?: string;\n fatal: boolean;\n data?: any;\n\n constructor(message?: string, code: number = MediaError.MEDIA_ERR_CUSTOM, fatal?: boolean, context?: string) {\n super(message);\n this.name = 'MediaError';\n this.code = code;\n this.context = context;\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", "/* eslint @typescript-eslint/triple-slash-reference: \"off\" */\n/// <reference path=\"../../../node_modules/mux-embed/dist/types/mux-embed.d.ts\" preserve=\"true\" />\nimport type { Options } from 'mux-embed';\nimport type { MediaError } from './errors';\nimport type { HlsConfig } from 'hls.js';\nimport type Hls from 'hls.js';\n\ntype KeyTypes = string | number | symbol;\ntype Maybe<T> = T | null | undefined;\n\nconst isNil = (x: unknown): x is null | undefined => x == undefined;\n\n// Type Guard to determine if a given key is actually a key of some object of type T\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport const isKeyOf = <T extends {} = any>(k: KeyTypes, o: Maybe<T>): k is keyof T => {\n if (isNil(o)) return false;\n return k in o;\n};\n\nexport type ValueOf<T> = T[keyof T];\nexport type Metadata = Partial<Required<Options>['data']>;\ntype MetaData = Metadata;\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 HlsPlaylistTypes = 'VOD' | 'EVENT' | null | undefined;\n\nexport type StreamTypes = {\n ON_DEMAND: 'on-demand';\n LIVE: 'live';\n UNKNOWN: 'unknown';\n};\n\nexport const StreamTypes: StreamTypes = {\n ON_DEMAND: 'on-demand',\n LIVE: 'live',\n UNKNOWN: 'unknown',\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 NONE: 'none';\n};\n\nexport const CmcdTypes: CmcdTypes = {\n HEADER: 'header',\n QUERY: 'query',\n NONE: 'none',\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\n// Both cuepoints and chapters have optional end times\n// so support both joined up and sparse cue placements\ntype CueLike<T = any> = {\n startTime: number;\n endTime?: number;\n value: T;\n};\nexport type CuePoint<T = any> =\n | CueLike<T> // new shape\n | { time: number; value: T }; // legacy shape, still supported for now\nexport type Chapter = CueLike<string>;\n\nexport const MaxResolution = {\n upTo720p: '720p',\n upTo1080p: '1080p',\n upTo1440p: '1440p',\n upTo2160p: '2160p',\n} as const;\n\nexport const MinResolution = {\n noLessThan480p: '480p',\n noLessThan540p: '540p',\n noLessThan720p: '720p',\n noLessThan1080p: '1080p',\n noLessThan1440p: '1440p',\n noLessThan2160p: '2160p',\n} as const;\n\nexport const RenditionOrder = {\n DESCENDING: 'desc',\n} as const;\n\nexport type MaxResolutionValue = ValueOf<typeof MaxResolution>;\nexport type MinResolutionValue = ValueOf<typeof MinResolution>;\nexport type RenditionOrderValue = ValueOf<typeof RenditionOrder>;\n\nexport type Tokens = {\n playback?: string;\n drm?: string;\n thumbnail?: string;\n storyboard?: string;\n};\n\nexport type MuxMediaPropTypes = {\n _hlsConfig?: Partial<HlsConfig>;\n autoPlay?: Autoplay;\n autoplay?: Autoplay;\n beaconCollectionDomain: Options['beaconCollectionDomain'];\n customDomain: string;\n debug: Options['debug'] & Hls['config']['debug'];\n disableCookies: Options['disableCookies'];\n disableTracking: boolean;\n drmToken?: string;\n playbackToken?: string;\n envKey: MetaData['env_key'];\n error?: HTMLMediaElement['error'] | MediaError;\n errorTranslator: Options['errorTranslator'];\n liveEdgeStart: number;\n maxResolution: MaxResolutionValue;\n metadata: Partial<Options['data']>;\n minResolution: MinResolutionValue;\n playbackId: string;\n playerInitTime: MetaData['player_init_time'];\n preferCmcd: ValueOf<CmcdTypes> | undefined;\n preferPlayback: ValueOf<PlaybackTypes> | undefined;\n programStartTime: number;\n programEndTime: number;\n assetStartTime: number;\n assetEndTime: number;\n renditionOrder: RenditionOrderValue;\n startTime: Hls['config']['startPosition'];\n streamType: ValueOf<StreamTypes>;\n targetLiveWindow: number;\n tokens: Tokens;\n type: MediaTypes;\n extraSourceParams: Record<string, any>;\n};\n\nexport type HTMLMediaElementProps = Partial<Pick<HTMLMediaElement, 'src' | 'preload' | 'error' | 'seekable'>>;\n\nexport type MuxMediaProps = HTMLMediaElementProps & MuxMediaPropTypes;\nexport type MuxMediaPropsInternal = MuxMediaProps & {\n playerSoftwareName: MetaData['player_software_name'];\n playerSoftwareVersion: MetaData['player_software_version'];\n drmTypeCb?: (drmType: Metadata['view_drm_type']) => void;\n};\n", "const code = 'en'; export default { code }", "import { isKeyOf, ExtensionMimeTypeMap, MimeTypeShorthandMap, StreamTypes } from './types';\nimport type { HlsPlaylistTypes, MuxMediaProps } from './types';\n// @ts-ignore\nimport lang from '../lang/en.json';\n\ntype addEventListenerWithTeardown = <\n K extends keyof HTMLMediaElementEventMap,\n T extends EventTarget = HTMLMediaElement,\n>(\n mediaEl: HTMLMediaElement,\n type: K,\n listener: (this: T, ev: HTMLMediaElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n target?: T | HTMLMediaElement\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 = (\n mediaEl,\n type,\n listener,\n options,\n target = mediaEl\n) => {\n /** @TODO fix types (hard problem due to lack of explicit relationship between Element and EventMap definitions) */\n // @ts-ignore\n target.addEventListener(type, listener, options);\n // NOTE: Using custom teardown\n mediaEl.addEventListener(\n 'teardown',\n () => {\n /** @TODO fix types (hard problem due to lack of explicit relationship between Element and EventMap definitions) */\n // @ts-ignore\n target.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; 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 toStreamTypeFromPlaylistType = (playlistType: HlsPlaylistTypes) => {\n return playlistType === 'VOD' ? StreamTypes.ON_DEMAND : StreamTypes.LIVE;\n};\n\nexport const toTargetLiveWindowFromPlaylistType = (playlistType: HlsPlaylistTypes) => {\n if (playlistType === 'EVENT') return Number.POSITIVE_INFINITY;\n if (playlistType === 'VOD') return Number.NaN;\n return 0;\n};\n\nexport const inferMimeTypeFromURL = (url: string) => {\n let pathname = '';\n try {\n pathname = new URL(url).pathname;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\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\nexport type MuxJWT = {\n sub: string;\n aud: 'v' | 't' | 'g' | 's' | 'd';\n exp: number;\n};\n\nexport const parseJwt = (token: string | undefined): Partial<MuxJWT> | undefined => {\n const base64Url = (token ?? '').split('.')[1];\n\n // exit early on invalid value\n if (!base64Url) return undefined;\n\n // Account for malformed JWTs\n try {\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(function (c) {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n return JSON.parse(jsonPayload);\n } catch {\n return undefined;\n }\n};\n\nexport const isJWTExpired = ({ exp }: Partial<Pick<MuxJWT, 'exp'>>, referenceTime: number = Date.now()) => {\n return !exp || exp * 1000 < referenceTime;\n};\n\n// NOTE: Treating missing sub (and expected sub) as mismatches for now (CJP)\nexport const isJWTSubMismatch = ({ sub }: Partial<Pick<MuxJWT, 'sub'>>, expectedSub: string | undefined) => {\n return sub !== expectedSub;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const isJWTAudMissing = ({ aud }: Partial<Pick<MuxJWT, 'aud'>>, _expectedAud: string | undefined) => {\n return !aud;\n};\n\nexport const isJWTAudMismatch = ({ aud }: Partial<Pick<MuxJWT, 'aud'>>, expectedAud: string | undefined) => {\n return aud !== expectedAud;\n};\n\nconst DEFAULT_LOCALE = 'en';\n\n// NL example\n// lang = {\n// \"Network Error\": \"Netwerk Fout\",\n// };\nexport function i18n(str: string, translate = true): any {\n const message = translate ? (lang as unknown as any)?.[str] ?? str : str;\n const locale = translate ? (lang as unknown as any).code : DEFAULT_LOCALE;\n return new IntlMessageFormat(message, locale);\n}\n\n/**\n * Poor man's IntlMessageFormat, enrich if need be.\n * @see https://formatjs.io/docs/intl-messageformat/\n */\nclass IntlMessageFormat {\n message: string;\n locale: string;\n\n /** @TODO re-implement esbuild custom plugin for code usage (CJP) */\n constructor(message: string, locale = (lang as unknown as any) ?? DEFAULT_LOCALE) {\n this.message = message;\n this.locale = locale;\n }\n\n format(values: Record<string, any>): string {\n return this.message.replace(/\\{(\\w+)\\}/g, (match, key) => {\n return values[key] ?? '';\n });\n }\n\n toString() {\n return this.message;\n }\n}\n", "import { addEventListenerWithTeardown } from './util';\nimport { ValueOf, Autoplay, AutoplayTypes, PlaybackEngine, MuxMediaPropsInternal, StreamTypes } from './types';\nimport Hls from './hls';\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 props: Partial<MuxMediaPropsInternal>,\n mediaEl: HTMLMediaElement,\n hls?: PlaybackEngine\n) => {\n const { autoplay: maybeAutoplay } = props;\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 // defer to streamType if set (including inferred)\n if (props.streamType && props.streamType !== StreamTypes.UNKNOWN) {\n isLive = props.streamType === StreamTypes.LIVE;\n } else {\n isLive = !Number.isFinite(mediaEl.duration);\n }\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 // defer to streamType if set (including inferred)\n if (props.streamType && props.streamType !== StreamTypes.UNKNOWN) {\n isLive = props.streamType === StreamTypes.LIVE;\n } else {\n isLive = data.details.live ?? false;\n }\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 or if a `startTime` has been explicitly set\n if (!isLive || Number.isFinite(props.startTime)) {\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 { 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';\n\nexport function setupMediaTracks(\n customMediaEl: HTMLMediaElement,\n hls: Pick<\n Hls,\n 'audioTrack' | 'audioTracks' | 'autoLevelEnabled' | 'nextLevel' | 'levels' | 'on' | 'once' | 'off' | 'trigger'\n >\n) {\n if (!('videoTracks' in customMediaEl)) return;\n\n // Create a map to save the unique id's we create for each level and rendition.\n // hls.js uses the levels array index primarily but we'll use the id to have a\n // 1 to 1 relation from rendition to level.\n const levelIdMap = new WeakMap();\n\n hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {\n removeAllMediaTracks();\n\n const videoTrack = customMediaEl.addVideoTrack('main');\n videoTrack.selected = true;\n\n for (const [id, level] of data.levels.entries()) {\n const videoRendition = videoTrack.addRendition(\n level.url[0],\n level.width,\n level.height,\n level.videoCodec,\n level.bitrate\n );\n\n // The returned levels all have an id of `0`, save the id in a WeakMap.\n levelIdMap.set(level, `${id}`);\n videoRendition.id = `${id}`;\n }\n });\n\n hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, function (event, data) {\n removeAudioTracks();\n\n for (const a of data.audioTracks) {\n // hls.js doesn't return a `kind` property for audio tracks yet.\n const kind = a.default ? 'main' : 'alternative';\n const audioTrack = customMediaEl.addAudioTrack(kind, a.name, a.lang);\n audioTrack.id = `${a.id}`;\n\n if (a.default) {\n audioTrack.enabled = true;\n }\n }\n });\n\n customMediaEl.audioTracks.addEventListener('change', () => {\n // Cast to number, hls.js uses numeric id's.\n const audioTrackId = +[...customMediaEl.audioTracks].find((t) => t.enabled)?.id;\n const availableIds = hls.audioTracks.map((t) => t.id);\n if (audioTrackId != hls.audioTrack && availableIds.includes(audioTrackId)) {\n hls.audioTrack = audioTrackId;\n }\n });\n\n // Fired when a level is removed after calling `removeLevel()`\n hls.on(Hls.Events.LEVELS_UPDATED, function (event, data) {\n const videoTrack = customMediaEl.videoTracks[customMediaEl.videoTracks.selectedIndex ?? 0];\n if (!videoTrack) return;\n\n const levelIds: string[] = data.levels.map((l) => levelIdMap.get(l));\n\n for (const rendition of customMediaEl.videoRenditions) {\n if (rendition.id && !levelIds.includes(rendition.id)) {\n videoTrack.removeRendition(rendition);\n }\n }\n });\n\n // hls.js doesn't support enabling multiple renditions.\n //\n // 1. if all renditions are enabled it's auto selection.\n // 2. if 1 of the renditions is disabled we assume a selection was made\n // and lock it to the first rendition that is enabled.\n const switchRendition = (event: Event) => {\n // @ts-ignore\n const level = event.target.selectedIndex as number;\n if (level != hls.nextLevel) {\n smoothSwitch(level);\n }\n };\n\n // Workaround for issue changing renditions on an alternative audio track.\n // https://github.com/video-dev/hls.js/issues/5749#issuecomment-1684629437\n const smoothSwitch = (levelIndex: number) => {\n const currentTime = customMediaEl.currentTime;\n let flushedFwdBuffer = false;\n\n const callback = (event: string, data: { endOffset: number }) => {\n flushedFwdBuffer ||= !Number.isFinite(data.endOffset);\n };\n\n hls.on(Hls.Events.BUFFER_FLUSHING, callback);\n hls.nextLevel = levelIndex;\n hls.off(Hls.Events.BUFFER_FLUSHING, callback);\n\n if (!flushedFwdBuffer) {\n hls.trigger(Hls.Events.BUFFER_FLUSHING, {\n startOffset: currentTime + 10,\n endOffset: Infinity,\n type: 'video',\n });\n }\n };\n\n customMediaEl.videoRenditions?.addEventListener('change', switchRendition);\n\n const removeVideoTracks = () => {\n for (const videoTrack of customMediaEl.videoTracks) {\n customMediaEl.removeVideoTrack(videoTrack);\n }\n };\n\n const removeAudioTracks = () => {\n for (const audioTrack of customMediaEl.audioTracks) {\n customMediaEl.removeAudioTrack(audioTrack);\n }\n };\n\n const removeAllMediaTracks = () => {\n removeVideoTracks();\n removeAudioTracks();\n };\n\n // NOTE: Since this is only relevant for hls, using destroying event (CJP).\n hls.once(Hls.Events.DESTROYING, removeAllMediaTracks);\n}\n", "import Hls from './hls';\nimport { CuePoint, Chapter } from './types';\nimport { addEventListenerWithTeardown } from './util';\n\ntype Config = { label: string };\n\n// Shared utils\n\n// Extracts the start time from a cuepoint, considering legacy \"time\" prop\nconst cuePointStart = (cuePoint: CuePoint): number => {\n if ('time' in cuePoint) {\n return cuePoint.time;\n }\n return cuePoint.startTime;\n};\n\nexport function setupTextTracks(\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 // NOTE: Undocumented method for determining identifier by hls.js. Relied on for\n // ensuring CUES_PARSED events can identify and apply cues to the appropriate track (CJP).\n // See: https://github.com/video-dev/hls.js/blob/master/src/controller/timeline-controller.ts#L640\n const id = trackObj._id ?? trackObj.default ? 'default' : `${trackObj.kind}${idx}`;\n\n addTextTrack(mediaEl, trackObj.kind as TextTrackKind, trackObj.label, baseTrackObj?.lang, id, trackObj.default);\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 (!showingTrack) return;\n\n const currentHlsTrack = hls.subtitleTracks[hls.subtitleTrack];\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 = !currentHlsTrack\n ? undefined\n : currentHlsTrack.default\n ? 'default'\n : `${hls.subtitleTracks[hls.subtitleTrack].type.toLowerCase()}${hls.subtitleTrack}`;\n\n if (hls.subtitleTrack < 0 || showingTrack?.id !== hlsTrackId) {\n const idx = hls.subtitleTracks.findIndex(({ lang, name, type, default: defaultTrack }) => {\n return (\n (showingTrack.id === 'default' && defaultTrack) ||\n (lang == showingTrack.language && name === showingTrack.label && type.toLowerCase() === showingTrack.kind)\n );\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?.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 forceHiddenTracks = () => {\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' || track.kind === 'chapters')) return;\n if (!track.cues?.length) {\n let selector = 'track';\n if (track.kind) selector += `[kind=\"${track.kind}\"]`;\n if (track.label) selector += `[label=\"${track.label}\"]`;\n const trackEl = mediaEl.querySelector(selector);\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, forceHiddenTracks);\n hls.once(Hls.Events.MEDIA_ATTACHED, forceHiddenTracks);\n}\n\nexport function addTextTrack(\n mediaEl: HTMLMediaElement,\n kind: TextTrackKind,\n label: string,\n lang?: string,\n id?: string,\n defaultTrack?: boolean\n): TextTrack {\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 if (!!defaultTrack) {\n trackEl.default = true;\n }\n trackEl.track.mode = ['subtitles', 'captions'].includes(kind) ? 'disabled' : 'hidden';\n\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\n return trackEl.track as TextTrack;\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\nexport function getTextTrack(mediaEl: HTMLMediaElement, label: string, kind: TextTrackKind) {\n return Array.from(mediaEl.querySelectorAll('track')).find((trackEl) => {\n return trackEl.track.label === label && trackEl.track.kind === kind;\n })?.track;\n}\n\nexport async function addCuesToTextTrack<T = any>(\n mediaEl: HTMLMediaElement,\n cues: CuePoint<T>[] | Chapter[],\n label: string,\n kind: TextTrackKind\n) {\n // If the track has already been created/added, use it.\n let track = getTextTrack(mediaEl, label, kind);\n if (!track) {\n // Otherwise, create a new one\n track = addTextTrack(mediaEl, kind, label);\n track.mode = 'hidden';\n // Wait a tick before providing a newly created track. Otherwise e.g. cues disappear when using track.addCue().\n await new Promise((resolve) => setTimeout(() => resolve(undefined), 0));\n }\n\n if (track.mode !== 'hidden') {\n track.mode = 'hidden';\n }\n\n // Copy cuePoints to ensure sort is not mutative\n [...cues]\n // Sort descending to ensure last cuepoints are added as cues first. This is done\n // so the track's cue's can be used for reference when determining an appropriate\n // endTime, allowing support of multiple invocations of addCuePoints\n .sort((cuePointA, cuePointB) => cuePointStart(cuePointB) - cuePointStart(cuePointA))\n .forEach((cuePoint) => {\n const value = cuePoint.value;\n const startTime = cuePointStart(cuePoint);\n\n if ('endTime' in cuePoint && cuePoint.endTime != undefined) {\n track?.addCue(\n new VTTCue(\n startTime,\n cuePoint.endTime,\n kind === 'chapters' ? (value as string) : JSON.stringify(value ?? null)\n )\n );\n } else {\n // find the cue that starts immediately after the cuePoint's time\n const cueAfterIndex = Array.prototype.findIndex.call(track?.cues, (cue) => cue.startTime >= startTime);\n const cueAfter = track?.cues?.[cueAfterIndex];\n const endTime = cueAfter\n ? cueAfter.startTime\n : Number.isFinite(mediaEl.duration)\n ? mediaEl.duration\n : Number.MAX_SAFE_INTEGER;\n\n // Adjust the endTime of the already added previous cue,\n // if present, so it does not overlap with the newly added cue.\n const previousCue = track?.cues?.[cueAfterIndex - 1];\n if (previousCue) {\n previousCue.endTime = startTime;\n }\n track?.addCue(\n new VTTCue(startTime, endTime, kind === 'chapters' ? (value as string) : JSON.stringify(value ?? null))\n );\n }\n });\n\n // NOTE: this doesn't naturally fire when we update the list\n // of cue points (without changing the active cue). We manually\n // fire this to force the state manager to reflect the new change\n mediaEl.textTracks.dispatchEvent(\n new Event('change', {\n bubbles: true,\n composed: true,\n })\n );\n\n return track;\n}\n\n// Cuepoints\n\nconst DEFAULT_CUEPOINTS_TRACK_LABEL = 'cuepoints';\nexport const DefaultCuePointsConfig: Config = Object.freeze({ label: DEFAULT_CUEPOINTS_TRACK_LABEL });\n\nexport async function addCuePoints<T>(\n mediaEl: HTMLMediaElement,\n cuePoints: CuePoint<T>[],\n cuePointsConfig: Config = DefaultCuePointsConfig\n) {\n return addCuesToTextTrack(mediaEl, cuePoints, cuePointsConfig.label, 'metadata');\n}\n\nconst toCuePoint = (cue: VTTCue) => ({\n time: cue.startTime,\n value: JSON.parse(cue.text),\n});\n\nexport function getCuePoints(\n mediaEl: HTMLMediaElement,\n cuePointsConfig: Config = { label: DEFAULT_CUEPOINTS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, cuePointsConfig.label, 'metadata');\n if (!track?.cues) return [];\n return Array.from(track.cues, (cue) => toCuePoint(cue as VTTCue));\n}\n\nexport function getActiveCuePoint(\n mediaEl: HTMLMediaElement,\n cuePointsConfig: Config = { label: DEFAULT_CUEPOINTS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, cuePointsConfig.label, 'metadata');\n if (!track?.activeCues?.length) return undefined;\n if (track.activeCues.length === 1) return toCuePoint(track.activeCues[0] as VTTCue);\n // NOTE: There is a bug in Chromium where there may be \"lingering activeCues\" even\n // after the playhead is no longer within their [startTime, endTime) bounds. This\n // accounts for those cases (CJP)\n const { currentTime } = mediaEl;\n const actualActiveCue = Array.prototype.find.call(track.activeCues ?? [], ({ startTime, endTime }) => {\n return startTime <= currentTime && endTime > currentTime;\n }) as VTTCue | undefined;\n if (!actualActiveCue) {\n return toCuePoint(track.activeCues[0] as VTTCue);\n }\n return toCuePoint(actualActiveCue);\n}\n\nexport async function setupCuePoints(mediaEl: HTMLMediaElement, cuePointsConfig: Config = DefaultCuePointsConfig) {\n return new Promise((resolve) => {\n addEventListenerWithTeardown(mediaEl, 'loadstart', async () => {\n const track = await addCuePoints(mediaEl, [], cuePointsConfig);\n addEventListenerWithTeardown(\n mediaEl,\n 'cuechange',\n () => {\n const activeCuePoint = getActiveCuePoint(mediaEl);\n if (activeCuePoint) {\n const evt = new CustomEvent('cuepointchange', {\n composed: true,\n bubbles: true,\n detail: activeCuePoint,\n });\n mediaEl.dispatchEvent(evt);\n }\n },\n {},\n track\n );\n resolve(track);\n });\n });\n}\n\n/**\n * Chapters\n */\n\nconst DEFAULT_CHAPTERS_TRACK_LABEL = 'chapters';\nexport const DefaultChaptersConfig: Config = Object.freeze({ label: DEFAULT_CHAPTERS_TRACK_LABEL });\n\nconst vttCueToChapter = (cue: VTTCue) => ({\n startTime: cue.startTime,\n endTime: cue.endTime,\n value: cue.text,\n});\n\nexport async function addChapters(\n mediaEl: HTMLMediaElement,\n chapters: Chapter[],\n chaptersConfig: Config = DefaultChaptersConfig\n) {\n return addCuesToTextTrack(mediaEl, chapters, chaptersConfig.label, 'chapters');\n}\n\nexport function getChapters(\n mediaEl: HTMLMediaElement,\n chaptersConfig: Config = { label: DEFAULT_CHAPTERS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, chaptersConfig.label, 'chapters');\n if (!track?.cues?.length) return [];\n return Array.from(track.cues, (cue) => vttCueToChapter(cue as VTTCue));\n}\n\nexport function getActiveChapter(\n mediaEl: HTMLMediaElement,\n chaptersConfig: Config = { label: DEFAULT_CHAPTERS_TRACK_LABEL }\n) {\n const track = getTextTrack(mediaEl, chaptersConfig.label, 'chapters');\n if (!track?.activeCues?.length) return undefined;\n if (track.activeCues.length === 1) return vttCueToChapter(track.activeCues[0] as VTTCue);\n // NOTE: There is a bug in Chromium where there may be \"lingering activeCues\" even\n // after the playhead is no longer within their [startTime, endTime) bounds. This\n // accounts for those cases (CJP)\n const { currentTime } = mediaEl;\n const actualActiveCue = Array.prototype.find.call(track.activeCues ?? [], ({ startTime, endTime }) => {\n return startTime <= currentTime && endTime > currentTime;\n }) as VTTCue | undefined;\n if (!actualActiveCue) {\n return vttCueToChapter(track.activeCues[0] as VTTCue);\n }\n return vttCueToChapter(actualActiveCue);\n}\n\nexport async function setupChapters(mediaEl: HTMLMediaElement, chaptersConfig: Config = DefaultChaptersConfig) {\n return new Promise((resolve) => {\n addEventListenerWithTeardown(mediaEl, 'loadstart', async () => {\n const track = await addChapters(mediaEl, [], chaptersConfig);\n\n addEventListenerWithTeardown(\n mediaEl,\n 'cuechange',\n () => {\n const activeCuePoint = getActiveChapter(mediaEl);\n if (activeCuePoint) {\n const evt = new CustomEvent('chapterchange', {\n composed: true,\n bubbles: true,\n detail: activeCuePoint,\n });\n mediaEl.dispatchEvent(evt);\n }\n },\n {},\n track\n );\n\n resolve(track);\n });\n });\n}\n", "import { PlaybackEngine } from './types';\n\ntype MediaWithPDT = HTMLMediaElement & { getStartDate?: () => Date };\n\nexport function getStartDate(mediaEl: MediaWithPDT, hls: PlaybackEngine | undefined) {\n if (hls) {\n const playingDate = hls.playingDate;\n\n if (playingDate != null) {\n // If the video is very long and the currentTime will transition day boundaries,\n // this may end up not being accurate\n return new Date(playingDate.getTime() - mediaEl.currentTime * 1000);\n }\n }\n\n if (typeof mediaEl.getStartDate === 'function') {\n return mediaEl.getStartDate();\n }\n\n return new Date(NaN);\n}\n\nexport function getCurrentPdt(mediaEl: MediaWithPDT, hls: PlaybackEngine | undefined) {\n if (hls && hls.playingDate) {\n return hls.playingDate;\n }\n\n if (typeof mediaEl.getStartDate === 'function') {\n const startDate = mediaEl.getStartDate();\n\n // If the video is very long and the currentTime will transition day boundaries,\n // this may end up not being accurate\n return new Date(startDate.getTime() + mediaEl.currentTime * 1000);\n }\n\n return new Date(NaN);\n}\n", "import type { LoaderResponse } from 'hls.js';\nimport {\n i18n,\n isJWTAudMismatch,\n isJWTAudMissing,\n isJWTExpired,\n isJWTSubMismatch,\n parseJwt,\n toPlaybackIdParts,\n} from './util';\nimport { isKeyOf, MuxMediaPropsInternal } from './types';\nimport type { MuxErrorCategoryValue } from './errors';\nimport { errorCategoryToTokenNameOrPrefix, MediaError, MuxErrorCategory, MuxErrorCode } from './errors';\n\nexport const MuxJWTAud = {\n VIDEO: 'v',\n // NOTE: These are not \"built in\" for mux-video/mux-audio (only mux-player) (CJP)\n THUMBNAIL: 't',\n STORYBOARD: 's',\n // GIF: 'g', // currently unused\n DRM: 'd',\n} as const;\n\nexport const categoryToAud = (category: MuxErrorCategoryValue) => {\n if (category === MuxErrorCategory.VIDEO) return MuxJWTAud.VIDEO;\n if (category === MuxErrorCategory.DRM) return MuxJWTAud.DRM;\n};\n\nexport const categoryToToken = (\n category: MuxErrorCategoryValue,\n muxMediaEl: Partial<Pick<MuxMediaPropsInternal, 'drmToken' | 'playbackToken' | 'tokens'>>\n) => {\n const nameOrPrefix = errorCategoryToTokenNameOrPrefix(category);\n const tokenName = `${nameOrPrefix}Token` as const;\n if (muxMediaEl.tokens?.[nameOrPrefix]) return muxMediaEl.tokens?.[nameOrPrefix];\n return isKeyOf(tokenName, muxMediaEl) ? muxMediaEl[tokenName] : undefined;\n};\n\nexport const getErrorFromResponse = (\n resp: Pick<Response, 'status' | 'url'> | Pick<LoaderResponse, 'code' | 'url'>,\n category: MuxErrorCategoryValue,\n muxMediaEl: Partial<Pick<MuxMediaPropsInternal, 'playbackId' | 'drmToken' | 'playbackToken' | 'tokens'>>,\n translate = false,\n offline = !globalThis.navigator?.onLine // NOTE: Passing this in for testing purposes\n) => {\n if (offline) {\n const message = i18n(`Your device appears to be offline`, translate);\n const context = undefined;\n const mediaErrorCode = MediaError.MEDIA_ERR_NETWORK;\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_OFFLINE;\n mediaError.data = resp;\n return mediaError;\n }\n const status = 'status' in resp ? resp.status : resp.code;\n const requestTime = Date.now();\n const mediaErrorCode = MediaError.MEDIA_ERR_NETWORK;\n // Not an error. WHAT ARE YOU EVEN DOING HERE?!?\n if (status === 200) return undefined;\n const tokenNamePrefix = errorCategoryToTokenNameOrPrefix(category);\n const token = categoryToToken(category, muxMediaEl);\n const expectedAud = categoryToAud(category);\n const [playbackId] = toPlaybackIdParts(muxMediaEl.playbackId ?? '');\n // NOTE: *should* have playback id when reaching here\n // if (!status) return MuxErrorCode.NETWORK_NO_STATUS;\n if (!status || !playbackId) return undefined;\n\n const jwtObj = parseJwt(token);\n // Make sure we didn't get here because of a malformed JWT and/or claim\n if (!!token && !jwtObj) {\n // 403 for DRM\n const message = i18n(`The {tokenNamePrefix}-token provided is invalid or malformed.`, translate).format({\n tokenNamePrefix,\n });\n const context = i18n(`Compact JWT string: {token}`, translate).format({\n token,\n });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_TOKEN_MALFORMED;\n mediaError.data = resp;\n return mediaError;\n }\n\n if (status >= 500) {\n /**\n * @TODO We plausibly should have some basic retry logic for all other 500 status\n * cases (CJP)\n **/\n const mediaError = new MediaError('', mediaErrorCode, true);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_UNKNOWN_ERROR;\n /** @TODO Add error msg + context crud here (NOT YET DEFINED) (CJP) */\n return mediaError;\n }\n\n if (status === 403) {\n if (jwtObj) {\n if (isJWTExpired(jwtObj, requestTime)) {\n const dateOptions: any = {\n timeStyle: 'medium',\n dateStyle: 'medium',\n };\n // E.g. for DRM: \"The video\u2019s secured drm-token has expired.\"\n // E.g. for Video: \"The video\u2019s secured playback-token has expired.\"\n const message = i18n(`The video\u2019s secured {tokenNamePrefix}-token has expired.`, translate).format({\n tokenNamePrefix,\n });\n const context = i18n(`Expired at: {expiredDate}. Current time: {currentDate}.`, translate).format({\n expiredDate: new Intl.DateTimeFormat('en', dateOptions).format(jwtObj.exp ?? 0 * 1000),\n currentDate: new Intl.DateTimeFormat('en', dateOptions).format(requestTime),\n });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_TOKEN_EXPIRED;\n mediaError.data = resp;\n return mediaError;\n }\n if (isJWTSubMismatch(jwtObj, playbackId)) {\n const message = i18n(\n `The video\u2019s playback ID does not match the one encoded in the {tokenNamePrefix}-token.`,\n translate\n ).format({\n tokenNamePrefix,\n });\n const context = i18n(\n `Specified playback ID: {playbackId} and the playback ID encoded in the {tokenNamePrefix}-token: {tokenPlaybackId}`,\n translate\n ).format({\n tokenNamePrefix,\n playbackId,\n tokenPlaybackId: jwtObj.sub,\n });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_TOKEN_SUB_MISMATCH;\n mediaError.data = resp;\n return mediaError;\n }\n if (isJWTAudMissing(jwtObj, expectedAud)) {\n const message = i18n(`The {tokenNamePrefix}-token is formatted with incorrect information.`, translate).format({\n tokenNamePrefix,\n });\n const context = i18n(\n `The {tokenNamePrefix}-token has no aud value. aud value should be {expectedAud}.`,\n translate\n ).format({\n tokenNamePrefix,\n expectedAud,\n });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_TOKEN_AUD_MISSING;\n mediaError.data = resp;\n return mediaError;\n }\n if (isJWTAudMismatch(jwtObj, expectedAud)) {\n const message = i18n(`The {tokenNamePrefix}-token is formatted with incorrect information.`, translate).format({\n tokenNamePrefix,\n });\n const context = i18n(\n `The {tokenNamePrefix}-token has an incorrect aud value: {aud}. aud value should be {expectedAud}.`,\n translate\n ).format({\n tokenNamePrefix,\n expectedAud,\n aud: jwtObj.aud,\n });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_TOKEN_AUD_MISMATCH;\n mediaError.data = resp;\n return mediaError;\n }\n\n // NOTE: This *should* not happen for DRM, since the drm token\n // is currently used to detect whether or not DRM should\n // be setup at all. Including for exhaustiveness. (CJP)\n } else {\n const message = i18n(\n `Authorization error trying to access this {category} URL. If this is a signed URL, you might need to provide a {tokenNamePrefix}-token.`,\n translate\n ).format({\n tokenNamePrefix,\n category,\n });\n const context = i18n(`Specified playback ID: {playbackId}`, translate).format({ playbackId });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_TOKEN_MISSING;\n mediaError.data = resp;\n return mediaError;\n }\n }\n\n if (status === 412) {\n const message = i18n(\n `This playback-id may belong to a live stream that is not currently active or an asset that is not ready.`,\n translate\n );\n const context = i18n(`Specified playback ID: {playbackId}`, translate).format({ playbackId });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_NOT_READY;\n mediaError.data = resp;\n return mediaError;\n }\n\n /**\n * NOTE: When using a \"structurally valid but non-existent\" playback id for a DRM (license or app certificate) request, this will result in a 403 status.\n * However, since we will only currently make a DRM request after successfully loading the media, this case should not need\n * to be accounted for. If we ever eagerly fetch FPS app certs prior to or in parallel to media requests, we would potentially\n * want to account for that case (either by normalizing statuses, in our messaging for generic 403 above, or through more complex\n * solutions like waiting for the media response). (CJP)\n */\n if (status === 404) {\n // NOTE: This *should* not happen for DRM (only playback/media requests), since the URL should never be invalid if code\n // is correct. Aka if we end up here it's almost definitely a bug.\n const message = i18n(\n `This URL or playback-id does not exist. You may have used an Asset ID or an ID from a different resource.`,\n translate\n );\n const context = i18n(`Specified playback ID: {playbackId}`, translate).format({ playbackId });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_NOT_FOUND;\n mediaError.data = resp;\n return mediaError;\n }\n\n /**\n * NOTE: Omitting a token for a DRM (license or app certificate) request results in a 400 status, unlike playback/media requests,\n * which are a 403 status (See above).\n * However, since we will only currently setup Mux Player for DRM if a drm token is provided, this case should not need\n * to be accounted for. If we ever change this, we would potentially\n * want to account for that case (either by normalizing statuses, in our messaging for generic 400 above, or through more complex\n * solutions like checking the category before deciding on error details here). (CJP)\n */\n if (status === 400) {\n const message = i18n(`The URL or playback-id was invalid. You may have used an invalid value as a playback-id.`);\n const context = i18n(`Specified playback ID: {playbackId}`, translate).format({ playbackId });\n const mediaError = new MediaError(message, mediaErrorCode, true, context);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_INVALID_URL;\n mediaError.data = resp;\n return mediaError;\n }\n\n const mediaError = new MediaError('', mediaErrorCode, true);\n mediaError.errorCategory = category;\n mediaError.muxCode = MuxErrorCode.NETWORK_UNKNOWN_ERROR;\n mediaError.data = resp;\n return mediaError;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["src_exports", "__export", "AutoplayTypes", "CmcdTypeValues", "CmcdTypes", "ExtensionMimeTypeMap", "hls_default", "MaxResolution", "MediaError", "MimeTypeShorthandMap", "MinResolution", "MuxErrorCategory", "MuxErrorCode", "MuxJWTAud", "PlaybackTypes", "RenditionOrder", "StreamTypes", "addChapters", "addCuePoints", "addTextTrack", "allMediaTypes", "errorCategoryToTokenNameOrPrefix", "generatePlayerInitTime", "generateUUID", "getActiveChapter", "getActiveCuePoint", "getAppCertificate", "getChapters", "getCuePoints", "getCurrentPdt", "getDRMConfig", "getEnded", "getError", "getLicenseKey", "getLiveEdgeStart", "getMediaPlaylistLinesFromMultivariantPlaylistSrc", "getSeekable", "getStartDate", "getStreamInfoFromHlsjsLevelDetails", "getStreamInfoFromPlaylistLines", "getStreamInfoFromSrcAndType", "getStreamType", "getStreamTypeConfig", "getTargetLiveWindow", "getTextTrack", "i18n", "initialize", "isKeyOf", "isMuxVideoSrc", "isPseudoEnded", "isStuckOnLastFragment", "loadMedia", "mux", "muxMediaState", "parseJwt", "removeTextTrack", "setupChapters", "setupCuePoints", "setupHls", "setupMux", "setupNativeFairplayDRM", "shorthandKeys", "teardown", "toAppCertURL", "toDRMTypeFromKeySystem", "toLicenseKeyURL", "toMuxVideoURL", "toPlaybackIdFromSrc", "toPlaybackIdParts", "updateStreamInfoFromHlsjsLevelDetails", "updateStreamInfoFromSrc", "__toCommonJS", "import_mux_embed", "import_hls", "hls_default", "Hls", "MuxErrorCategory", "MuxErrorCode", "errorCategoryToTokenNameOrPrefix", "category", "_MediaError", "message", "code", "fatal", "context", "_a", "MediaError", "isNil", "x", "isKeyOf", "k", "o", "AutoplayTypes", "StreamTypes", "PlaybackTypes", "CmcdTypes", "CmcdTypeValues", "ExtensionMimeTypeMap", "MimeTypeShorthandMap", "shorthandKeys", "allMediaTypes", "MaxResolution", "MinResolution", "RenditionOrder", "code", "en_default", "addEventListenerWithTeardown", "mediaEl", "type", "listener", "options", "target", "inSeekableRange", "seekable", "duration", "time", "i", "toPlaybackIdParts", "playbackIdWithOptionalParams", "qIndex", "idPart", "queryPart", "getType", "props", "upperType", "isKeyOf", "MimeTypeShorthandMap", "src", "inferMimeTypeFromURL", "toStreamTypeFromPlaylistType", "playlistType", "StreamTypes", "toTargetLiveWindowFromPlaylistType", "url", "pathname", "extDelimIdx", "upperExt", "ExtensionMimeTypeMap", "parseJwt", "token", "base64Url", "base64", "jsonPayload", "c", "isJWTExpired", "exp", "referenceTime", "isJWTSubMismatch", "sub", "expectedSub", "isJWTAudMissing", "aud", "_expectedAud", "isJWTAudMismatch", "expectedAud", "DEFAULT_LOCALE", "i18n", "str", "translate", "_a", "_b", "message", "en_default", "locale", "IntlMessageFormat", "values", "match", "key", "AutoplayTypeValues", "AutoplayTypes", "isAutoplayValue", "value", "setupAutoplay", "props", "mediaEl", "hls", "maybeAutoplay", "hasPlayed", "isLive", "autoplay", "updateHasPlayed", "addEventListenerWithTeardown", "handleAutoplay", "StreamTypes", "hls_default", "e", "data", "_a", "handleSeek", "newAutoplay", "oldMuted", "restoreMuted", "setupPreload", "preload", "src", "mediaEl", "hls", "updatePreload", "val", "hasLoadedSource", "hasPlayFired", "originalLength", "originalSize", "updateHlsPreload", "newPreload", "safeLoadSource", "addEventListenerWithTeardown", "setupMediaTracks", "customMediaEl", "hls", "_a", "levelIdMap", "hls_default", "event", "data", "removeAllMediaTracks", "videoTrack", "id", "level", "videoRendition", "removeAudioTracks", "a", "kind", "audioTrack", "audioTrackId", "t", "availableIds", "levelIds", "l", "rendition", "switchRendition", "smoothSwitch", "levelIndex", "currentTime", "flushedFwdBuffer", "callback", "removeVideoTracks", "cuePointStart", "cuePoint", "setupTextTracks", "mediaEl", "hls", "hls_default", "_type", "tracks", "trackObj", "_a", "_b", "baseTrackObj", "idx", "lang", "name", "type", "id", "addTextTrack", "changeHandler", "showingTrack", "textTrack", "currentHlsTrack", "hlsTrackId", "defaultTrack", "cue", "track", "cues", "disabled", "trackEl", "forceHiddenTracks", "selector", "src", "kind", "label", "removeTextTrack", "trackElement", "getTextTrack", "addCuesToTextTrack", "resolve", "cuePointA", "cuePointB", "value", "startTime", "cueAfterIndex", "cueAfter", "endTime", "previousCue", "DEFAULT_CUEPOINTS_TRACK_LABEL", "DefaultCuePointsConfig", "addCuePoints", "cuePoints", "cuePointsConfig", "toCuePoint", "getCuePoints", "getActiveCuePoint", "currentTime", "actualActiveCue", "setupCuePoints", "addEventListenerWithTeardown", "activeCuePoint", "evt", "DEFAULT_CHAPTERS_TRACK_LABEL", "DefaultChaptersConfig", "vttCueToChapter", "addChapters", "chapters", "chaptersConfig", "getChapters", "getActiveChapter", "setupChapters", "getStartDate", "mediaEl", "hls", "playingDate", "getCurrentPdt", "startDate", "import_hls", "MuxJWTAud", "categoryToAud", "category", "MuxErrorCategory", "categoryToToken", "muxMediaEl", "_a", "_b", "nameOrPrefix", "errorCategoryToTokenNameOrPrefix", "tokenName", "isKeyOf", "getErrorFromResponse", "resp", "translate", "offline", "message", "i18n", "context", "mediaErrorCode", "MediaError", "mediaError", "MuxErrorCode", "status", "requestTime", "tokenNamePrefix", "token", "expectedAud", "playbackId", "toPlaybackIdParts", "jwtObj", "parseJwt", "isJWTExpired", "dateOptions", "isJWTSubMismatch", "isJWTAudMissing", "isJWTAudMismatch", "DRMType", "toDRMTypeFromKeySystem", "keySystem", "getMediaPlaylistLinesFromMultivariantPlaylistSrc", "src", "resp", "multivariantPlaylistStr", "mediaPlaylistUrl", "_line", "idx", "lines", "mediaPlaylistStr", "getStreamInfoFromPlaylistLines", "playlistLines", "_a", "_b", "_c", "playlistType", "line", "streamType", "toStreamTypeFromPlaylistType", "targetLiveWindow", "toTargetLiveWindowFromPlaylistType", "liveEdgeStartOffset", "StreamTypes", "partInfLine", "targetDurationLine", "targetDurationValue", "getStreamInfoFromSrcAndType", "type", "ExtensionMimeTypeMap", "updateStreamInfoFromSrc", "mediaEl", "getType", "muxMediaState", "getStreamInfoFromHlsjsLevelDetails", "levelDetails", "lowLatency", "updateStreamInfoFromHlsjsLevelDetails", "hls", "_d", "_e", "_f", "_g", "_h", "seekable", "index", "userAgentStr", "userAgentPlatform", "isAndroidLike", "platformStr", "MUX_VIDEO_DOMAIN", "MSE_SUPPORTED", "hls_default", "DEFAULT_PREFER_MSE", "generatePlayerInitTime", "mux", "generateUUID", "toMuxVideoURL", "playbackIdWithParams", "domain", "maxResolution", "minResolution", "renditionOrder", "programStartTime", "programEndTime", "assetStartTime", "assetEndTime", "playbackToken", "token", "extraSourceParams", "playbackId", "queryPart", "toPlaybackIdParts", "url", "_", "key", "k", "v", "toPlaybackIdFromParameterized", "toPlaybackIdFromSrc", "toVideoId", "props", "isMuxVideoSrc", "getError", "getStreamType", "getTargetLiveWindow", "getSeekable", "getLiveEdgeStart", "DEFAULT_ENDED_MOE", "isApproximatelyEqual", "x", "y", "moe", "isApproximatelyGTE", "isPseudoEnded", "isStuckOnLastFragment", "videoLevelDetails", "level", "fragments", "lastFragment", "lastFragmentMidpoint", "lastBufferedStart", "lastBufferedEnd", "getEnded", "initialize", "core", "teardown", "metadata", "view_session_id", "video_id", "drmTypeCb", "drmType", "nextHlsInstance", "setupHls", "setPreload", "setupPreload", "setupMux", "loadMedia", "setupCuePoints", "setupChapters", "setAutoplay", "setupAutoplay", "handleNativeError", "handleInternalError", "seekInSeekableRange", "useNative", "canUseNative", "preferPlayback", "preferMse", "PlaybackTypes", "preferNative", "debug", "startPosition", "preferCmcd", "_hlsConfig", "hlsType", "shouldUseNative", "defaultConfig", "streamTypeConfig", "getStreamTypeConfig", "drmConfig", "getDRMConfig", "cmcd", "CmcdTypes", "xhr", "urlObj", "cmcdVal", "cmcdKVStr", "drmToken", "playbackIdWithOptionalParams", "toLicenseKeyURL", "toAppCertURL", "supportedConfigurations", "mediaKeySystemConfig", "videoCapabilities", "capability", "value", "getAppCertificate", "appCertificateUrl", "getLicenseKey", "message", "licenseServerUrl", "keyBuffer", "setupNativeFairplayDRM", "addEventListenerWithTeardown", "event", "initDataType", "access", "i18n", "mediaError", "MediaError", "MuxErrorCategory", "MuxErrorCode", "keys", "fairPlayAppCert", "errOrResp", "getErrorFromResponse", "error", "initData", "session", "mediaKeyStatus", "resolve", "messageEvent", "messageEventMsg", "response", "customDomain", "scheme", "base", "hostname", "hlsjs", "env_key", "disableTracking", "inferredEnv", "player_init_time", "player_software_name", "player_software_version", "beaconCollectionDomain", "disableCookies", "muxEmbedErrorTranslator", "maybeDispatchEndedCallback", "prevSeekableStart", "prevSeekableEnd", "seekableChange", "seekableTimeRanges", "nextSeekableStart", "nextSeekableEnd", "setupSeekableChangePoll", "intervalId", "setupNativeStreamInfo", "playHandler", "loadedMetadataHandler", "trackEl", "_evt", "data", "_event", "getErrorFromHlsErrorData", "setupMediaTracks", "setupTextTracks", "startTime", "inSeekableRange", "wasAuto", "code", "ourError", "status", "ErrorCodeMap", "hlsErrorDataToErrorCode", "hlsErrorDataToCategory", "errorCode", "category"]
7
7
  }