UNPKG

@oplayer/plugins

Version:
485 lines (481 loc) 24.1 kB
/** * name: @oplayer/plugins * version: v1.0.15-beta.4 * description: oplayer's plugin * author: shiyiya * homepage: https://github.com/shiyiya/oplayer */ (function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode('.playlist{position:absolute;top:0;left:100%;height:100%;z-index:9;width:18em;transition:transform .3s;background-color:#1c1c1ce6}@media (max-width: 991px){.playlist{max-width:70%}}.playlist.playlist__active{transform:translate(-100%)}.playlist.playlist__wait .playlist-list{cursor:wait}.playlist.playlist__wait .playlist-list .playlist-list-item{pointer-events:none}.playlist.playlist__active:before{content:"";position:absolute;width:100vw;height:100%;right:0;z-index:-1}.playlist-head{display:flex;justify-content:space-between;background:#000;border-bottom:1px solid #484848;padding:.2em .2em .2em .4em;align-items:center;color:#fff;box-sizing:border-box;height:2.2em}.playlist-head>span{font-size:.8em}.playlist-head .playlist-back{display:flex;align-items:center;cursor:pointer}.playlist-head .playlist-back>svg{width:1.75em;height:1.75em;fill:#fff;pointer-events:none}.playlist-head .playlist-back:hover{background-color:#ffffff4d;border-radius:2px}.playlist-list{overflow:auto;height:100%;padding-bottom:2.2em;box-sizing:border-box;color:#ccc}.playlist-list::-webkit-scrollbar{width:.3em}.playlist-list::-webkit-scrollbar-thumb{background:#ccc}.playlist-list-item{position:relative;border-bottom:1px solid #444;padding:8px;display:flex;height:5em;cursor:pointer;box-sizing:border-box;overflow:hidden}.playlist-list-item>*{pointer-events:none}.playlist-list-item:hover,.playlist-list-item.playlist-source__active{color:#fff;background-color:#ffffff1a}.playlist-list-item.playlist-source__progress:before{content:"";top:0;left:-100%;position:absolute;width:100%;height:100%;animation:progress 1s infinite;background:linear-gradient(to right,transparent,rgba(255,255,255,.4),transparent)}@keyframes progress{0%{left:-100%}to{left:100%}}.playlist-list-item-thumb{background-color:#000;border:1px solid #444;float:left;margin-right:10px;height:100%;aspect-ratio:16/9;color:#555;display:flex;justify-content:center;align-items:center;position:relative}.playlist-list-item-img{height:100%;width:100%;object-fit:cover}.playlist-list-item-img__error:after{content:"ERROR";position:absolute;left:0;top:0;width:100%;height:100%;background-color:#000;display:flex;justify-content:center;align-items:center}.playlist-list-item-desc{width:100%;font-size:14px;display:flex;flex-direction:column;justify-content:space-evenly}.playlist-list-item-desc>p{margin:0 0 6px;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;overflow:hidden;-webkit-box-orient:vertical;line-height:1.2}')),document.head.appendChild(t)}}catch(i){console.error("vite-plugin-css-injected-by-js",i)}})(); import { isIOS as A, loadSDK as q, $ as v, Player as U } from "@oplayer/core"; const O = !!globalThis.chrome, F = '<svg viewBox="0 0 1024 1024" style="scale: 0.9;"><path d="M895.66 128H128a85.44 85.44 0 0 0-85.44 85.44v127.84H128v-127.84h767.66v597.12H597.28V896H896a85.44 85.44 0 0 0 85.44-85.44V213.44A85.44 85.44 0 0 0 896 128zM42.56 767.16v127.84h127.82a127.82 127.82 0 0 0-127.82-127.84z m0-170.56V682a213.26 213.26 0 0 1 213.28 213.32v0.68h85.44a298.38 298.38 0 0 0-298-298.72h-0.66z m0-170.54v85.44c212-0.2 384 171.5 384.16 383.5v1h85.44c-0.92-258.92-210.68-468.54-469.6-469.28z"></path></svg>'; class j { constructor(t) { this.options = t, this.name = "oplayer-plugin-chromecast", this.version = "1.0.15-beta.4"; } apply(t) { if (this.canPlay()) return this.player = t, this.registerUI(), this; } get cast() { return cast.framework.CastContext.getInstance(); } get castSessionMedia() { var t; return (t = this.cast.getCurrentSession()) == null ? void 0 : t.getSessionObj().media[0]; } get isCastConnected() { return this.cast.getCastState() === cast.framework.CastState.CONNECTED; } get device() { var t; return (t = this.cast.getCurrentSession()) == null ? void 0 : t.getCastDevice(); } hasActiveCastSession(t) { var s, r; return ((r = (s = this.castSessionMedia) == null ? void 0 : s.media) == null ? void 0 : r.contentId) === (t == null ? void 0 : t.src); } canPlay() { return O && !A; } async __requestChromeCast() { var i; if (this._player || (this._player = new cast.framework.RemotePlayer(), new cast.framework.RemotePlayerController(this._player)), this.hasActiveCastSession(this.player.options.source)) return; this.cast.setOptions({ receiverApplicationId: window.chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED, resumeSavedSession: !0, androidReceiverCompatible: !0, ...this.options }); const t = await this.cast.requestSession(); if (t) throw new Error(`Chrome Cast Error Code: ${t}`); return (i = this.cast.getCurrentSession()) == null ? void 0 : i.loadMedia(this.__buildRequest()); } __buildRequest() { var y, u, n; const { source: t, isLive: i } = this.player.options, s = new chrome.cast.media.MediaInfo( t.src, ((y = this.player.loader) == null ? void 0 : y.key) == "hls" ? "application/x-mpegurl" : "video/mp4" ); s.contentUrl = t.src, s.streamType = i ? chrome.cast.media.StreamType.LIVE : chrome.cast.media.StreamType.BUFFERED; const r = new chrome.cast.media.GenericMediaMetadata(); t.title && (r.title = t.title), t.poster && (r.images = [{ url: t.poster, height: null, width: null }]), s.metadata = r; const d = (n = (u = this.player.context.ui) == null ? void 0 : u.config.subtitle) == null ? void 0 : n.source; d && (s.tracks = d.map((f, g) => { const h = new chrome.cast.media.Track(g, chrome.cast.media.TrackType.TEXT); return h.name = f.name, h.trackContentId = f.src, h.trackContentType = f.type || "text/vtt", h.language = f.language || f.name, h.subtype = chrome.cast.media.TextTrackType.CAPTIONS, h; })); const c = new chrome.cast.media.LoadRequest(s); return c.autoplay = this.player.isPlaying, c.currentTime = this.player.currentTime, c; } async _loadCast() { var t; (t = window.cast) != null && t.framework || (await q("https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1", "cast"), await customElements.whenDefined("google-cast-launcher")); } async start() { try { await this._loadCast(); const t = await this.__requestChromeCast(); if (t) throw new Error(`Chrome Cast Error Code: ${t}`); } catch (t) { this.player.emit("cast-error", t); } } registerUI() { if (!this.player.context.ui) return; const { menu: t, icons: i } = this.player.context.ui; t == null || t.register({ name: this.player.locales.get("Chromecast"), position: "top", icon: i.chromecast || F, onClick: () => this.start() }); } } const D = '<svg style="transform: scale(0.9)" viewBox="0 0 1024 1024"><path d="M662.186667 981.333333H361.813333c-17.194667 0-32.853333-9.386667-40.661333-23.552a50.176 50.176 0 0 1 0-47.104l150.186667-260.565333c7.808-14.08 23.466667-23.509333 40.661333-23.509333 17.194667 0 32.853333 9.386667 40.661333 23.552l150.186667 260.565333c7.850667 14.08 7.850667 32.938667 0 47.061333-7.808 14.122667-23.466667 23.552-40.661333 23.552z m-219.008-94.165333h137.642666L512 767.872l-68.821333 119.296z"></path><path d="M821.76 841.642667h-100.138667c-26.581333 0-46.933333-20.437333-46.933333-47.104 0-26.666667 20.352-47.104 46.933333-47.104h100.138667c37.546667 0 67.285333-29.824 67.285333-67.498667V204.373333c-1.578667-37.674667-31.317333-67.498667-67.285333-67.498666H203.818667c-37.546667 0-67.285333 29.866667-67.285334 67.498666v477.184c0 37.674667 29.738667 67.498667 67.285334 67.498667h100.096c26.624 0 46.933333 20.394667 46.933333 47.104 0 26.666667-20.309333 47.104-46.933333 47.104H203.818667A163.541333 163.541333 0 0 1 42.666667 679.893333V204.373333A161.194667 161.194667 0 0 1 203.818667 42.666667H821.76C909.354667 42.666667 981.333333 114.858667 981.333333 204.373333v477.141334c0 87.893333-71.978667 160.128-159.573333 160.128z"></path></svg>'; class W { constructor() { this.name = "oplayer-plugin-airplay", this.version = "1.0.15-beta.4"; } apply(t) { if (this.canPlay()) return this.player = t, t.$video.addEventListener("webkitplaybacktargetavailabilitychanged", (i) => { i.availability === "available" ? this.registerUI() : this.unregisterUI(); }), this; } canPlay() { return !!globalThis.WebKitPlaybackTargetAvailabilityEvent; } start() { const t = this.player.$video; t.webkitShowPlaybackTargetPicker && t.webkitShowPlaybackTargetPicker(); } registerUI() { if (!this.player.context.ui) return; const { menu: t, icons: i } = this.player.context.ui; t == null || t.register({ name: this.player.locales.get("AirPlay"), position: "top", icon: i.airplay || D, onClick: () => this.start() }); } unregisterUI() { var t, i; (i = (t = this.player.context.ui) == null ? void 0 : t.menu) == null || i.unregister("AirPlay"); } } const S = class S { constructor(t) { this.key = "playlist", this.name = "oplayer-plugin-playlist", this.version = "1.0.15-beta.4", this.options = Object.assign({ autoNext: !0, autoHide: !0, sources: [] }, t); } apply(t) { if (!t.isNativeUI) return this.player = t, this._init(), this; } async _init() { var d; const t = () => { var c; this.renderContainer(), this.changeSourceList(this.options.sources), typeof i == "number" && this.changeSource(i), this.options.autoNext && this.player.on(["ended", "error"], () => { this.next(); }), (c = this.player.context.ui.keyboard) == null || c.register({ L: () => { this.$root.classList.toggle("playlist__active"); } }); }, { initialIndex: i, m3uList: s, sources: r } = this.options; s && ((d = r[0]) != null && d.src) ? (S.m3u8Parser || (S.m3u8Parser = globalThis.m3u8Parser || await import("m3u8-parser")), fetch(r[0].src).then((c) => c.text()).then((c) => { const y = new S.m3u8Parser.Parser(); y.push(c), y.end(), this.options.sources = y.manifest.segments.map((u) => s != null && s.sourceFormat ? s.sourceFormat(u) : { src: u.uri, title: u.title }), t(); }).catch((c) => { this.player.emit("notice", { pluginName: this.name, text: "Playlist: " + c.message }); })) : t(); } get isWaiting() { return this.$root.classList.contains("playlist__wait"); } changeSource(t) { if (!this.options.sources[t] || this.isWaiting) return; const i = this.$root.querySelector(`.playlist-list-item[data-index='${t}']`); this.$root.classList.add("playlist__wait"), i == null || i.classList.add("playlist-source__progress"); const s = this.options.sources[t]; return new Promise((r) => { var d, c; if (!s.src && this.options.customFetcher) { r((c = (d = this.options).customFetcher) == null ? void 0 : c.call(d, this.player, s, t)); return; } r(s); }).then((r) => { if (!r.src) throw this.player.context.ui.notice("Empty Source"), new Error("Empty Source"); const { src: d, poster: c, format: y, title: u, subtitles: n, thumbnails: f, highlights: g, danmaku: h } = r; return this.player.changeSource({ src: d, poster: c, format: y, title: u }).then(() => { var x; n && this.player.context.ui.subtitle.changeSource(n), f && this.player.context.ui.changThumbnails(f), g && this.player.context.ui.changHighlightSource(g), h && ((x = this.player.context.danmaku) == null || x.changeSource(h)); }); }).then(() => { this.player.emit("playlistsourcechange", { source: s, id: t }), this.options.autoHide && setTimeout(() => { this.hideUI(); }, 300); }).catch((r) => { this.player.emit("playlistsourceerror", { error: (r == null ? void 0 : r.payload) || r, idx: t }); }).finally(() => { var r; this.currentIndex = t, this._updateHeader(), (r = this.$root.querySelector(".playlist-source__active")) == null || r.classList.remove("playlist-source__active"), i == null || i.classList.add("playlist-source__active"), setTimeout(() => { this.$root.classList.remove("playlist__wait"), i == null || i.classList.remove("playlist-source__progress"); }, 300); }); } changeSourceList(t) { this.options.sources = t, this.renderList(t), this.player.emit("playlistchange", t); } next() { this.changeSource((this.currentIndex || 0) + 1); } previous() { this.changeSource((this.currentIndex || 0) - 1); } showUI() { this.$root.classList.add("playlist__active"); } hideUI() { this.$root.classList.remove("playlist__active"); } renderContainer() { const t = ` <div class="playlist-head"> <span class="playlist-head-title">${this.player.locales.get("Playlist")}</span> <div class="playlist-back">${this.player.context.ui.icons.playlist || '<svg viewBox="0 0 32 32"><path d="m 12.59,20.34 4.58,-4.59 -4.58,-4.59 1.41,-1.41 6,6 -6,6 z"></path></svg>'}</div> </div> <div class="playlist-list"> </div>`; this.$root = document.createElement("div"), this.$root.innerHTML = t, this.$root.className = "playlist", this.$root.onclick = (i) => { const s = i.target; s.classList.contains("playlist-list-item") ? this.changeSource(+s.getAttribute("data-index")) : (s.classList.contains("playlist-back") || s == this.$root && s.classList.contains("playlist__active")) && this.hideUI(); }, this.player.context.ui.$root.appendChild(this.$root), this.player.context.ui.menu.register({ name: this.player.locales.get("Playlist"), icon: '<svg style="transform: scale(1.2);" viewBox="0 0 1024 1024"><path d="M213.333333 426.666667h426.666667c23.466667 0 42.666667 19.2 42.666667 42.666666s-19.2 42.666667-42.666667 42.666667H213.333333c-23.466667 0-42.666667-19.2-42.666666-42.666667s19.2-42.666667 42.666666-42.666666z m0-170.666667h426.666667c23.466667 0 42.666667 19.2 42.666667 42.666667s-19.2 42.666667-42.666667 42.666666H213.333333c-23.466667 0-42.666667-19.2-42.666666-42.666666s19.2-42.666667 42.666666-42.666667z m0 341.333333h256c23.466667 0 42.666667 19.2 42.666667 42.666667s-19.2 42.666667-42.666667 42.666667H213.333333c-23.466667 0-42.666667-19.2-42.666666-42.666667s19.2-42.666667 42.666666-42.666667z m384 37.546667v180.48c0 16.64 17.92 26.88 32.426667 18.346667l150.613333-90.453334c13.653333-8.106667 13.653333-28.16 0-36.693333l-150.613333-90.453333a21.674667 21.674667 0 0 0-32.426667 18.773333z"></path></svg>', position: "top", onClick: () => { this.showUI(); const i = this.$root.querySelector(".playlist-list"), s = this.$root.querySelector(".playlist-source__active"); s && i.scrollHeight > 0 && this.currentIndex && i.scrollTo(0, s.offsetTop - s.offsetHeight); } }); } renderList(t) { const i = t.map( (s, r) => ` <div class="playlist-list-item" data-index="${r}"> <div class="playlist-list-item-thumb"> ${s.poster ? `<img class="playlist-list-item-img" src="${s.poster}" alt="${s.title || ""}" loading="lazy" onerror="this.classList.add('playlist-list-item-img__error');"/>` : "<span>EMPTY</span>"} </div> <div class="playlist-list-item-desc"> <p>${s.title}</p> ${s.duration ? `<span>${s.duration}</span>` : ""} </div> </div>` ).join(""); this._updateHeader(), this.$root.querySelector(".playlist-list").innerHTML = i; } _updateHeader() { this.$root.querySelector(".playlist-head-title").textContent = `${this.player.locales.get( "Playlist" )} (${this.currentIndex !== void 0 ? `${this.currentIndex + 1}/` : ""}${this.options.sources.length})`; } destroy() { this.currentIndex = void 0, this.options.sources = [], this.renderList([]); } }; S.m3u8Parser = globalThis.m3u8Parser; let z = S; const R = v.css({ position: "absolute", right: "0.5em", top: "0.5em", "z-index": 1, display: "flex", gap: "5px", "align-items": "center", "justify-content": "center" }), w = v.css( "display: inline-block;background: rgba(28 ,28 ,28 , 0.9);color: #fff;padding: 4px 8px;border-radius: 4px; fill:#fff; font-size: 14px" ), M = v.css({ position: "relative", "&::before": { display: "block", content: "''", position: "absolute", width: "50%", height: "2px", "background-color": "#fff", transform: "rotate(40deg) translateY(-100%)", top: "48%", left: "6px" } }), B = ({ duration: p, skipDuration: t, video: i, image: s, plugins: r, target: d, autoplay: c, onSkip: y, position: u }) => ({ name: "oplayer-plugin-ad", version: "1.0.15-beta.4", key: "ad", apply: (n) => { c ? f() : v.render( v.create( `div.${v.css({ width: "100%", height: "100%", position: "absolute", top: "0", left: "0", "z-index": 999 })}` ), n.$root ).onclick = function() { this.remove(), f(); }; function f() { const g = v.create( `div.${v.css({ width: "100%", height: "100%", position: "absolute", top: "0", left: "0", "z-index": 999, cursor: "pointer" })}`, {}, `<div class=${u ? v.css({ ...u, position: "absolute", "z-index": 1, display: "flex", gap: "5px", "align-items": "center", "justify-content": "center" }) : R}> ${t ? `<div class=${w} skipDuration>${n.locales.get( "Can be closed after %ss", t )}</div>` : ""} <div class=${w} duration>${n.locales.get("%ss", p)}</div> ${i ? ` <div class='${w} ${M}' volume> <svg width="1em" height="1.5em" viewBox="0 0 1024 1024" version="1.1"> <path d="M552.96 152.064v719.872c0 16.118-12.698 29.184-28.365 29.184a67.482 67.482 0 0 1-48.394-20.644L329.359 729.354a74.547 74.547 0 0 0-53.493-22.794H250.47c-104.386 0-189.03-87.101-189.03-194.56s84.644-194.56 189.03-194.56h25.396c20.07 0 39.3-8.192 53.473-22.794L476.18 143.503a67.482 67.482 0 0 1 48.436-20.623c15.646 0 28.344 13.066 28.344 29.184z m216.965 101.58a39.936 39.936 0 0 1 0-57.425 42.25 42.25 0 0 1 58.778 0c178.483 174.408 178.483 457.154 0 631.562a42.25 42.25 0 0 1-58.778 0 39.936 39.936 0 0 1 0-57.405 359.506 359.506 0 0 0 0-516.752zM666.542 373.884a39.731 39.731 0 0 1 0-55.235 37.52 37.52 0 0 1 53.944 0c104.305 106.783 104.305 279.921 0 386.704a37.52 37.52 0 0 1-53.944 0 39.731 39.731 0 0 1 0-55.235c74.486-76.288 74.486-199.946 0-276.234z" /> </svg> </div>` : ""} </div> </div> ` ); let h; const x = g.querySelector(`.${w}[skipDuration]`), E = g.querySelector(`.${w}[duration]`), C = g.querySelector(`.${w}[volume]`); i ? (h = U.make(g, { muted: !0, autoplay: !0, loop: !0, source: { src: i } }).use(r || []).create(), C.addEventListener("click", (a) => { a.preventDefault(), a.stopPropagation(), h.isMuted ? h.unmute() : h.mute(), C.classList.toggle(M); })) : g.style.background = `url(${s}) center center`, v.render(g, n.$root); let b = 0; const _ = () => { clearInterval(H), h == null || h.destroy(), g.remove(), n.play(); }, H = setInterval(() => { t !== void 0 && (b++, t - b > 0 ? x.innerText = n.locales.get("Can be closed after %ss", t - b) : (x.innerText = n.locales.get("Close"), x.onclick ?? (x.onclick = () => { y == null || y(b), _(); }))), p - b > 0 ? E.innerText = n.locales.get("%ss", p - b) : _(); }, 1e3); d && g.addEventListener("click", (a) => { a.target.classList.contains(w) || window.open(d, "_blank"); }); } } }); function N(p, t) { const { $progress: i } = p.context.ui, s = i.firstElementChild; let r = [], d = {}, c, y = !1, u = t == null ? void 0 : t.src; const n = v.render(v.create(`div.${p.context.ui.vttThumbnailsCls}`), s); n.style.width = ((t == null ? void 0 : t.width) || 160) + "px", n.style.height = ((t == null ? void 0 : t.height) || 90) + "px"; const f = (a) => { fetch(a).then((e) => e.text()).then((e) => { r = g(e), y = !0, n.style.opacity = "1"; }).catch((e) => { p.emit("notice", { text: "Failed to load vtt thumbnails", reason: e }); }); }; t != null && t.src && f(t.src), p.on("videosourcechange", () => { p.context.ui.progressHoverCallback.splice( p.context.ui.progressHoverCallback.findIndex((a) => a == _), 1 ), y = !1, n.style.opacity = "0", r = [], d = {}; }); const g = (a) => { const e = []; return a.split(/[\r\n][\r\n]/i).forEach((l) => { if (l.match( /([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?( ?--> ?)([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?[\r\n]{1}.*/gi )) { const m = l.split(/[\r\n]/i), I = isFinite(+m[0]) ? m[1] : m[0], k = isFinite(+m[0]) ? m[2] : m[1], $ = I.split(/ ?--> ?/i), P = $[0], L = $[1], T = E(k); e.push({ start: h(P), end: h(L), css: T }); } return e; }), e; }, h = (a) => { const e = x(a); return e.hours * (60 * 60) + e.minutes * 60 + e.seconds + e.milliseconds / 1e3; }, x = (a) => { const e = a.split("."), l = e[0].split(":"); return { milliseconds: parseInt(e[1], 10) || 0, seconds: parseInt(l.pop(), 10) || 0, minutes: parseInt(l.pop(), 10) || 0, hours: parseInt(l.pop(), 10) || 0 }; }, E = (a) => { const e = {}; if (!a.match(/#xywh=/i)) return e.background = 'url("' + C(a) + '")', e; const o = b(a); return e.background = 'url("' + C(o.image) + '") no-repeat -' + o.x + "px -" + o.y + "px", e.width = o.w + "px", e.height = o.h + "px", e.url = C(o.image), e; }, C = /* @__PURE__ */ (() => { const a = {}; return (e) => { if (!u) return e; if (a[e]) return a[e]; if (/(https?:)?\/\//.test(e)) return e; let o = u; /(https?:)?\/\//.test(e) && (o = u.substring(0, u.indexOf("?") || void 0)); const l = o.lastIndexOf("/"); if (o.startsWith("https://") && l < 8 || o.startsWith("http://") && l < 7) return u + e; const m = o.substring(l + 1); return a[e] = ((t == null ? void 0 : t.prefix) || "") + u.replace(m, e), a[e]; }; })(), b = (a) => { const e = a.split(/#xywh=/i), o = e[0], m = e[1].match(/[0-9]+/gi); return { x: m[0], y: m[1], w: m[2], h: m[3], image: o }; }, _ = (a) => { if (!y || !a) return; const e = p.duration, o = a * e, l = H(o); if (!l) { n.style.opacity = "0"; return; } const m = s.clientWidth, I = a * m, k = parseInt(l.width, 10), $ = k >> 1, P = m - (I + $), L = I - $; if (n.style.opacity = "1", L > 0 && P > 0 ? n.style.transform = "translateX(" + (I - $) + "px)" : L <= 0 ? n.style.transform = "translateX(0px)" : P <= 0 && (n.style.transform = "translateX(" + (m - k) + "px)"), !(c && c === l)) { c = l; for (const T in l) l.hasOwnProperty(T) && (n.style[T] = l[T]); } }, H = (a) => { for (let e = 0; e < r.length; ++e) { const o = r[e]; if (a >= o.start && a < o.end) { if (o.css.url && !d[o.css.url]) { const l = new Image(); l.src = o.css.url, d[o.css.url] = l; } return o.css; } } }; p.context.ui.progressHoverCallback.push(_), p.context.ui.changThumbnails = ({ src: a }) => f(a); } const X = (p) => ({ name: "oplayer-vtt-thumbnails", version: "1.0.15-beta.4", apply: (t) => N(t, p) }); export { W as AirPlay, j as Chromecast, z as Playlist, B as ad, X as vttThumbnails };