@mux/playback-core 0.25.1 → 0.25.2
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.
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +2 -2
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +2 -2
- package/dist/playback-core.js +1 -1
- package/dist/playback-core.js.map +2 -2
- package/dist/playback-core.mjs +1 -1
- package/dist/playback-core.mjs.map +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/index.cjs.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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": ["/* eslint @typescript-eslint/triple-slash-reference: \"off\" */\n/// <reference path=\"../../../node_modules/mux-embed/dist/types/mux-embed.d.ts\" />\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 type {\n ValueOf,\n PlaybackCore,\n MuxMediaProps,\n MuxMediaPropsInternal,\n MaxResolutionValue,\n MinResolutionValue,\n RenditionOrderValue,\n} from './types';\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\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\nconst userAgentStr = globalThis?.navigator?.userAgent ?? '';\nconst isAndroid = userAgentStr.toLowerCase().indexOf('android') !== -1;\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 = isAndroid;\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 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' | 'drmToken'\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'>>\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 } = 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);\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'>>,\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.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\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.start(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\" />\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/ban-types\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};\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 } 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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",
|
|
4
|
+
"sourcesContent": ["/* eslint @typescript-eslint/triple-slash-reference: \"off\" */\n/// <reference path=\"../../../node_modules/mux-embed/dist/types/mux-embed.d.ts\" />\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 type {\n ValueOf,\n PlaybackCore,\n MuxMediaProps,\n MuxMediaPropsInternal,\n MaxResolutionValue,\n MinResolutionValue,\n RenditionOrderValue,\n} from './types';\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\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\nconst userAgentStr = globalThis?.navigator?.userAgent ?? '';\nconst isAndroid = userAgentStr.toLowerCase().indexOf('android') !== -1;\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 = isAndroid;\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 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' | 'drmToken'\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'>>\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 } = 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);\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'>>,\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.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\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\" />\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/ban-types\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};\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 } 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
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", "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", "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", "isAndroid", "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", "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", "keySystem", "supportedConfigurations", "mediaKeySystemConfig", "videoCapabilities", "capability", "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"]
|
|
7
7
|
}
|