@plutotcool/vue-freecaster
Version:
Freecaster video player integration for vue
546 lines (545 loc) • 15 kB
JavaScript
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
};