UNPKG

@tidal-music/player

Version:
1,417 lines (1,416 loc) 26.9 kB
import { s as h, f as _, e as p, p as y, o as m, g as v, h as P, i as d, j as I, k as L, m as f, P as H, d as T, a as b, c as M, w as N } from "./index-CmV5XX7g.js"; import { B as D, c as w, m as A } from "./basePlayer-C99zz0ed.js"; function R(a) { return new CustomEvent( "playback-quality-changed", { detail: { playbackContext: a } } ); } function O(a) { const e = a.audioCodec; if (e === "flac") { const t = a.originalAudioId != null ? k(a.originalAudioId) : void 0; return a.audioSamplingRate && a.audioSamplingRate > 44100 || t != null && t > 16 ? "HI_RES_LOSSLESS" : "LOSSLESS"; } return e === "mp4a.40.2" ? "HIGH" : "LOW"; } function k(a) { if (!a?.includes(",")) return; const t = a.match(/\d+/g)?.at(-1); return t != null ? Number(t) : void 0; } function C(a, e) { if (a && e?.audioCodec) { const t = h.getMediaProductTransition( a ); if (!t) { console.warn("No media product transition saved."); return; } const { mediaProduct: i, playbackContext: s } = t, n = { ...s, actualAudioQuality: O(e), bandwidth: e.bandwidth ?? null, bitDepth: e.originalAudioId ? k(e.originalAudioId) ?? null : null, codec: e.audioCodec ? _( e.audioCodec ) ?? null : null, sampleRate: e.audioSamplingRate ?? null }; h.saveMediaProductTransition( a, { mediaProduct: i, playbackContext: n } ), p.dispatchEvent(R(n)); } } function F(a, e) { const t = m.now(), i = a.mimeType, s = a.codecs, n = a.bandwidth, o = a.width, c = a.height; return { assetPosition: e, bandwidth: n, codecs: s, mimeType: i, timestamp: t, videoHeight: c, videoWidth: o }; } async function U(a, e, t) { const i = F(e, t); return i.mimeType && i.codecs && await y({ adaptations: [i], streamingSessionId: a }), i; } function x(a) { let e; const t = () => { const n = a.getVariantTracks().find((c) => c.active), o = a.getMediaElement(); e && o && U( e, n, o.currentTime ).catch(console.error); }, i = (n) => { t(); const o = n.newTrack; e && C(e, o); }; a.addEventListener("adaptation", i), a.addEventListener( "variantchanged", t ); const s = (n) => { n instanceof CustomEvent && (e = n.detail.playbackContext.playbackSessionId); }; return p.addEventListener("media-product-transition", s), function() { a.removeEventListener("adaptation", i), a.removeEventListener( "variantchanged", t ), p.removeEventListener( "media-product-transition", s ); }; } async function G() { try { const e = await (await fetch("https://fp.fa.tidal.com/certificate")).arrayBuffer(); return new Uint8Array(e); } catch (a) { throw console.error("Failed to retrieve the server certificate.", a); } } const S = { isPlaying: !1, isSeeking: !1 }, W = (a) => new Promise( (e) => a.addEventListener("waiting", () => e(), { once: !0 }) ), Y = (a) => new Promise( (e) => a.addEventListener("playing", () => e(), { once: !0 }) ); function Q() { S.isSeeking = !0; } function B() { S.isSeeking = !1; } function V() { S.isPlaying = !1; } async function q(a, e) { S.isPlaying = !0, await W(a); const t = a.currentTime; if (!S.isPlaying || t === 0) return; const i = m.now(), s = S.isSeeking ? "SEEK" : "UNEXPECTED"; await Y(a); const n = m.now(); y({ stalls: [{ assetPosition: t, endTimestamp: n, reason: s, startTimestamp: i }], streamingSessionId: e }); } function z(a) { let e; p.addEventListener("media-product-transition", (o) => { o instanceof CustomEvent && (e = o.detail.playbackContext.playbackSessionId); }); const t = () => V(), i = () => { e && q(a, e).catch( console.error ); }, s = () => Q(), n = () => B(); return a.addEventListener("seeking", s), a.addEventListener("seeked", n), a.addEventListener("playing", i), a.addEventListener("paused", t), function() { a.removeEventListener("seeking", s), a.removeEventListener("seeked", n), a.removeEventListener("playing", i), a.removeEventListener("paused", t); }; } let g; function K(a) { switch (a.split("/").pop()?.split("?")[0]) { case "fairplay": return "FAIR_PLAY"; case "widevine": return "WIDEVINE"; default: return "NONE"; } } const $ = new Uint8Array([ 10, 193, 2, 8, 3, 18, 16, 23, 5, 185, 23, 204, 18, 4, 134, 139, 6, 51, 58, 47, 119, 42, 140, 24, 130, 180, 130, 146, 5, 34, 142, 2, 48, 130, 1, 10, 2, 130, 1, 1, 0, 153, 237, 91, 59, 50, 125, 171, 94, 36, 239, 195, 182, 42, 149, 181, 152, 82, 10, 213, 188, 203, 55, 80, 62, 6, 69, 184, 20, 216, 118, 184, 223, 64, 81, 4, 65, 173, 140, 227, 173, 177, 27, 184, 140, 78, 114, 90, 94, 74, 158, 7, 149, 41, 29, 88, 88, 64, 35, 167, 225, 175, 14, 56, 169, 18, 121, 57, 48, 8, 97, 11, 111, 21, 140, 135, 140, 126, 33, 191, 251, 254, 234, 119, 225, 1, 158, 30, 87, 129, 232, 164, 95, 70, 38, 61, 20, 230, 14, 128, 88, 168, 96, 122, 220, 224, 79, 172, 132, 87, 177, 55, 168, 214, 124, 205, 235, 51, 112, 93, 152, 58, 33, 251, 78, 236, 189, 74, 16, 202, 71, 73, 12, 164, 126, 170, 93, 67, 130, 24, 221, 186, 241, 202, 222, 51, 146, 241, 61, 111, 251, 100, 66, 253, 49, 225, 191, 64, 176, 198, 4, 209, 196, 186, 76, 149, 32, 164, 191, 151, 238, 189, 96, 146, 154, 252, 238, 245, 91, 186, 245, 100, 226, 208, 231, 108, 215, 197, 92, 115, 160, 130, 185, 150, 18, 11, 131, 89, 237, 206, 36, 112, 112, 130, 104, 13, 111, 103, 198, 216, 44, 74, 197, 243, 19, 68, 144, 167, 78, 236, 55, 175, 75, 47, 1, 12, 89, 232, 40, 67, 226, 88, 47, 11, 107, 159, 93, 176, 252, 94, 110, 223, 100, 251, 211, 8, 180, 113, 27, 207, 18, 80, 1, 156, 159, 90, 9, 2, 3, 1, 0, 1, 58, 20, 108, 105, 99, 101, 110, 115, 101, 46, 119, 105, 100, 101, 118, 105, 110, 101, 46, 99, 111, 109, 18, 128, 3, 174, 52, 115, 20, 181, 168, 53, 41, 127, 39, 19, 136, 251, 123, 184, 203, 82, 119, 210, 73, 130, 60, 221, 209, 218, 48, 185, 51, 57, 81, 30, 179, 204, 189, 234, 4, 185, 68, 185, 39, 193, 33, 52, 110, 253, 189, 234, 201, 212, 19, 145, 126, 110, 193, 118, 161, 4, 56, 70, 10, 80, 59, 193, 149, 43, 155, 164, 228, 206, 15, 196, 191, 194, 10, 152, 8, 170, 175, 75, 252, 209, 156, 29, 207, 205, 245, 116, 204, 172, 40, 209, 180, 16, 65, 108, 249, 222, 136, 4, 48, 28, 189, 179, 52, 202, 252, 208, 212, 9, 120, 66, 58, 100, 46, 84, 97, 61, 240, 175, 207, 150, 202, 74, 146, 73, 216, 85, 228, 43, 58, 112, 62, 241, 118, 127, 106, 155, 211, 109, 107, 248, 43, 231, 107, 191, 12, 186, 79, 222, 89, 210, 171, 204, 118, 254, 182, 66, 71, 184, 92, 67, 31, 188, 165, 34, 102, 182, 25, 252, 54, 151, 149, 67, 252, 169, 203, 189, 187, 250, 250, 14, 26, 85, 231, 85, 163, 199, 188, 230, 85, 249, 100, 111, 88, 42, 185, 207, 112, 170, 8, 185, 121, 248, 103, 246, 58, 11, 43, 127, 219, 54, 44, 91, 196, 236, 213, 85, 216, 91, 202, 169, 197, 147, 195, 131, 200, 87, 212, 157, 170, 183, 126, 64, 183, 133, 29, 223, 210, 73, 152, 128, 142, 53, 178, 88, 231, 93, 120, 234, 192, 202, 22, 247, 4, 115, 4, 194, 13, 147, 237, 228, 232, 255, 28, 111, 23, 230, 36, 62, 63, 61, 168, 252, 23, 9, 135, 14, 196, 95, 186, 130, 58, 38, 63, 12, 239, 161, 247, 9, 59, 25, 9, 146, 131, 38, 51, 55, 5, 4, 58, 41, 189, 166, 249, 180, 52, 44, 200, 223, 84, 60, 177, 161, 24, 47, 124, 95, 255, 51, 241, 4, 144, 250, 202, 91, 37, 54, 11, 118, 1, 94, 156, 90, 6, 171, 142, 224, 47, 0, 210, 232, 213, 152, 97, 4, 170, 204, 77, 212, 117, 253, 150, 238, 156, 228, 227, 38, 242, 27, 131, 199, 5, 133, 119, 179, 135, 50, 205, 218, 188, 106, 107, 237, 19, 251, 13, 73, 211, 138, 69, 235, 135, 165, 244 ]); class X extends D { #t = !0; #n; #e; #a = null; #s = null; #i; #r = !1; name = "shakaPlayer"; shakaInstance; constructor() { super(), this.playbackState = "IDLE", this.#n = this.#m(), v("outputDevicesEnabled") && (async () => g = (await import("./output-devices-CMDZU3db.js")).outputDevices)(), P.addEventListener("authorized", () => { this.shakaInstance && this.#o(this.shakaInstance).catch(console.error); }); const e = () => { this.mediaElement && !this.mediaElement.paused && (this.playbackState = "PLAYING"); }, t = (r) => { const u = r.type === "buffering" && this.mediaElement?.networkState === HTMLMediaElement.NETWORK_LOADING; (this.mediaElement?.paused || u) && (this.playbackState = "STALLED"); }, i = () => { (async () => { this.mediaElement && this.preloadedStreamingSessionId && this.mediaElement.currentTime === this.mediaElement.duration && (await N(1e3), this.mediaElement && this.mediaElement.currentTime !== this.mediaElement.duration) || (this.playbackState = "NOT_PLAYING"); })().catch(console.error); }, s = (r) => { const u = r.target; u.readyState > HTMLMediaElement.HAVE_NOTHING && (this.currentTime = u.currentTime); }, n = (r) => { this.currentStreamingSessionId && r.target instanceof HTMLMediaElement && h.overwriteDuration( this.currentStreamingSessionId, r.target.duration ); }, o = (r) => { s(r), this.finishCurrentMediaProduct("completed"); }, c = (r) => console.error( "HTMLMediaElement errored", r.target.error ), l = () => { this.currentTime = this.mediaElement ? this.mediaElement.currentTime : 0, this.seekEnd(this.currentTime); }; this.#e = { durationChangeHandler: n, endedHandler: o, errorHandler: c, pauseHandler: i, playHandler: e, playingHandler: e, seekedHandler: l, stalledHandler: t, timeUpdateHandler: s, waitingHandler: t }, this.#i = { bufferingHandler: (r) => { r.buffering ? t(r) : this.hasStarted() && e(); }, errorHandler: ((r) => this.#d(r)), loadedHandler: i, stallDetectedHandler: t }; } async #o(e) { const { clientId: t } = await P.credentialsProvider.getCredentials(); if (!t || "Cypress" in window) return; const i = await d.Player.probeSupport(); if (i.drm["com.widevine.alpha"]) this.debugLog("Configuring widevine DRM."), e.configure({ drm: { advanced: { "com.widevine.alpha": { audioRobustness: ["SW_SECURE_CRYPTO"], serverCertificate: $, videoRobustness: ["SW_SECURE_CRYPTO"] } }, servers: { "com.widevine.alpha": "https://api.tidal.com/v2/widevine" // TODO: update DRM URLs from manifest response if changed } } }); else if (i.drm["com.apple.fps.1_0"]) { this.debugLog("Configuring fairplay DRM."), d.polyfill.PatchedMediaKeysApple.install(); const s = await G(); e.configure({ drm: { advanced: { "com.apple.fps.1_0": { serverCertificate: s, serverCertificateUri: "https://fp.fa.tidal.com/certificate" } }, initDataTransform: d.util.FairPlayUtils.verimatrixInitDataTransform, servers: { "com.apple.fps.1_0": "https://fp.fa.tidal.com/license" } } }); } } /** * Playback of media product type demo needed to be done with * useNativeHlsForFairPlay and preferNativeHls set to false, but * we don't support `demo` anymore. */ async #l(e) { await d.util.FairPlayUtils.isFairPlaySupported() && e && (e.getConfiguration().streaming.preferNativeHls !== !0 && e.configure("streaming.preferNativeHls", !0), e.getConfiguration().streaming.useNativeHlsForFairPlay !== !0 && e.configure("streaming.useNativeHlsForFairPlay", !0), await e.unload(!0)); } async #u(e) { this.debugLog("createShakaPlayer", e); const t = new d.Player(); await t.attach(e), z(e), x(t); const i = await d.util.FairPlayUtils.isFairPlaySupported(), s = { backoffFactor: 2, // the multiplicative backoff factor between retries baseDelay: 1e3, // the base delay in ms between retries fuzzFactor: 0.5, // the fuzz factor to apply to each retry delay maxAttempts: 5, // the maximum number of requests before we fail timeout: 5e3 // timeout in ms, after which we abort; 0 means never }; t.configure({ abr: { enabled: !0 }, drm: { retryParameters: s }, manifest: { defaultPresentationDelay: 0, disableText: !0, disableThumbnails: !0, retryParameters: s }, streaming: { bufferBehind: 40, // The number of seconds of content that the StreamingEngine will attempt to buffer ahead of the playhead. This value must be greater than or equal to the rebuffering goal. bufferingGoal: 40, preferNativeHls: i, // The number of seconds of content that the StreamingEngine will attempt to buffer behind of the playhead. retryParameters: s, /* * Resume can be handled automatic by Shaka, but has no callback * for triggering tracking events etc. */ // failureCallback() {}, useNativeHlsForFairPlay: i } }); try { await this.#o(t); } catch { this.finishCurrentMediaProduct("error"); return; } return t.getNetworkingEngine()?.registerRequestFilter(async (n, o, c) => { if (n === d.net.NetworkingEngine.RequestType.LICENSE) { const r = c?.isPreload ?? !1 ? this.preloadedStreamingSessionId ?? this.currentStreamingSessionId : this.currentStreamingSessionId; performance.mark( "streaming_metrics:drm_license_fetch:startTimestamp", { detail: r, startTime: m.now() } ), o.headers["Content-Type"] = "application/octet-stream"; const { token: u } = await P.credentialsProvider.getCredentials(); u && (o.headers.authorization = `Bearer ${u}`); } }), t.getNetworkingEngine()?.registerResponseFilter((n, o, c) => { const r = c?.isPreload ? this.preloadedStreamingSessionId ?? this.currentStreamingSessionId : this.currentStreamingSessionId; n === d.net.NetworkingEngine.RequestType.LICENSE && r && (performance.mark( "streaming_metrics:drm_license_fetch:endTimestamp", { detail: r, startTime: m.now() } ), performance.measure("streaming_metrics:drm_license_fetch", { detail: r, end: "streaming_metrics:drm_license_fetch:endTimestamp", start: "streaming_metrics:drm_license_fetch:startTimestamp" }), y({ cdm: K(o.uri), cdmVersion: null, streamingSessionId: r }), I([ L({ endReason: "COMPLETE", endTimestamp: m.timestamp( "streaming_metrics:drm_license_fetch:endTimestamp" ), errorCode: null, errorMessage: null, startTimestamp: m.timestamp( "streaming_metrics:drm_license_fetch:startTimestamp" ), streamingSessionId: r }) ]).catch(console.error), performance.clearMarks( "streaming_metrics:drm_license_fetch:endTimestamp" ), performance.clearMarks( "streaming_metrics:drm_license_fetch:startTimestamp" )); }), this.#g(t, !0), this.#h(f, !0), t; } #d(e) { if (this.#t) return; const t = e.detail, i = `S${t.code}`; switch (t.code) { case d.util.Error.Code.LICENSE_REQUEST_FAILED: this.currentStreamingSessionId && I([ L({ endReason: "ERROR", endTimestamp: m.timestamp( "streaming_metrics:drm_license_fetch:endTimestamp" ), errorCode: i, errorMessage: JSON.stringify(t), startTimestamp: m.timestamp( "streaming_metrics:drm_license_fetch:startTimestamp" ), streamingSessionId: this.currentStreamingSessionId }) ]).catch(console.error); break; case d.util.Error.Code.LOAD_INTERRUPTED: return; case d.util.Error.Code.SRC_EQUALS_PRELOAD_NOT_SUPPORTED: return; // Ignore this error, handled via promise rejection. case d.util.Error.Code.TIMEOUT: console.warn("Shaka: TIMEOUT"), console.warn("Shaka: URI", t.data[0]), console.warn("Shaka: RequestType", t.data[1]); break; } const s = t.category === d.util.Error.Category.NETWORK; t.severity === d.util.Error.Severity.CRITICAL && (this.playbackState = "STALLED", this.mediaElement && this.mediaElement.pause(), this.currentStreamingSessionId && y({ errorCode: i, errorMessage: JSON.stringify(t), streamingSessionId: this.currentStreamingSessionId }), p.dispatchError( new H( s ? "PENetwork" : "EUnexpected", i ) ), s || this.finishCurrentMediaProduct("error")), s && (this.#r = !0); } async #c({ assetPosition: e, assetUriOrPreloader: t, mediaProduct: i, playbackInfo: s, streamInfo: n }) { this.debugLog("loadAndDispatchMediaProductTransition"), this.currentTime = e; const { shakaInstance: o } = this; if (!o) return; const c = new Promise((r) => { o.addEventListener( "loaded", () => { r(); }, { once: !0 } ); }); o.load(t, e).catch( (r) => this.#d( new CustomEvent("shaka-error", { detail: r }) ) ), this.currentStreamingSessionId = s.streamingSessionId, this.preloadedStreamingSessionId = void 0; let l; if (h.hasMediaProductTransition( s.streamingSessionId )) l = h.getMediaProductTransition( s.streamingSessionId ).playbackContext; else { const r = await new Promise( (u) => f.addEventListener( "durationchange", (E) => { E.target instanceof HTMLMediaElement && u(E.target.duration); }, { once: !0 } ) ); l = w({ assetPosition: e, duration: r, playbackInfo: s, streamInfo: n }), h.saveMediaProductTransition( n.streamingSessionId, { mediaProduct: i, playbackContext: l } ); } await c, this.currentStreamingSessionId === n.streamingSessionId && p.dispatchEvent( A(i, l) ); } async #m() { this.debugLog("loadLibraries"), d.polyfill.installAll(), await T(), this.shakaInstance = await this.#u(f); } #h(e, t) { this.debugLog( "mediaElementEvents", t ? "adding to" : "removing from", e ); const i = t ? "addEventListener" : "removeEventListener"; e[i]( "durationchange", this.#e.durationChangeHandler, { passive: !0 } ), e[i]("play", this.#e.playHandler, { passive: !0 }), e[i]( "playing", this.#e.playingHandler, { passive: !0 } ), e[i]( "timeupdate", this.#e.timeUpdateHandler, { passive: !0 } ), e[i]( "pause", this.#e.pauseHandler, { passive: !0 } ), e[i]( "ended", this.#e.endedHandler, { passive: !0 } ), e[i]( "error", this.#e.errorHandler, { passive: !0 } ), e[i]( "waiting", this.#e.waitingHandler, { passive: !0 } ), e[i]( "stalled", this.#e.stalledHandler, { passive: !0 } ), e[i]( "seeked", this.#e.seekedHandler, { passive: !0 } ); } #g(e, t) { this.debugLog("shakaEvents"); const i = t ? "addEventListener" : "removeEventListener"; e[i]("error", this.#i.errorHandler, !1), e[i]( "buffering", this.#i.bufferingHandler, !1 ), e[i]( "stalldetected", this.#i.stallDetectedHandler, !1 ), e[i]( "loaded", this.#i.loadedHandler, !1 ); } getPosition() { return this.currentTime; } async load(e, t) { this.debugLog("load", e), await this.ready, this.currentTime = e.assetPosition, this.startAssetPosition = e.assetPosition, await this.reset(), this.#t = !1, await this.#l(this.shakaInstance), await T(); const { assetPosition: i, mediaProduct: s, playbackInfo: n, streamInfo: o } = e; this.currentStreamingSessionId = o.streamingSessionId, t === "explicit" && (this.playbackState = "NOT_PLAYING"); const { mediaElement: c, shakaInstance: l } = this; if (!(!l || !c)) return this.#c({ assetPosition: i, assetUriOrPreloader: o.streamUrl, mediaProduct: s, playbackInfo: n, streamInfo: o }); } get mediaElement() { return f; } async next(e) { if (this.debugLog("next", e), !this.shakaInstance) { console.warn("Shaka not initialized."); return; } if (this.#a = await this.shakaInstance.preload( e.streamInfo.streamUrl ), this.playbackState === "IDLE" && (this.playbackState = "NOT_PLAYING"), this.preloadedStreamingSessionId = e.streamInfo.streamingSessionId, e.streamInfo.duration) { const t = w({ assetPosition: 0, duration: e.streamInfo.duration, playbackInfo: e.playbackInfo, streamInfo: e.streamInfo }); h.saveMediaProductTransition( e.streamInfo.streamingSessionId, { mediaProduct: e.mediaProduct, playbackContext: t } ); } this.#s = e, this.#t = !1; } pause() { this.debugLog("pause"), this.mediaElement && this.mediaElement.pause(); } async play() { if (this.debugLog("play"), await this.maybeHardReload(), this.#r) { const t = this.shakaInstance?.retryStreaming(); if (this.#r = !t, !t) { this.playbackState = "NOT_PLAYING", this.finishCurrentMediaProduct("error"); return; } } if (this.playbackState === "IDLE") return this.debugLog("is IDLE, returning early"), Promise.resolve(); "setSinkId" in f && await this.updateOutputDevice(), this.mediaProductStarted(this.currentStreamingSessionId), this.setStateToXIfNotYInZMs(1e3, "PLAYING", "STALLED"), await this.mediaElement?.play(); const e = this.shakaInstance?.getVariantTracks()?.find((t) => t.active); C(this.currentStreamingSessionId, e); } async playbackEngineEndedHandler(e) { if (this.isActivePlayer) { const { reason: t } = e.detail; t === "completed" && (this.hasNextItem() ? (await this.skipToPreloadedMediaProduct(), await this.play()) : (b.preloadedStreamingSessionId ? this.debugLog( `Switching player from ${this.name} to ${b.preloadPlayer?.name}` ) : this.debugLog("No next item queued."), this.playbackState = "NOT_PLAYING")); } } get ready() { return this.#n; } async reset({ keepPreload: e } = { keepPreload: !1 }) { if (this.debugLog("reset"), this.#t) return; e || await this.unloadPreloadedMediaProduct(), this.playbackState !== "IDLE" && this.finishCurrentMediaProduct("skip"), this.playbackState = "IDLE", this.detachPlaybackEngineEndedHandler(), this.currentStreamingSessionId = void 0, e || (this.preloadedStreamingSessionId = void 0), this.#t = !0; const { mediaElement: t, shakaInstance: i } = this; if (i && t && t.readyState !== 0) return i.unload( /* initializeMediaSource */ !0 ); } // eslint-disable-next-line @typescript-eslint/no-misused-promises seek(e) { this.debugLog("seek", e); const { mediaElement: t } = this; if (!t) return; this.seekStart(this.currentTime), this.currentTime = e; const i = e; return "fastSeek" in t ? t.fastSeek(i) : t.currentTime = i, new Promise((s) => { t.addEventListener( "seeked", () => s(t.currentTime), { once: !0 } ); }); } async skipToPreloadedMediaProduct() { if (this.debugLog( "skipToPreloadedMediaProduct", this.preloadedStreamingSessionId ), this.#s) { const { mediaProduct: e, playbackInfo: t, streamInfo: i } = this.#s, n = h.getMediaProductTransition( i.streamingSessionId )?.mediaProduct ?? e; return this.#c({ assetPosition: 0, assetUriOrPreloader: this.#a ?? i.streamUrl, mediaProduct: n, playbackInfo: t, streamInfo: i }); } return Promise.reject("Nothing preloaded."); } togglePlayback() { this.debugLog("togglePlayback"); const { mediaElement: e } = this; e && (e.paused ? e.play().catch(console.error) : e.pause()); } async unloadPreloadedMediaProduct() { this.debugLog( "unloadPreloadedMediaProduct", this.preloadedStreamingSessionId ), this.preloadedStreamingSessionId && (this.cleanUpStoredPreloadInfo(), await this.#a?.destroy()); } async updateOutputDevice() { if (!g) return; if (g && !g.activeDevice || !v("outputDevicesEnabled")) return Promise.resolve(); const e = g.activeDevice.webDeviceId; this.outputDeviceType = g.activeDevice.type; try { await f.setSinkId(e), p.dispatchEvent( M(g.activeDevice.id) ); } catch (t) { console.error(t); } } get volume() { return v("desiredVolumeLevel"); } set volume(e) { this.debugLog("Setting volume to", e), this.mediaElement && (this.mediaElement.volume = e); } } export { X as default }; //# sourceMappingURL=shakaPlayer-16_jV3wU.js.map