UNPKG

@plutotcool/vue-freecaster

Version:

Freecaster video player integration for vue

546 lines (545 loc) 15 kB
import { shallowRef as b, toRef as C, isRef as D, watch as c, onMounted as F, onUnmounted as M, unref as y, defineComponent as I, mergeModels as B, useModel as f, computed as A, useAttrs as _, openBlock as O, createElementBlock as V, mergeProps as R, ref as z, createBlock as G, resolveDynamicComponent as U, withCtx as x, createTextVNode as $, toDisplayString as j, createCommentVNode as H } from "vue"; function q(a = {}) { let { element: t, options: n, player: e, listeners: s = {} } = a; const o = { ...a, destroy: () => w(o), load: b(), listeners: s, key: b(0), attributes: b({}), element: C(t), options: C(n), player: D(e) ? e : b(e) }; return le(o), ee(o), Y(o), te(o), ae(o), ne(o), se(o), X(o), oe(o), re(o), W(o), o; } const Z = { class: "freecaster-player", "data-playsinline": "true" }, J = { videoId: "video-id", watermarkEnabled: "watermark.enabled", thumbnailsSrc: "thumbnails.src", subtitlesDefaultLang: "subtitles.default_lang", subtitlesLang: "subtitles.lang", subtitlesNative: "subtitles.native", floatOnScroll: "float_on_scroll", chaptersEnabled: "chapters.enabled", chaptersStyle: "chapters.style", chaptersList: "chapters.list", audioOnly: "audio_only", trackersGaEnabled: "trackers.ga.enabled", trackersGaTagIds: "trackers.ga.tag_ids string", speedOptions: "speed.options", speedLabels: "speed.labels" }, k = [ // Standard video events "abort", "canplay", "canplaythrough", "durationchange", "emptied", "encrypted", "ended", "error", "load", "loadeddata", "loadedmetadata", "loadstart", "pause", "play", "playing", "progress", "ratechange", "seeked", "seeking", "stalled", "suspend", "timeupdate", "volumechange", "waiting", "waitingforkey", "enterpictureinpicture", "leavepictureinpicture", "resize", // Freecaster player events "fullscreenenter", "fullscreenexit", "viewenter", "viewleave", "fcplayerDestroy", "fcplayerSrcChanged", "fcplayerConfigChanged", "fcplayerCountdownTick", "fcplayerCountdownEnabled", "fcplayerCountdownDisabled", "fcplayerCountdownZero" ]; function K(a, t) { a.player.value && w(a), a.player.value = t, P(a); } function w(a) { var r; const t = a.element.value, n = t == null ? void 0 : t.parentNode, e = n && Array.from(n.childNodes), s = t && (e == null ? void 0 : e.indexOf(t)), o = s !== void 0 && (e == null ? void 0 : e[s + 1]); Q(a), (r = a.player.value) == null || r.destroy(), a.player.value = void 0, !(!t || !n || t.parentNode) && (t.innerHTML = "", o ? n.insertBefore(t, o) : n.appendChild(t)); } function P({ listeners: a, player: t }) { if (t.value) for (const n of k) { const e = a == null ? void 0 : a[L(n)]; e && t.value.addEventListener(n, e); } } function Q({ listeners: a, player: t }) { if (t.value) for (const n of k) { const e = a == null ? void 0 : a[L(n)]; e && t.value.removeEventListener(n, e); } } function W({ options: a, ...t }) { t.player.value && (t.player.value = void 0); let n; const e = (s) => { var o; ((o = t.element.value) == null ? void 0 : o.id) === s.id && K(t, s); }; c([t.player, () => { var s; return (s = a.value) == null ? void 0 : s.videoId; }], ([s, o]) => { s && o && s.loadVideo(o); }), c([ t.element, t.player, t.load ], ([s, o, r]) => { s ? !o && r && r(s) : w(t); }), F(() => { (window._fcpr || (window._fcpr = [])).push(e), t.load.value = window.fcload, t.load.value || (n = setInterval(() => { t.load.value = window.fcload, t.load.value && clearInterval(n); }, 50)); }), M(() => { clearInterval(n); const s = (window._fcpr || (window._fcpr = [])).indexOf(e); s === -1 || _fcpr.splice(s, 1), y(t.keepAlive) || t.destroy(); }); } function X({ listeners: a, emit: t }) { if (t) for (const n of k) { const e = L(n), s = (r) => t(n, r), o = a[e]; a[e] = o ? (r) => { o(r), s(r); } : s; } } function Y({ listeners: a, player: t, options: n, paused: e }) { if (!e) return; const { onPlay: s, onPause: o } = a; let r = !1; const l = () => { const i = t.value ? t.value.paused : !0; r = e.value !== i, e.value = i; }; a.onPlay = s ? (i) => { l(), s(i); } : l, a.onPause = o ? (i) => { l(), o(i); } : l, c([t, () => { var i; return (i = n.value) == null ? void 0 : i.videoId; }], (i, [u]) => { u || l(); }), c([e, t], ([i, u]) => { if (r) { r = !1; return; } i ? u == null || u.pause() : u == null || u.play(); }); } function ee({ listeners: a, player: t, volume: n, muted: e }) { let s = !1, o = !1, r = e == null ? void 0 : e.value, l = n == null ? void 0 : n.value; const { onVolumechange: i, onFcplayerSrcChanged: u } = a, v = e && (() => { s = r !== e.value, e.value = !!r; }), m = n && (() => { o = l !== n.value, n.value = typeof l == "number" ? l : 1; }), h = () => { t.value && (t.value.muted = !!r, t.value.volume = typeof l == "number" ? l : 1); }, g = () => { var d; ((d = t.value) != null && d.readyState || 0 >= HTMLMediaElement.HAVE_CURRENT_DATA) && (r = t.value.muted, l = t.value.volume, v == null || v(), m == null || m()); }; a.onFcplayerSrcChanged = u ? (d) => { h(), u(d); } : h, a.onVolumechange = i ? (d) => { g(), i(d); } : g, e && c([e, t], ([d, p]) => { if (s) { s = !1; return; } p && (p.muted = d); }), n && c([n, t], ([d, p]) => { if (o) { o = !1; return; } p && (p.volume = d); }); } function te({ listeners: a, player: t, options: n, currentTime: e }) { if (!e) return; const { onTimeupdate: s } = a; let o = !1; const r = () => { const l = t.value ? t.value.currentTime : 0; o = l !== e.value, e.value = l; }; a.onTimeupdate = s ? (l) => { r(), s(l); } : r, c([t, () => { var l; return (l = n.value) == null ? void 0 : l.videoId; }], r), c([e, t], ([l, i]) => { if (o) { o = !1; return; } i && (i.currentTime = l); }); } function ae({ listeners: a, player: t, fullscreen: n }) { if (!n) return; const { onFullscreenenter: e, onFullscreenexit: s } = a; let o = !1; const r = () => { o = !n.value, n.value = !0; }, l = () => { o = !!n.value, n.value = !1; }; a.onFullscreenenter = e ? () => { r(), e(); } : r, a.onFullscreenexit = s ? () => { l(), s(); } : l, c([n, t], ([i, u]) => { if (o) { o = !1; return; } i ? u == null || u.requestFullscreen() : document.fullscreenElement === (u == null ? void 0 : u.getRootNode()) && document.exitFullscreen(); }); } function ne({ player: a, subtitles: t, currentSubtitles: n }) { if (!t && !n) return; t || (t = b([])); const e = () => { var o, r; const s = (o = a.value) != null && o.textTracks.length ? Array.from(((r = a.value) == null ? void 0 : r.textTracks) || []).filter((l) => l.kind === "subtitles") : []; (t.value.length !== s.length || t.value.some((l, i) => l !== s[i])) && (t.value = s), n && (n.value = s.find((l) => l.mode !== "disabled")); }; n && c(n, (s) => { var o; for (const r of t.value) s === r ? (s.is_active = !0, s.mode = (o = a.value) != null && o.config.subtitles.native ? "showing" : "hidden") : (r.is_active = !1, r.mode = "disabled"); }), c(a, (s, o) => { o == null || o.textTracks.removeEventListener("addtrack", e), o == null || o.textTracks.removeEventListener("removetrack", e), o == null || o.textTracks.removeEventListener("change", e), s == null || s.textTracks.addEventListener("addtrack", e), s == null || s.textTracks.addEventListener("removetrack", e), s == null || s.textTracks.addEventListener("change", e), e(); }); } function se({ listeners: a, player: t, options: n, readyState: e }) { if (!e) return; const { onLoadeddata: s } = a, o = () => { e.value = t.value ? t.value.readyState : 0; }; a.onLoadeddata = s ? (r) => { o(), s(r); } : o, c([t, () => { var r; return (r = n.value) == null ? void 0 : r.videoId; }], o); } function oe({ options: a, attributes: t }) { c([a], ([n]) => { t.value = ie(n); }, { deep: !0, immediate: !0 }); } function re({ options: a, key: t }) { c([() => { var n; return (n = a.value) == null ? void 0 : n.videoId; }], ([n], [e]) => { !n != !e && t.value++; }); } function le({ listeners: a, player: t }) { const n = () => { t.value && !Array.isArray(t.value.config.chapters.list) && (t.value.config.chapters.list = []); }, { onFcplayerSrcChanged: e } = a; a.onFcplayerSrcChanged = e ? (s) => { n(), e(s); } : n; } function ie(a = {}) { return Object.entries(a).reduce((n, [e, s]) => { if (s !== void 0) { const o = J[e] || e; n[`data-${o}`] = s; } return n; }, { ...Z }); } function L(a) { return `on${a[0].toUpperCase()}${a.slice(1)}`; } const ue = /* @__PURE__ */ I({ __name: "FreecasterPlayer", props: /* @__PURE__ */ B({ keepAlive: { type: Boolean }, videoId: {}, height: {}, width: {}, preload: {}, volume: {}, autoplay: { type: Boolean }, autopause: { type: Boolean }, controls: { type: Boolean }, muted: { type: Boolean }, loop: { type: Boolean }, cast: { type: Boolean }, playsinline: { type: Boolean }, watermarkEnabled: { type: Boolean }, lang: {}, stats: { type: Boolean }, noads: { type: Boolean }, thumbnailsSrc: {}, poster: {}, stretching: { type: [String, Boolean] }, subtitlesDefaultLang: {}, subtitlesLang: {}, subtitlesNative: { type: Boolean }, floatOnScroll: { type: Boolean }, multiplay: { type: Boolean }, chaptersEnabled: { type: Boolean }, chaptersStyle: {}, chaptersList: {}, audioOnly: { type: Boolean }, trackersGaEnabled: { type: Boolean }, trackersGaTagIds: {}, speedOptions: {}, speedLabels: {} }, { modelValue: {}, modelModifiers: {}, paused: { type: Boolean, default: !0 }, pausedModifiers: {}, muted: { type: Boolean, default: !1 }, mutedModifiers: {}, fullscreen: { type: Boolean, default: !1 }, fullscreenModifiers: {}, volume: { default: 1 }, volumeModifiers: {}, currentTime: { default: 0 }, currentTimeModifiers: {}, readyState: { default: 0 }, readyStateModifiers: {}, currentSubtitles: {}, currentSubtitlesModifiers: {}, subtitles: { default: [] }, subtitlesModifiers: {}, destroy: {}, destroyModifiers: {} }), emits: /* @__PURE__ */ B(["abort", "canplay", "canplaythrough", "durationchange", "emptied", "encrypted", "ended", "error", "load", "loadeddata", "loadedmetadata", "loadstart", "pause", "play", "playing", "progress", "ratechange", "seeked", "seeking", "stalled", "suspend", "timeupdate", "volumechange", "waiting", "waitingforkey", "enterpictureinpicture", "leavepictureinpicture", "resize", "fullscreenenter", "fullscreenexit", "viewenter", "viewleave", "fcplayerDestroy", "fcplayerSrcChanged", "fcplayerConfigChanged", "fcplayerCountdownTick", "fcplayerCountdownEnabled", "fcplayerCountdownDisabled", "fcplayerCountdownZero"], ["update:modelValue", "update:paused", "update:muted", "update:fullscreen", "update:volume", "update:currentTime", "update:readyState", "update:currentSubtitles", "update:subtitles", "update:destroy"]), setup(a, { expose: t, emit: n }) { const e = a, s = n, o = f(a, "modelValue"), r = f(a, "paused"), l = f(a, "muted"), i = f(a, "fullscreen"), u = f(a, "volume"), v = f(a, "currentTime"), m = f(a, "readyState"), h = f(a, "currentSubtitles"), g = f(a, "subtitles"), d = f(a, "destroy"), p = A(() => ({ videoId: e.videoId, height: e.height, width: e.width, preload: e.preload, volume: e.volume, autoplay: e.autoplay, autopause: e.autopause, controls: e.controls, muted: e.muted, loop: e.loop, cast: e.cast, playsinline: e.playsinline, watermarkEnabled: e.watermarkEnabled, lang: e.lang, stats: e.stats, noads: e.noads, thumbnailsSrc: e.thumbnailsSrc, poster: e.poster, stretching: e.stretching, subtitlesDefaultLang: e.subtitlesDefaultLang, subtitlesLang: e.subtitlesLang, subtitlesNative: e.subtitlesNative, floatOnScroll: e.floatOnScroll, multiplay: e.multiplay, chaptersEnabled: e.chaptersEnabled, chaptersStyle: e.chaptersStyle, chaptersList: e.chaptersList, audioOnly: e.audioOnly, trackersGaEnabled: e.trackersGaEnabled, trackersGaTagIds: e.trackersGaTagIds, speedOptions: e.speedOptions, speedLabels: e.speedLabels })), T = _(), { element: N, key: fe, attributes: E, destroy: S } = q({ keepAlive: A(() => e.keepAlive), options: p, player: o, paused: r, muted: l, fullscreen: i, volume: u, currentTime: v, readyState: m, emit: s, currentSubtitles: h, subtitles: g }); return d.value = S, t({ player: o, paused: r, muted: l, fullscreen: i, volume: u, currentTime: v, readyState: m, currentSubtitles: h, subtitles: g, destroy: S }), (pe, ve) => (O(), V("div", R({ ref_key: "element", ref: N }, { ...y(T), ...y(E) }, { class: [ y(T).class, y(E).class ].filter(Boolean) }), null, 16)); } }), ce = "https://player.freecaster.com/freecaster/stable/fcplayer.js", de = "FreecasterPlayer", he = { async install(a, t = {}) { let { script: n = !0, component: e = !0 } = t; if (n === !0 && (n = ce), e === !0 && (e = de), n && typeof window < "u" && !window.fcplayer) { const s = document.createElement("script"); s.async = !0, s.src = n, document.head.appendChild(s); } e && a.component(e, ue); } }, ge = /* @__PURE__ */ I({ __name: "FreecasterStyle", setup(a) { const t = z(); let n; F(() => { s() || (n = new MutationObserver(() => { s() && e(); }), n.observe(document.head, { childList: !0 })); }), M(() => { e(); }); function e() { n == null || n.disconnect(), n = void 0; } function s() { return !!(t.value || (t.value = Array.from(document.querySelectorAll( 'link[rel="stylesheet"][href^="https://player.freecaster.com/"]' )).map((o) => `@import ${JSON.stringify(o.href)};`).join(` `))); } return (o, r) => t.value ? (O(), G(U("style"), { key: 0 }, { default: x(() => [ $(j(t.value), 1) ]), _: 1 })) : H("", !0); } }); export { ue as FreecasterPlayer, he as FreecasterPlugin, ge as FreecasterStyle, q as usePlayer };