5609 lines
193 KiB
JavaScript
5609 lines
193 KiB
JavaScript
"object" == typeof navigator &&
|
|
(function (e, t) {
|
|
"object" == typeof exports && "undefined" != typeof module
|
|
? (module.exports = t())
|
|
: "function" == typeof define && define.amd
|
|
? define("Plyr", t)
|
|
: ((e = "undefined" != typeof globalThis ? globalThis : e || self).Plyr =
|
|
t());
|
|
})(this, function () {
|
|
"use strict";
|
|
function e(e, t, i) {
|
|
return (
|
|
(t = (function (e) {
|
|
var t = (function (e, t) {
|
|
if ("object" != typeof e || null === e) return e;
|
|
var i = e[Symbol.toPrimitive];
|
|
if (void 0 !== i) {
|
|
var s = i.call(e, t || "default");
|
|
if ("object" != typeof s) return s;
|
|
throw new TypeError(
|
|
"@@toPrimitive must return a primitive value."
|
|
);
|
|
}
|
|
return ("string" === t ? String : Number)(e);
|
|
})(e, "string");
|
|
return "symbol" == typeof t ? t : String(t);
|
|
})(t)) in e
|
|
? Object.defineProperty(e, t, {
|
|
value: i,
|
|
enumerable: !0,
|
|
configurable: !0,
|
|
writable: !0,
|
|
})
|
|
: (e[t] = i),
|
|
e
|
|
);
|
|
}
|
|
function t(e, t) {
|
|
for (var i = 0; i < t.length; i++) {
|
|
var s = t[i];
|
|
(s.enumerable = s.enumerable || !1),
|
|
(s.configurable = !0),
|
|
"value" in s && (s.writable = !0),
|
|
Object.defineProperty(e, s.key, s);
|
|
}
|
|
}
|
|
function i(e, t, i) {
|
|
return (
|
|
t in e
|
|
? Object.defineProperty(e, t, {
|
|
value: i,
|
|
enumerable: !0,
|
|
configurable: !0,
|
|
writable: !0,
|
|
})
|
|
: (e[t] = i),
|
|
e
|
|
);
|
|
}
|
|
function s(e, t) {
|
|
var i = Object.keys(e);
|
|
if (Object.getOwnPropertySymbols) {
|
|
var s = Object.getOwnPropertySymbols(e);
|
|
t &&
|
|
(s = s.filter(function (t) {
|
|
return Object.getOwnPropertyDescriptor(e, t).enumerable;
|
|
})),
|
|
i.push.apply(i, s);
|
|
}
|
|
return i;
|
|
}
|
|
function n(e) {
|
|
for (var t = 1; t < arguments.length; t++) {
|
|
var n = null != arguments[t] ? arguments[t] : {};
|
|
t % 2
|
|
? s(Object(n), !0).forEach(function (t) {
|
|
i(e, t, n[t]);
|
|
})
|
|
: Object.getOwnPropertyDescriptors
|
|
? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n))
|
|
: s(Object(n)).forEach(function (t) {
|
|
Object.defineProperty(
|
|
e,
|
|
t,
|
|
Object.getOwnPropertyDescriptor(n, t)
|
|
);
|
|
});
|
|
}
|
|
return e;
|
|
}
|
|
var a = { addCSS: !0, thumbWidth: 15, watch: !0 };
|
|
var l = function (e) {
|
|
return null != e ? e.constructor : null;
|
|
},
|
|
r = function (e, t) {
|
|
return !!(e && t && e instanceof t);
|
|
},
|
|
o = function (e) {
|
|
return null == e;
|
|
},
|
|
c = function (e) {
|
|
return l(e) === Object;
|
|
},
|
|
u = function (e) {
|
|
return l(e) === String;
|
|
},
|
|
h = function (e) {
|
|
return Array.isArray(e);
|
|
},
|
|
d = function (e) {
|
|
return r(e, NodeList);
|
|
},
|
|
m = {
|
|
nullOrUndefined: o,
|
|
object: c,
|
|
number: function (e) {
|
|
return l(e) === Number && !Number.isNaN(e);
|
|
},
|
|
string: u,
|
|
boolean: function (e) {
|
|
return l(e) === Boolean;
|
|
},
|
|
function: function (e) {
|
|
return l(e) === Function;
|
|
},
|
|
array: h,
|
|
nodeList: d,
|
|
element: function (e) {
|
|
return r(e, Element);
|
|
},
|
|
event: function (e) {
|
|
return r(e, Event);
|
|
},
|
|
empty: function (e) {
|
|
return (
|
|
o(e) ||
|
|
((u(e) || h(e) || d(e)) && !e.length) ||
|
|
(c(e) && !Object.keys(e).length)
|
|
);
|
|
},
|
|
};
|
|
function p(e, t) {
|
|
if (1 > t) {
|
|
var i = (function (e) {
|
|
var t = "".concat(e).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
|
|
return t
|
|
? Math.max(0, (t[1] ? t[1].length : 0) - (t[2] ? +t[2] : 0))
|
|
: 0;
|
|
})(t);
|
|
return parseFloat(e.toFixed(i));
|
|
}
|
|
return Math.round(e / t) * t;
|
|
}
|
|
var g = (function () {
|
|
function e(t, i) {
|
|
(function (e, t) {
|
|
if (!(e instanceof t))
|
|
throw new TypeError("Cannot call a class as a function");
|
|
})(this, e),
|
|
m.element(t)
|
|
? (this.element = t)
|
|
: m.string(t) && (this.element = document.querySelector(t)),
|
|
m.element(this.element) &&
|
|
m.empty(this.element.rangeTouch) &&
|
|
((this.config = n({}, a, {}, i)), this.init());
|
|
}
|
|
return (
|
|
(function (e, i, s) {
|
|
i && t(e.prototype, i), s && t(e, s);
|
|
})(
|
|
e,
|
|
[
|
|
{
|
|
key: "init",
|
|
value: function () {
|
|
e.enabled &&
|
|
(this.config.addCSS &&
|
|
((this.element.style.userSelect = "none"),
|
|
(this.element.style.webKitUserSelect = "none"),
|
|
(this.element.style.touchAction = "manipulation")),
|
|
this.listeners(!0),
|
|
(this.element.rangeTouch = this));
|
|
},
|
|
},
|
|
{
|
|
key: "destroy",
|
|
value: function () {
|
|
e.enabled &&
|
|
(this.config.addCSS &&
|
|
((this.element.style.userSelect = ""),
|
|
(this.element.style.webKitUserSelect = ""),
|
|
(this.element.style.touchAction = "")),
|
|
this.listeners(!1),
|
|
(this.element.rangeTouch = null));
|
|
},
|
|
},
|
|
{
|
|
key: "listeners",
|
|
value: function (e) {
|
|
var t = this,
|
|
i = e ? "addEventListener" : "removeEventListener";
|
|
["touchstart", "touchmove", "touchend"].forEach(function (e) {
|
|
t.element[i](
|
|
e,
|
|
function (e) {
|
|
return t.set(e);
|
|
},
|
|
!1
|
|
);
|
|
});
|
|
},
|
|
},
|
|
{
|
|
key: "get",
|
|
value: function (t) {
|
|
if (!e.enabled || !m.event(t)) return null;
|
|
var i,
|
|
s = t.target,
|
|
n = t.changedTouches[0],
|
|
a = parseFloat(s.getAttribute("min")) || 0,
|
|
l = parseFloat(s.getAttribute("max")) || 100,
|
|
r = parseFloat(s.getAttribute("step")) || 1,
|
|
o = s.getBoundingClientRect(),
|
|
c = ((100 / o.width) * (this.config.thumbWidth / 2)) / 100;
|
|
return (
|
|
0 > (i = (100 / o.width) * (n.clientX - o.left))
|
|
? (i = 0)
|
|
: 100 < i && (i = 100),
|
|
50 > i
|
|
? (i -= (100 - 2 * i) * c)
|
|
: 50 < i && (i += 2 * (i - 50) * c),
|
|
a + p((i / 100) * (l - a), r)
|
|
);
|
|
},
|
|
},
|
|
{
|
|
key: "set",
|
|
value: function (t) {
|
|
e.enabled &&
|
|
m.event(t) &&
|
|
!t.target.disabled &&
|
|
(t.preventDefault(),
|
|
(t.target.value = this.get(t)),
|
|
(function (e, t) {
|
|
if (e && t) {
|
|
var i = new Event(t, { bubbles: !0 });
|
|
e.dispatchEvent(i);
|
|
}
|
|
})(t.target, "touchend" === t.type ? "change" : "input"));
|
|
},
|
|
},
|
|
],
|
|
[
|
|
{
|
|
key: "setup",
|
|
value: function (t) {
|
|
var i =
|
|
1 < arguments.length && void 0 !== arguments[1]
|
|
? arguments[1]
|
|
: {},
|
|
s = null;
|
|
if (
|
|
(m.empty(t) || m.string(t)
|
|
? (s = Array.from(
|
|
document.querySelectorAll(
|
|
m.string(t) ? t : 'input[type="range"]'
|
|
)
|
|
))
|
|
: m.element(t)
|
|
? (s = [t])
|
|
: m.nodeList(t)
|
|
? (s = Array.from(t))
|
|
: m.array(t) && (s = t.filter(m.element)),
|
|
m.empty(s))
|
|
)
|
|
return null;
|
|
var l = n({}, a, {}, i);
|
|
if (m.string(t) && l.watch) {
|
|
var r = new MutationObserver(function (i) {
|
|
Array.from(i).forEach(function (i) {
|
|
Array.from(i.addedNodes).forEach(function (i) {
|
|
m.element(i) &&
|
|
(function (e, t) {
|
|
return function () {
|
|
return Array.from(
|
|
document.querySelectorAll(t)
|
|
).includes(this);
|
|
}.call(e, t);
|
|
})(i, t) &&
|
|
new e(i, l);
|
|
});
|
|
});
|
|
});
|
|
r.observe(document.body, { childList: !0, subtree: !0 });
|
|
}
|
|
return s.map(function (t) {
|
|
return new e(t, i);
|
|
});
|
|
},
|
|
},
|
|
{
|
|
key: "enabled",
|
|
get: function () {
|
|
return "ontouchstart" in document.documentElement;
|
|
},
|
|
},
|
|
]
|
|
),
|
|
e
|
|
);
|
|
})();
|
|
const f = (e) => (null != e ? e.constructor : null),
|
|
y = (e, t) => Boolean(e && t && e instanceof t),
|
|
b = (e) => null == e,
|
|
v = (e) => f(e) === Object,
|
|
w = (e) => f(e) === String,
|
|
T = (e) => "function" == typeof e,
|
|
k = (e) => Array.isArray(e),
|
|
C = (e) => y(e, NodeList),
|
|
A = (e) =>
|
|
b(e) ||
|
|
((w(e) || k(e) || C(e)) && !e.length) ||
|
|
(v(e) && !Object.keys(e).length);
|
|
var S = {
|
|
nullOrUndefined: b,
|
|
object: v,
|
|
number: (e) => f(e) === Number && !Number.isNaN(e),
|
|
string: w,
|
|
boolean: (e) => f(e) === Boolean,
|
|
function: T,
|
|
array: k,
|
|
weakMap: (e) => y(e, WeakMap),
|
|
nodeList: C,
|
|
element: (e) =>
|
|
null !== e &&
|
|
"object" == typeof e &&
|
|
1 === e.nodeType &&
|
|
"object" == typeof e.style &&
|
|
"object" == typeof e.ownerDocument,
|
|
textNode: (e) => f(e) === Text,
|
|
event: (e) => y(e, Event),
|
|
keyboardEvent: (e) => y(e, KeyboardEvent),
|
|
cue: (e) => y(e, window.TextTrackCue) || y(e, window.VTTCue),
|
|
track: (e) => y(e, TextTrack) || (!b(e) && w(e.kind)),
|
|
promise: (e) => y(e, Promise) && T(e.then),
|
|
url: (e) => {
|
|
if (y(e, window.URL)) return !0;
|
|
if (!w(e)) return !1;
|
|
let t = e;
|
|
(e.startsWith("http://") && e.startsWith("https://")) ||
|
|
(t = `http://${e}`);
|
|
try {
|
|
return !A(new URL(t).hostname);
|
|
} catch (e) {
|
|
return !1;
|
|
}
|
|
},
|
|
empty: A,
|
|
};
|
|
const E = (() => {
|
|
const e = document.createElement("span"),
|
|
t = {
|
|
WebkitTransition: "webkitTransitionEnd",
|
|
MozTransition: "transitionend",
|
|
OTransition: "oTransitionEnd otransitionend",
|
|
transition: "transitionend",
|
|
},
|
|
i = Object.keys(t).find((t) => void 0 !== e.style[t]);
|
|
return !!S.string(i) && t[i];
|
|
})();
|
|
function P(e, t) {
|
|
setTimeout(() => {
|
|
try {
|
|
(e.hidden = !0), e.offsetHeight, (e.hidden = !1);
|
|
} catch (e) { }
|
|
}, t);
|
|
}
|
|
var M = {
|
|
isIE: Boolean(window.document.documentMode),
|
|
isEdge: /Edge/g.test(navigator.userAgent),
|
|
isWebKit:
|
|
"WebkitAppearance" in document.documentElement.style &&
|
|
!/Edge/g.test(navigator.userAgent),
|
|
isIPhone:
|
|
/iPhone|iPod/gi.test(navigator.userAgent) &&
|
|
navigator.maxTouchPoints > 1,
|
|
isIPadOS:
|
|
"MacIntel" === navigator.platform && navigator.maxTouchPoints > 1,
|
|
isIos:
|
|
/iPad|iPhone|iPod/gi.test(navigator.userAgent) &&
|
|
navigator.maxTouchPoints > 1,
|
|
};
|
|
function N(e, t) {
|
|
return t.split(".").reduce((e, t) => e && e[t], e);
|
|
}
|
|
function x(e = {}, ...t) {
|
|
if (!t.length) return e;
|
|
const i = t.shift();
|
|
return S.object(i)
|
|
? (Object.keys(i).forEach((t) => {
|
|
S.object(i[t])
|
|
? (Object.keys(e).includes(t) || Object.assign(e, { [t]: {} }),
|
|
x(e[t], i[t]))
|
|
: Object.assign(e, { [t]: i[t] });
|
|
}),
|
|
x(e, ...t))
|
|
: e;
|
|
}
|
|
function L(e, t) {
|
|
const i = e.length ? e : [e];
|
|
Array.from(i)
|
|
.reverse()
|
|
.forEach((e, i) => {
|
|
const s = i > 0 ? t.cloneNode(!0) : t,
|
|
n = e.parentNode,
|
|
a = e.nextSibling;
|
|
s.appendChild(e), a ? n.insertBefore(s, a) : n.appendChild(s);
|
|
});
|
|
}
|
|
function I(e, t) {
|
|
S.element(e) &&
|
|
!S.empty(t) &&
|
|
Object.entries(t)
|
|
.filter(([, e]) => !S.nullOrUndefined(e))
|
|
.forEach(([t, i]) => e.setAttribute(t, i));
|
|
}
|
|
function $(e, t, i) {
|
|
const s = document.createElement(e);
|
|
return S.object(t) && I(s, t), S.string(i) && (s.innerText = i), s;
|
|
}
|
|
function _(e, t, i, s) {
|
|
S.element(t) && t.appendChild($(e, i, s));
|
|
}
|
|
function O(e) {
|
|
S.nodeList(e) || S.array(e)
|
|
? Array.from(e).forEach(O)
|
|
: S.element(e) &&
|
|
S.element(e.parentNode) &&
|
|
e.parentNode.removeChild(e);
|
|
}
|
|
function j(e) {
|
|
if (!S.element(e)) return;
|
|
let { length: t } = e.childNodes;
|
|
for (; t > 0;) e.removeChild(e.lastChild), (t -= 1);
|
|
}
|
|
function q(e, t) {
|
|
return S.element(t) && S.element(t.parentNode) && S.element(e)
|
|
? (t.parentNode.replaceChild(e, t), e)
|
|
: null;
|
|
}
|
|
function D(e, t) {
|
|
if (!S.string(e) || S.empty(e)) return {};
|
|
const i = {},
|
|
s = x({}, t);
|
|
return (
|
|
e.split(",").forEach((e) => {
|
|
const t = e.trim(),
|
|
n = t.replace(".", ""),
|
|
a = t.replace(/[[\]]/g, "").split("="),
|
|
[l] = a,
|
|
r = a.length > 1 ? a[1].replace(/["']/g, "") : "";
|
|
switch (t.charAt(0)) {
|
|
case ".":
|
|
S.string(s.class) ? (i.class = `${s.class} ${n}`) : (i.class = n);
|
|
break;
|
|
case "#":
|
|
i.id = t.replace("#", "");
|
|
break;
|
|
case "[":
|
|
i[l] = r;
|
|
}
|
|
}),
|
|
x(s, i)
|
|
);
|
|
}
|
|
function H(e, t) {
|
|
if (!S.element(e)) return;
|
|
let i = t;
|
|
S.boolean(i) || (i = !e.hidden), (e.hidden = i);
|
|
}
|
|
function R(e, t, i) {
|
|
if (S.nodeList(e)) return Array.from(e).map((e) => R(e, t, i));
|
|
if (S.element(e)) {
|
|
let s = "toggle";
|
|
return (
|
|
void 0 !== i && (s = i ? "add" : "remove"),
|
|
e.classList[s](t),
|
|
e.classList.contains(t)
|
|
);
|
|
}
|
|
return !1;
|
|
}
|
|
function F(e, t) {
|
|
return S.element(e) && e.classList.contains(t);
|
|
}
|
|
function V(e, t) {
|
|
const { prototype: i } = Element;
|
|
return (
|
|
i.matches ||
|
|
i.webkitMatchesSelector ||
|
|
i.mozMatchesSelector ||
|
|
i.msMatchesSelector ||
|
|
function () {
|
|
return Array.from(document.querySelectorAll(t)).includes(this);
|
|
}
|
|
).call(e, t);
|
|
}
|
|
function U(e) {
|
|
return this.elements.container.querySelectorAll(e);
|
|
}
|
|
function B(e) {
|
|
return this.elements.container.querySelector(e);
|
|
}
|
|
function W(e = null, t = !1) {
|
|
S.element(e) && e.focus({ preventScroll: !0, focusVisible: t });
|
|
}
|
|
const z = {
|
|
"audio/ogg": "vorbis",
|
|
"audio/wav": "1",
|
|
"video/webm": "vp8, vorbis",
|
|
"video/mp4": "avc1.42E01E, mp4a.40.2",
|
|
"video/ogg": "theora",
|
|
},
|
|
K = {
|
|
audio: "canPlayType" in document.createElement("audio"),
|
|
video: "canPlayType" in document.createElement("video"),
|
|
check(e, t) {
|
|
const i = K[e] || "html5" !== t;
|
|
return { api: i, ui: i && K.rangeInput };
|
|
},
|
|
pip: !(
|
|
M.isIPhone ||
|
|
(!S.function($("video").webkitSetPresentationMode) &&
|
|
(!document.pictureInPictureEnabled ||
|
|
$("video").disablePictureInPicture))
|
|
),
|
|
airplay: S.function(window.WebKitPlaybackTargetAvailabilityEvent),
|
|
playsinline: "playsInline" in document.createElement("video"),
|
|
mime(e) {
|
|
if (S.empty(e)) return !1;
|
|
const [t] = e.split("/");
|
|
let i = e;
|
|
if (!this.isHTML5 || t !== this.type) return !1;
|
|
Object.keys(z).includes(i) && (i += `; codecs="${z[e]}"`);
|
|
try {
|
|
return Boolean(i && this.media.canPlayType(i).replace(/no/, ""));
|
|
} catch (e) {
|
|
return !1;
|
|
}
|
|
},
|
|
textTracks: "textTracks" in document.createElement("video"),
|
|
rangeInput: (() => {
|
|
const e = document.createElement("input");
|
|
return (e.type = "range"), "range" === e.type;
|
|
})(),
|
|
touch: "ontouchstart" in document.documentElement,
|
|
transitions: !1 !== E,
|
|
reducedMotion:
|
|
"matchMedia" in window &&
|
|
window.matchMedia("(prefers-reduced-motion)").matches,
|
|
},
|
|
Y = (() => {
|
|
let e = !1;
|
|
try {
|
|
const t = Object.defineProperty({}, "passive", {
|
|
get: () => ((e = !0), null),
|
|
});
|
|
window.addEventListener("test", null, t),
|
|
window.removeEventListener("test", null, t);
|
|
} catch (e) { }
|
|
return e;
|
|
})();
|
|
function Q(e, t, i, s = !1, n = !0, a = !1) {
|
|
if (!e || !("addEventListener" in e) || S.empty(t) || !S.function(i))
|
|
return;
|
|
const l = t.split(" ");
|
|
let r = a;
|
|
Y && (r = { passive: n, capture: a }),
|
|
l.forEach((t) => {
|
|
this &&
|
|
this.eventListeners &&
|
|
s &&
|
|
this.eventListeners.push({
|
|
element: e,
|
|
type: t,
|
|
callback: i,
|
|
options: r,
|
|
}),
|
|
e[s ? "addEventListener" : "removeEventListener"](t, i, r);
|
|
});
|
|
}
|
|
function X(e, t = "", i, s = !0, n = !1) {
|
|
Q.call(this, e, t, i, !0, s, n);
|
|
}
|
|
function J(e, t = "", i, s = !0, n = !1) {
|
|
Q.call(this, e, t, i, !1, s, n);
|
|
}
|
|
function G(e, t = "", i, s = !0, n = !1) {
|
|
const a = (...l) => {
|
|
J(e, t, a, s, n), i.apply(this, l);
|
|
};
|
|
Q.call(this, e, t, a, !0, s, n);
|
|
}
|
|
function Z(e, t = "", i = !1, s = {}) {
|
|
if (!S.element(e) || S.empty(t)) return;
|
|
const n = new CustomEvent(t, {
|
|
bubbles: i,
|
|
detail: { ...s, plyr: this },
|
|
});
|
|
e.dispatchEvent(n);
|
|
}
|
|
function ee() {
|
|
this &&
|
|
this.eventListeners &&
|
|
(this.eventListeners.forEach((e) => {
|
|
const { element: t, type: i, callback: s, options: n } = e;
|
|
t.removeEventListener(i, s, n);
|
|
}),
|
|
(this.eventListeners = []));
|
|
}
|
|
function te() {
|
|
return new Promise((e) =>
|
|
this.ready
|
|
? setTimeout(e, 0)
|
|
: X.call(this, this.elements.container, "ready", e)
|
|
).then(() => { });
|
|
}
|
|
function ie(e) {
|
|
S.promise(e) && e.then(null, () => { });
|
|
}
|
|
function se(e) {
|
|
return S.array(e) ? e.filter((t, i) => e.indexOf(t) === i) : e;
|
|
}
|
|
function ne(e, t) {
|
|
return S.array(e) && e.length
|
|
? e.reduce((e, i) => (Math.abs(i - t) < Math.abs(e - t) ? i : e))
|
|
: null;
|
|
}
|
|
function ae(e) {
|
|
return !(!window || !window.CSS) && window.CSS.supports(e);
|
|
}
|
|
const le = [
|
|
[1, 1],
|
|
[4, 3],
|
|
[3, 4],
|
|
[5, 4],
|
|
[4, 5],
|
|
[3, 2],
|
|
[2, 3],
|
|
[16, 10],
|
|
[10, 16],
|
|
[16, 9],
|
|
[9, 16],
|
|
[21, 9],
|
|
[9, 21],
|
|
[32, 9],
|
|
[9, 32],
|
|
].reduce((e, [t, i]) => ({ ...e, [t / i]: [t, i] }), {});
|
|
function re(e) {
|
|
if (!(S.array(e) || (S.string(e) && e.includes(":")))) return !1;
|
|
return (S.array(e) ? e : e.split(":")).map(Number).every(S.number);
|
|
}
|
|
function oe(e) {
|
|
if (!S.array(e) || !e.every(S.number)) return null;
|
|
const [t, i] = e,
|
|
s = (e, t) => (0 === t ? e : s(t, e % t)),
|
|
n = s(t, i);
|
|
return [t / n, i / n];
|
|
}
|
|
function ce(e) {
|
|
const t = (e) => (re(e) ? e.split(":").map(Number) : null);
|
|
let i = t(e);
|
|
if (
|
|
(null === i && (i = t(this.config.ratio)),
|
|
null === i &&
|
|
!S.empty(this.embed) &&
|
|
S.array(this.embed.ratio) &&
|
|
({ ratio: i } = this.embed),
|
|
null === i && this.isHTML5)
|
|
) {
|
|
const { videoWidth: e, videoHeight: t } = this.media;
|
|
i = [e, t];
|
|
}
|
|
return oe(i);
|
|
}
|
|
function ue(e) {
|
|
if (!this.isVideo) return {};
|
|
const { wrapper: t } = this.elements,
|
|
i = ce.call(this, e);
|
|
if (!S.array(i)) return {};
|
|
const [s, n] = oe(i),
|
|
a = (100 / s) * n;
|
|
if (
|
|
(ae(`aspect-ratio: ${s}/${n}`)
|
|
? (t.style.aspectRatio = `${s}/${n}`)
|
|
: (t.style.paddingBottom = `${a}%`),
|
|
this.isVimeo && !this.config.vimeo.premium && this.supported.ui)
|
|
) {
|
|
const e =
|
|
(100 / this.media.offsetWidth) *
|
|
parseInt(window.getComputedStyle(this.media).paddingBottom, 10),
|
|
i = (e - a) / (e / 50);
|
|
this.fullscreen.active
|
|
? (t.style.paddingBottom = null)
|
|
: (this.media.style.transform = `translateY(-${i}%)`);
|
|
} else this.isHTML5 && t.classList.add(this.config.classNames.videoFixedRatio);
|
|
return { padding: a, ratio: i };
|
|
}
|
|
function he(e, t, i = 0.05) {
|
|
const s = e / t,
|
|
n = ne(Object.keys(le), s);
|
|
return Math.abs(n - s) <= i ? le[n] : [e, t];
|
|
}
|
|
const de = {
|
|
getSources() {
|
|
if (!this.isHTML5) return [];
|
|
return Array.from(this.media.querySelectorAll("source")).filter((e) => {
|
|
const t = e.getAttribute("type");
|
|
return !!S.empty(t) || K.mime.call(this, t);
|
|
});
|
|
},
|
|
getQualityOptions() {
|
|
return this.config.quality.forced
|
|
? this.config.quality.options
|
|
: de.getSources
|
|
.call(this)
|
|
.map((e) => Number(e.getAttribute("size")))
|
|
.filter(Boolean);
|
|
},
|
|
setup() {
|
|
if (!this.isHTML5) return;
|
|
const e = this;
|
|
(e.options.speed = e.config.speed.options),
|
|
S.empty(this.config.ratio) || ue.call(e),
|
|
Object.defineProperty(e.media, "quality", {
|
|
get() {
|
|
const t = de.getSources
|
|
.call(e)
|
|
.find((t) => t.getAttribute("src") === e.source);
|
|
return t && Number(t.getAttribute("size"));
|
|
},
|
|
set(t) {
|
|
if (e.quality !== t) {
|
|
if (
|
|
e.config.quality.forced &&
|
|
S.function(e.config.quality.onChange)
|
|
)
|
|
e.config.quality.onChange(t);
|
|
else {
|
|
const i = de.getSources
|
|
.call(e)
|
|
.find((e) => Number(e.getAttribute("size")) === t);
|
|
if (!i) return;
|
|
const {
|
|
currentTime: s,
|
|
paused: n,
|
|
preload: a,
|
|
readyState: l,
|
|
playbackRate: r,
|
|
} = e.media;
|
|
(e.media.src = i.getAttribute("src")),
|
|
("none" !== a || l) &&
|
|
(e.once("loadedmetadata", () => {
|
|
(e.speed = r), (e.currentTime = s), n || ie(e.play());
|
|
}),
|
|
e.media.load());
|
|
}
|
|
Z.call(e, e.media, "qualitychange", !1, { quality: t });
|
|
}
|
|
},
|
|
});
|
|
},
|
|
cancelRequests() {
|
|
this.isHTML5 &&
|
|
(O(de.getSources.call(this)),
|
|
this.media.setAttribute("src", this.config.blankVideo),
|
|
this.media.load(),
|
|
this.debug.log("Cancelled network requests"));
|
|
},
|
|
};
|
|
function me(e, ...t) {
|
|
return S.empty(e)
|
|
? e
|
|
: e.toString().replace(/{(\d+)}/g, (e, i) => t[i].toString());
|
|
}
|
|
const pe = (e = "", t = "", i = "") =>
|
|
e.replace(
|
|
new RegExp(
|
|
t.toString().replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1"),
|
|
"g"
|
|
),
|
|
i.toString()
|
|
),
|
|
ge = (e = "") =>
|
|
e
|
|
.toString()
|
|
.replace(
|
|
/\w\S*/g,
|
|
(e) => e.charAt(0).toUpperCase() + e.slice(1).toLowerCase()
|
|
);
|
|
function fe(e = "") {
|
|
let t = e.toString();
|
|
return (
|
|
(t = (function (e = "") {
|
|
let t = e.toString();
|
|
return (
|
|
(t = pe(t, "-", " ")),
|
|
(t = pe(t, "_", " ")),
|
|
(t = ge(t)),
|
|
pe(t, " ", "")
|
|
);
|
|
})(t)),
|
|
t.charAt(0).toLowerCase() + t.slice(1)
|
|
);
|
|
}
|
|
function ye(e) {
|
|
const t = document.createElement("div");
|
|
return t.appendChild(e), t.innerHTML;
|
|
}
|
|
const be = {
|
|
pip: "PIP",
|
|
airplay: "AirPlay",
|
|
html5: "HTML5",
|
|
vimeo: "Vimeo",
|
|
youtube: "YouTube",
|
|
},
|
|
ve = {
|
|
get(e = "", t = {}) {
|
|
if (S.empty(e) || S.empty(t)) return "";
|
|
let i = N(t.i18n, e);
|
|
if (S.empty(i)) return Object.keys(be).includes(e) ? be[e] : "";
|
|
const s = { "{seektime}": t.seekTime, "{title}": t.title };
|
|
return (
|
|
Object.entries(s).forEach(([e, t]) => {
|
|
i = pe(i, e, t);
|
|
}),
|
|
i
|
|
);
|
|
},
|
|
};
|
|
class we {
|
|
constructor(t) {
|
|
e(this, "get", (e) => {
|
|
if (!we.supported || !this.enabled) return null;
|
|
const t = window.localStorage.getItem(this.key);
|
|
if (S.empty(t)) return null;
|
|
const i = JSON.parse(t);
|
|
return S.string(e) && e.length ? i[e] : i;
|
|
}),
|
|
e(this, "set", (e) => {
|
|
if (!we.supported || !this.enabled) return;
|
|
if (!S.object(e)) return;
|
|
let t = this.get();
|
|
S.empty(t) && (t = {}), x(t, e);
|
|
try {
|
|
window.localStorage.setItem(this.key, JSON.stringify(t));
|
|
} catch (e) { }
|
|
}),
|
|
(this.enabled = t.config.storage.enabled),
|
|
(this.key = t.config.storage.key);
|
|
}
|
|
static get supported() {
|
|
try {
|
|
if (!("localStorage" in window)) return !1;
|
|
const e = "___test";
|
|
return (
|
|
window.localStorage.setItem(e, e),
|
|
window.localStorage.removeItem(e),
|
|
!0
|
|
);
|
|
} catch (e) {
|
|
return !1;
|
|
}
|
|
}
|
|
}
|
|
function Te(e, t = "text") {
|
|
return new Promise((i, s) => {
|
|
try {
|
|
const s = new XMLHttpRequest();
|
|
if (!("withCredentials" in s)) return;
|
|
s.addEventListener("load", () => {
|
|
if ("text" === t)
|
|
try {
|
|
i(JSON.parse(s.responseText));
|
|
} catch (e) {
|
|
i(s.responseText);
|
|
}
|
|
else i(s.response);
|
|
}),
|
|
s.addEventListener("error", () => {
|
|
throw new Error(s.status);
|
|
}),
|
|
s.open("GET", e, !0),
|
|
(s.responseType = t),
|
|
s.send();
|
|
} catch (e) {
|
|
s(e);
|
|
}
|
|
});
|
|
}
|
|
function ke(e, t) {
|
|
if (!S.string(e)) return;
|
|
const i = "cache",
|
|
s = S.string(t);
|
|
let n = !1;
|
|
const a = () => null !== document.getElementById(t),
|
|
l = (e, t) => {
|
|
(e.innerHTML = t),
|
|
(s && a()) || document.body.insertAdjacentElement("afterbegin", e);
|
|
};
|
|
if (!s || !a()) {
|
|
const a = we.supported,
|
|
r = document.createElement("div");
|
|
if ((r.setAttribute("hidden", ""), s && r.setAttribute("id", t), a)) {
|
|
const e = window.localStorage.getItem(`${i}-${t}`);
|
|
if (((n = null !== e), n)) {
|
|
const t = JSON.parse(e);
|
|
l(r, t.content);
|
|
}
|
|
}
|
|
Te(e)
|
|
.then((e) => {
|
|
if (!S.empty(e)) {
|
|
if (a)
|
|
try {
|
|
window.localStorage.setItem(
|
|
`${i}-${t}`,
|
|
JSON.stringify({ content: e })
|
|
);
|
|
} catch (e) { }
|
|
l(r, e);
|
|
}
|
|
})
|
|
.catch(() => { });
|
|
}
|
|
}
|
|
const Ce = (e) => Math.trunc((e / 60 / 60) % 60, 10),
|
|
Ae = (e) => Math.trunc((e / 60) % 60, 10),
|
|
Se = (e) => Math.trunc(e % 60, 10);
|
|
function Ee(e = 0, t = !1, i = !1) {
|
|
if (!S.number(e)) return Ee(void 0, t, i);
|
|
const s = (e) => `0${e}`.slice(-2);
|
|
let n = Ce(e);
|
|
const a = Ae(e),
|
|
l = Se(e);
|
|
return (
|
|
(n = t || n > 0 ? `${n}:` : ""),
|
|
`${i && e > 0 ? "-" : ""}${n}${s(a)}:${s(l)}`
|
|
);
|
|
}
|
|
const Pe = {
|
|
getIconUrl() {
|
|
const e = new URL(this.config.iconUrl, window.location),
|
|
t = window.location.host
|
|
? window.location.host
|
|
: window.top.location.host,
|
|
i = e.host !== t || (M.isIE && !window.svg4everybody);
|
|
return { url: this.config.iconUrl, cors: i };
|
|
},
|
|
findElements() {
|
|
try {
|
|
return (
|
|
(this.elements.controls = B.call(
|
|
this,
|
|
this.config.selectors.controls.wrapper
|
|
)),
|
|
(this.elements.buttons = {
|
|
play: U.call(this, this.config.selectors.buttons.play),
|
|
pause: B.call(this, this.config.selectors.buttons.pause),
|
|
restart: B.call(this, this.config.selectors.buttons.restart),
|
|
rewind: B.call(this, this.config.selectors.buttons.rewind),
|
|
fastForward: B.call(
|
|
this,
|
|
this.config.selectors.buttons.fastForward
|
|
),
|
|
mute: B.call(this, this.config.selectors.buttons.mute),
|
|
pip: B.call(this, this.config.selectors.buttons.pip),
|
|
airplay: B.call(this, this.config.selectors.buttons.airplay),
|
|
settings: B.call(this, this.config.selectors.buttons.settings),
|
|
captions: B.call(this, this.config.selectors.buttons.captions),
|
|
fullscreen: B.call(
|
|
this,
|
|
this.config.selectors.buttons.fullscreen
|
|
),
|
|
}),
|
|
(this.elements.progress = B.call(
|
|
this,
|
|
this.config.selectors.progress
|
|
)),
|
|
(this.elements.inputs = {
|
|
seek: B.call(this, this.config.selectors.inputs.seek),
|
|
volume: B.call(this, this.config.selectors.inputs.volume),
|
|
}),
|
|
(this.elements.display = {
|
|
buffer: B.call(this, this.config.selectors.display.buffer),
|
|
currentTime: B.call(
|
|
this,
|
|
this.config.selectors.display.currentTime
|
|
),
|
|
duration: B.call(this, this.config.selectors.display.duration),
|
|
}),
|
|
S.element(this.elements.progress) &&
|
|
(this.elements.display.seekTooltip =
|
|
this.elements.progress.querySelector(
|
|
`.${this.config.classNames.tooltip}`
|
|
)),
|
|
!0
|
|
);
|
|
} catch (e) {
|
|
return (
|
|
this.debug.warn(
|
|
"It looks like there is a problem with your custom controls HTML",
|
|
e
|
|
),
|
|
this.toggleNativeControls(!0),
|
|
!1
|
|
);
|
|
}
|
|
},
|
|
createIcon(e, t) {
|
|
const i = "http://www.w3.org/2000/svg",
|
|
s = Pe.getIconUrl.call(this),
|
|
n = `${s.cors ? "" : s.url}#${this.config.iconPrefix}`,
|
|
a = document.createElementNS(i, "svg");
|
|
I(a, x(t, { "aria-hidden": "true", focusable: "false" }));
|
|
const l = document.createElementNS(i, "use"),
|
|
r = `${n}-${e}`;
|
|
return (
|
|
"href" in l &&
|
|
l.setAttributeNS("http://www.w3.org/1999/xlink", "href", r),
|
|
l.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", r),
|
|
a.appendChild(l),
|
|
a
|
|
);
|
|
},
|
|
createLabel(e, t = {}) {
|
|
const i = ve.get(e, this.config);
|
|
return $(
|
|
"span",
|
|
{
|
|
...t,
|
|
class: [t.class, this.config.classNames.hidden]
|
|
.filter(Boolean)
|
|
.join(" "),
|
|
},
|
|
i
|
|
);
|
|
},
|
|
createBadge(e) {
|
|
if (S.empty(e)) return null;
|
|
const t = $("span", { class: this.config.classNames.menu.value });
|
|
return (
|
|
t.appendChild(
|
|
$("span", { class: this.config.classNames.menu.badge }, e)
|
|
),
|
|
t
|
|
);
|
|
},
|
|
createButton(e, t) {
|
|
const i = x({}, t);
|
|
let s = fe(e);
|
|
const n = {
|
|
element: "button",
|
|
toggle: !1,
|
|
label: null,
|
|
icon: null,
|
|
labelPressed: null,
|
|
iconPressed: null,
|
|
};
|
|
switch (
|
|
(["element", "icon", "label"].forEach((e) => {
|
|
Object.keys(i).includes(e) && ((n[e] = i[e]), delete i[e]);
|
|
}),
|
|
"button" !== n.element ||
|
|
Object.keys(i).includes("type") ||
|
|
(i.type = "button"),
|
|
Object.keys(i).includes("class")
|
|
? i.class
|
|
.split(" ")
|
|
.some((e) => e === this.config.classNames.control) ||
|
|
x(i, { class: `${i.class} ${this.config.classNames.control}` })
|
|
: (i.class = this.config.classNames.control),
|
|
e)
|
|
) {
|
|
case "play":
|
|
(n.toggle = !0),
|
|
(n.label = "play"),
|
|
(n.labelPressed = "pause"),
|
|
(n.icon = "play"),
|
|
(n.iconPressed = "pause");
|
|
break;
|
|
case "mute":
|
|
(n.toggle = !0),
|
|
(n.label = "mute"),
|
|
(n.labelPressed = "unmute"),
|
|
(n.icon = "volume"),
|
|
(n.iconPressed = "muted");
|
|
break;
|
|
case "captions":
|
|
(n.toggle = !0),
|
|
(n.label = "enableCaptions"),
|
|
(n.labelPressed = "disableCaptions"),
|
|
(n.icon = "captions-off"),
|
|
(n.iconPressed = "captions-on");
|
|
break;
|
|
case "fullscreen":
|
|
(n.toggle = !0),
|
|
(n.label = "enterFullscreen"),
|
|
(n.labelPressed = "exitFullscreen"),
|
|
(n.icon = "enter-fullscreen"),
|
|
(n.iconPressed = "exit-fullscreen");
|
|
break;
|
|
case "play-large":
|
|
(i.class += ` ${this.config.classNames.control}--overlaid`),
|
|
(s = "play"),
|
|
(n.label = "play"),
|
|
(n.icon = "play");
|
|
break;
|
|
default:
|
|
S.empty(n.label) && (n.label = s), S.empty(n.icon) && (n.icon = e);
|
|
}
|
|
const a = $(n.element);
|
|
return (
|
|
n.toggle
|
|
? (a.appendChild(
|
|
Pe.createIcon.call(this, n.iconPressed, {
|
|
class: "icon--pressed",
|
|
})
|
|
),
|
|
a.appendChild(
|
|
Pe.createIcon.call(this, n.icon, { class: "icon--not-pressed" })
|
|
),
|
|
a.appendChild(
|
|
Pe.createLabel.call(this, n.labelPressed, {
|
|
class: "label--pressed",
|
|
})
|
|
),
|
|
a.appendChild(
|
|
Pe.createLabel.call(this, n.label, {
|
|
class: "label--not-pressed",
|
|
})
|
|
))
|
|
: (a.appendChild(Pe.createIcon.call(this, n.icon)),
|
|
a.appendChild(Pe.createLabel.call(this, n.label))),
|
|
x(i, D(this.config.selectors.buttons[s], i)),
|
|
I(a, i),
|
|
"play" === s
|
|
? (S.array(this.elements.buttons[s]) ||
|
|
(this.elements.buttons[s] = []),
|
|
this.elements.buttons[s].push(a))
|
|
: (this.elements.buttons[s] = a),
|
|
a
|
|
);
|
|
},
|
|
createRange(e, t) {
|
|
const i = $(
|
|
"input",
|
|
x(
|
|
D(this.config.selectors.inputs[e]),
|
|
{
|
|
type: "range",
|
|
min: 0,
|
|
max: 100,
|
|
step: 0.01,
|
|
value: 0,
|
|
autocomplete: "off",
|
|
role: "slider",
|
|
"aria-label": ve.get(e, this.config),
|
|
"aria-valuemin": 0,
|
|
"aria-valuemax": 100,
|
|
"aria-valuenow": 0,
|
|
},
|
|
t
|
|
)
|
|
);
|
|
return (
|
|
(this.elements.inputs[e] = i),
|
|
Pe.updateRangeFill.call(this, i),
|
|
g.setup(i),
|
|
i
|
|
);
|
|
},
|
|
createProgress(e, t) {
|
|
const i = $(
|
|
"progress",
|
|
x(
|
|
D(this.config.selectors.display[e]),
|
|
{
|
|
min: 0,
|
|
max: 100,
|
|
value: 0,
|
|
role: "progressbar",
|
|
"aria-hidden": !0,
|
|
},
|
|
t
|
|
)
|
|
);
|
|
if ("volume" !== e) {
|
|
i.appendChild($("span", null, "0"));
|
|
const t = { played: "played", buffer: "buffered" }[e],
|
|
s = t ? ve.get(t, this.config) : "";
|
|
i.innerText = `% ${s.toLowerCase()}`;
|
|
}
|
|
return (this.elements.display[e] = i), i;
|
|
},
|
|
createTime(e, t) {
|
|
const i = D(this.config.selectors.display[e], t),
|
|
s = $(
|
|
"div",
|
|
x(i, {
|
|
class: `${i.class ? i.class : ""} ${this.config.classNames.display.time
|
|
} `.trim(),
|
|
"aria-label": ve.get(e, this.config),
|
|
role: "timer",
|
|
}),
|
|
"00:00"
|
|
);
|
|
return (this.elements.display[e] = s), s;
|
|
},
|
|
bindMenuItemShortcuts(e, t) {
|
|
X.call(
|
|
this,
|
|
e,
|
|
"keydown keyup",
|
|
(i) => {
|
|
if (![" ", "ArrowUp", "ArrowDown", "ArrowRight"].includes(i.key))
|
|
return;
|
|
if ((i.preventDefault(), i.stopPropagation(), "keydown" === i.type))
|
|
return;
|
|
const s = V(e, '[role="menuitemradio"]');
|
|
if (!s && [" ", "ArrowRight"].includes(i.key))
|
|
Pe.showMenuPanel.call(this, t, !0);
|
|
else {
|
|
let t;
|
|
" " !== i.key &&
|
|
("ArrowDown" === i.key || (s && "ArrowRight" === i.key)
|
|
? ((t = e.nextElementSibling),
|
|
S.element(t) || (t = e.parentNode.firstElementChild))
|
|
: ((t = e.previousElementSibling),
|
|
S.element(t) || (t = e.parentNode.lastElementChild)),
|
|
W.call(this, t, !0));
|
|
}
|
|
},
|
|
!1
|
|
),
|
|
X.call(this, e, "keyup", (e) => {
|
|
"Return" === e.key && Pe.focusFirstMenuItem.call(this, null, !0);
|
|
});
|
|
},
|
|
createMenuItem({
|
|
value: e,
|
|
list: t,
|
|
type: i,
|
|
title: s,
|
|
badge: n = null,
|
|
checked: a = !1,
|
|
}) {
|
|
const l = D(this.config.selectors.inputs[i]),
|
|
r = $(
|
|
"button",
|
|
x(l, {
|
|
type: "button",
|
|
role: "menuitemradio",
|
|
class: `${this.config.classNames.control} ${l.class ? l.class : ""
|
|
}`.trim(),
|
|
"aria-checked": a,
|
|
value: e,
|
|
})
|
|
),
|
|
o = $("span");
|
|
(o.innerHTML = s),
|
|
S.element(n) && o.appendChild(n),
|
|
r.appendChild(o),
|
|
Object.defineProperty(r, "checked", {
|
|
enumerable: !0,
|
|
get: () => "true" === r.getAttribute("aria-checked"),
|
|
set(e) {
|
|
e &&
|
|
Array.from(r.parentNode.children)
|
|
.filter((e) => V(e, '[role="menuitemradio"]'))
|
|
.forEach((e) => e.setAttribute("aria-checked", "false")),
|
|
r.setAttribute("aria-checked", e ? "true" : "false");
|
|
},
|
|
}),
|
|
this.listeners.bind(
|
|
r,
|
|
"click keyup",
|
|
(t) => {
|
|
if (!S.keyboardEvent(t) || " " === t.key) {
|
|
switch (
|
|
(t.preventDefault(), t.stopPropagation(), (r.checked = !0), i)
|
|
) {
|
|
case "language":
|
|
this.currentTrack = Number(e);
|
|
break;
|
|
case "quality":
|
|
this.quality = e;
|
|
break;
|
|
case "speed":
|
|
this.speed = parseFloat(e);
|
|
}
|
|
Pe.showMenuPanel.call(this, "home", S.keyboardEvent(t));
|
|
}
|
|
},
|
|
i,
|
|
!1
|
|
),
|
|
Pe.bindMenuItemShortcuts.call(this, r, i),
|
|
t.appendChild(r);
|
|
},
|
|
formatTime(e = 0, t = !1) {
|
|
if (!S.number(e)) return e;
|
|
return Ee(e, Ce(this.duration) > 0, t);
|
|
},
|
|
updateTimeDisplay(e = null, t = 0, i = !1) {
|
|
S.element(e) && S.number(t) && (e.innerText = Pe.formatTime(t, i));
|
|
},
|
|
updateVolume() {
|
|
this.supported.ui &&
|
|
(S.element(this.elements.inputs.volume) &&
|
|
Pe.setRange.call(
|
|
this,
|
|
this.elements.inputs.volume,
|
|
this.muted ? 0 : this.volume
|
|
),
|
|
S.element(this.elements.buttons.mute) &&
|
|
(this.elements.buttons.mute.pressed =
|
|
this.muted || 0 === this.volume));
|
|
},
|
|
setRange(e, t = 0) {
|
|
S.element(e) && ((e.value = t), Pe.updateRangeFill.call(this, e));
|
|
},
|
|
updateProgress(e) {
|
|
if (!this.supported.ui || !S.event(e)) return;
|
|
let t = 0;
|
|
const i = (e, t) => {
|
|
const i = S.number(t) ? t : 0,
|
|
s = S.element(e) ? e : this.elements.display.buffer;
|
|
if (S.element(s)) {
|
|
s.value = i;
|
|
const e = s.getElementsByTagName("span")[0];
|
|
S.element(e) && (e.childNodes[0].nodeValue = i);
|
|
}
|
|
};
|
|
if (e)
|
|
switch (e.type) {
|
|
case "timeupdate":
|
|
case "seeking":
|
|
case "seeked":
|
|
(s = this.currentTime),
|
|
(n = this.duration),
|
|
(t =
|
|
0 === s || 0 === n || Number.isNaN(s) || Number.isNaN(n)
|
|
? 0
|
|
: ((s / n) * 100).toFixed(2)),
|
|
"timeupdate" === e.type &&
|
|
Pe.setRange.call(this, this.elements.inputs.seek, t);
|
|
break;
|
|
case "playing":
|
|
case "progress":
|
|
i(this.elements.display.buffer, 100 * this.buffered);
|
|
}
|
|
var s, n;
|
|
},
|
|
updateRangeFill(e) {
|
|
const t = S.event(e) ? e.target : e;
|
|
if (S.element(t) && "range" === t.getAttribute("type")) {
|
|
if (V(t, this.config.selectors.inputs.seek)) {
|
|
t.setAttribute("aria-valuenow", this.currentTime);
|
|
const e = Pe.formatTime(this.currentTime),
|
|
i = Pe.formatTime(this.duration),
|
|
s = ve.get("seekLabel", this.config);
|
|
t.setAttribute(
|
|
"aria-valuetext",
|
|
s.replace("{currentTime}", e).replace("{duration}", i)
|
|
);
|
|
} else if (V(t, this.config.selectors.inputs.volume)) {
|
|
const e = 100 * t.value;
|
|
t.setAttribute("aria-valuenow", e),
|
|
t.setAttribute("aria-valuetext", `${e.toFixed(1)}%`);
|
|
} else t.setAttribute("aria-valuenow", t.value);
|
|
(M.isWebKit || M.isIPadOS) &&
|
|
t.style.setProperty("--value", (t.value / t.max) * 100 + "%");
|
|
}
|
|
},
|
|
updateSeekTooltip(e) {
|
|
var t, i;
|
|
if (
|
|
!this.config.tooltips.seek ||
|
|
!S.element(this.elements.inputs.seek) ||
|
|
!S.element(this.elements.display.seekTooltip) ||
|
|
0 === this.duration
|
|
)
|
|
return;
|
|
const s = this.elements.display.seekTooltip,
|
|
n = `${this.config.classNames.tooltip}--visible`,
|
|
a = (e) => R(s, n, e);
|
|
if (this.touch) return void a(!1);
|
|
let l = 0;
|
|
const r = this.elements.progress.getBoundingClientRect();
|
|
if (S.event(e)) l = (100 / r.width) * (e.pageX - r.left);
|
|
else {
|
|
if (!F(s, n)) return;
|
|
l = parseFloat(s.style.left, 10);
|
|
}
|
|
l < 0 ? (l = 0) : l > 100 && (l = 100);
|
|
const o = (this.duration / 100) * l;
|
|
s.innerText = Pe.formatTime(o);
|
|
const c =
|
|
null === (t = this.config.markers) ||
|
|
void 0 === t ||
|
|
null === (i = t.points) ||
|
|
void 0 === i
|
|
? void 0
|
|
: i.find(({ time: e }) => e === Math.round(o));
|
|
c && s.insertAdjacentHTML("afterbegin", `${c.label}<br>`),
|
|
(s.style.left = `${l}%`),
|
|
S.event(e) &&
|
|
["mouseenter", "mouseleave"].includes(e.type) &&
|
|
a("mouseenter" === e.type);
|
|
},
|
|
timeUpdate(e) {
|
|
const t =
|
|
!S.element(this.elements.display.duration) && this.config.invertTime;
|
|
Pe.updateTimeDisplay.call(
|
|
this,
|
|
this.elements.display.currentTime,
|
|
t ? this.duration - this.currentTime : this.currentTime,
|
|
t
|
|
),
|
|
(e && "timeupdate" === e.type && this.media.seeking) ||
|
|
Pe.updateProgress.call(this, e);
|
|
},
|
|
durationUpdate() {
|
|
if (!this.supported.ui || (!this.config.invertTime && this.currentTime))
|
|
return;
|
|
if (this.duration >= 2 ** 32)
|
|
return (
|
|
H(this.elements.display.currentTime, !0),
|
|
void H(this.elements.progress, !0)
|
|
);
|
|
S.element(this.elements.inputs.seek) &&
|
|
this.elements.inputs.seek.setAttribute(
|
|
"aria-valuemax",
|
|
this.duration
|
|
);
|
|
const e = S.element(this.elements.display.duration);
|
|
!e &&
|
|
this.config.displayDuration &&
|
|
this.paused &&
|
|
Pe.updateTimeDisplay.call(
|
|
this,
|
|
this.elements.display.currentTime,
|
|
this.duration
|
|
),
|
|
e &&
|
|
Pe.updateTimeDisplay.call(
|
|
this,
|
|
this.elements.display.duration,
|
|
this.duration
|
|
),
|
|
this.config.markers.enabled && Pe.setMarkers.call(this),
|
|
Pe.updateSeekTooltip.call(this);
|
|
},
|
|
toggleMenuButton(e, t) {
|
|
H(this.elements.settings.buttons[e], !t);
|
|
},
|
|
updateSetting(e, t, i) {
|
|
const s = this.elements.settings.panels[e];
|
|
let n = null,
|
|
a = t;
|
|
if ("captions" === e) n = this.currentTrack;
|
|
else {
|
|
if (
|
|
((n = S.empty(i) ? this[e] : i),
|
|
S.empty(n) && (n = this.config[e].default),
|
|
!S.empty(this.options[e]) && !this.options[e].includes(n))
|
|
)
|
|
return void this.debug.warn(`Unsupported value of '${n}' for ${e}`);
|
|
if (!this.config[e].options.includes(n))
|
|
return void this.debug.warn(`Disabled value of '${n}' for ${e}`);
|
|
}
|
|
if (
|
|
(S.element(a) || (a = s && s.querySelector('[role="menu"]')),
|
|
!S.element(a))
|
|
)
|
|
return;
|
|
this.elements.settings.buttons[e].querySelector(
|
|
`.${this.config.classNames.menu.value}`
|
|
).innerHTML = Pe.getLabel.call(this, e, n);
|
|
const l = a && a.querySelector(`[value="${n}"]`);
|
|
S.element(l) && (l.checked = !0);
|
|
},
|
|
getLabel(e, t) {
|
|
switch (e) {
|
|
case "speed":
|
|
return 1 === t ? ve.get("normal", this.config) : `${t}×`;
|
|
case "quality":
|
|
if (S.number(t)) {
|
|
const e = ve.get(`qualityLabel.${t}`, this.config);
|
|
return e.length ? e : `${t}p`;
|
|
}
|
|
return ge(t);
|
|
case "captions":
|
|
return xe.getLabel.call(this);
|
|
default:
|
|
return null;
|
|
}
|
|
},
|
|
setQualityMenu(e) {
|
|
if (!S.element(this.elements.settings.panels.quality)) return;
|
|
const t = "quality",
|
|
i =
|
|
this.elements.settings.panels.quality.querySelector(
|
|
'[role="menu"]'
|
|
);
|
|
S.array(e) &&
|
|
(this.options.quality = se(e).filter((e) =>
|
|
this.config.quality.options.includes(e)
|
|
));
|
|
const s =
|
|
!S.empty(this.options.quality) && this.options.quality.length > 1;
|
|
if (
|
|
(Pe.toggleMenuButton.call(this, t, s),
|
|
j(i),
|
|
Pe.checkMenu.call(this),
|
|
!s)
|
|
)
|
|
return;
|
|
const n = (e) => {
|
|
const t = ve.get(`qualityBadge.${e}`, this.config);
|
|
return t.length ? Pe.createBadge.call(this, t) : null;
|
|
};
|
|
this.options.quality
|
|
.sort((e, t) => {
|
|
const i = this.config.quality.options;
|
|
return i.indexOf(e) > i.indexOf(t) ? 1 : -1;
|
|
})
|
|
.forEach((e) => {
|
|
Pe.createMenuItem.call(this, {
|
|
value: e,
|
|
list: i,
|
|
type: t,
|
|
title: Pe.getLabel.call(this, "quality", e),
|
|
badge: n(e),
|
|
});
|
|
}),
|
|
Pe.updateSetting.call(this, t, i);
|
|
},
|
|
setCaptionsMenu() {
|
|
if (!S.element(this.elements.settings.panels.captions)) return;
|
|
const e = "captions",
|
|
t =
|
|
this.elements.settings.panels.captions.querySelector(
|
|
'[role="menu"]'
|
|
),
|
|
i = xe.getTracks.call(this),
|
|
s = Boolean(i.length);
|
|
if (
|
|
(Pe.toggleMenuButton.call(this, e, s),
|
|
j(t),
|
|
Pe.checkMenu.call(this),
|
|
!s)
|
|
)
|
|
return;
|
|
const n = i.map((e, i) => ({
|
|
value: i,
|
|
checked: this.captions.toggled && this.currentTrack === i,
|
|
title: xe.getLabel.call(this, e),
|
|
badge:
|
|
e.language && Pe.createBadge.call(this, e.language.toUpperCase()),
|
|
list: t,
|
|
type: "language",
|
|
}));
|
|
n.unshift({
|
|
value: -1,
|
|
checked: !this.captions.toggled,
|
|
title: ve.get("disabled", this.config),
|
|
list: t,
|
|
type: "language",
|
|
}),
|
|
n.forEach(Pe.createMenuItem.bind(this)),
|
|
Pe.updateSetting.call(this, e, t);
|
|
},
|
|
setSpeedMenu() {
|
|
if (!S.element(this.elements.settings.panels.speed)) return;
|
|
const e = "speed",
|
|
t =
|
|
this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
|
this.options.speed = this.options.speed.filter(
|
|
(e) => e >= this.minimumSpeed && e <= this.maximumSpeed
|
|
);
|
|
const i = !S.empty(this.options.speed) && this.options.speed.length > 1;
|
|
Pe.toggleMenuButton.call(this, e, i),
|
|
j(t),
|
|
Pe.checkMenu.call(this),
|
|
i &&
|
|
(this.options.speed.forEach((i) => {
|
|
Pe.createMenuItem.call(this, {
|
|
value: i,
|
|
list: t,
|
|
type: e,
|
|
title: Pe.getLabel.call(this, "speed", i),
|
|
});
|
|
}),
|
|
Pe.updateSetting.call(this, e, t));
|
|
},
|
|
checkMenu() {
|
|
const { buttons: e } = this.elements.settings,
|
|
t = !S.empty(e) && Object.values(e).some((e) => !e.hidden);
|
|
H(this.elements.settings.menu, !t);
|
|
},
|
|
focusFirstMenuItem(e, t = !1) {
|
|
if (this.elements.settings.popup.hidden) return;
|
|
let i = e;
|
|
S.element(i) ||
|
|
(i = Object.values(this.elements.settings.panels).find(
|
|
(e) => !e.hidden
|
|
));
|
|
const s = i.querySelector('[role^="menuitem"]');
|
|
W.call(this, s, t);
|
|
},
|
|
toggleMenu(e) {
|
|
const { popup: t } = this.elements.settings,
|
|
i = this.elements.buttons.settings;
|
|
if (!S.element(t) || !S.element(i)) return;
|
|
const { hidden: s } = t;
|
|
let n = s;
|
|
if (S.boolean(e)) n = e;
|
|
else if (S.keyboardEvent(e) && "Escape" === e.key) n = !1;
|
|
else if (S.event(e)) {
|
|
const s = S.function(e.composedPath) ? e.composedPath()[0] : e.target,
|
|
a = t.contains(s);
|
|
if (a || (!a && e.target !== i && n)) return;
|
|
}
|
|
i.setAttribute("aria-expanded", n),
|
|
H(t, !n),
|
|
R(this.elements.container, this.config.classNames.menu.open, n),
|
|
n && S.keyboardEvent(e)
|
|
? Pe.focusFirstMenuItem.call(this, null, !0)
|
|
: n || s || W.call(this, i, S.keyboardEvent(e));
|
|
},
|
|
getMenuSize(e) {
|
|
const t = e.cloneNode(!0);
|
|
(t.style.position = "absolute"),
|
|
(t.style.opacity = 0),
|
|
t.removeAttribute("hidden"),
|
|
e.parentNode.appendChild(t);
|
|
const i = t.scrollWidth,
|
|
s = t.scrollHeight;
|
|
return O(t), { width: i, height: s };
|
|
},
|
|
showMenuPanel(e = "", t = !1) {
|
|
const i = this.elements.container.querySelector(
|
|
`#plyr-settings-${this.id}-${e}`
|
|
);
|
|
if (!S.element(i)) return;
|
|
const s = i.parentNode,
|
|
n = Array.from(s.children).find((e) => !e.hidden);
|
|
if (K.transitions && !K.reducedMotion) {
|
|
(s.style.width = `${n.scrollWidth}px`),
|
|
(s.style.height = `${n.scrollHeight}px`);
|
|
const e = Pe.getMenuSize.call(this, i),
|
|
t = (e) => {
|
|
e.target === s &&
|
|
["width", "height"].includes(e.propertyName) &&
|
|
((s.style.width = ""),
|
|
(s.style.height = ""),
|
|
J.call(this, s, E, t));
|
|
};
|
|
X.call(this, s, E, t),
|
|
(s.style.width = `${e.width}px`),
|
|
(s.style.height = `${e.height}px`);
|
|
}
|
|
H(n, !0), H(i, !1), Pe.focusFirstMenuItem.call(this, i, t);
|
|
},
|
|
setDownloadUrl() {
|
|
const e = this.elements.buttons.download;
|
|
S.element(e) && e.setAttribute("href", this.download);
|
|
},
|
|
create(e) {
|
|
const {
|
|
bindMenuItemShortcuts: t,
|
|
createButton: i,
|
|
createProgress: s,
|
|
createRange: n,
|
|
createTime: a,
|
|
setQualityMenu: l,
|
|
setSpeedMenu: r,
|
|
showMenuPanel: o,
|
|
} = Pe;
|
|
(this.elements.controls = null),
|
|
S.array(this.config.controls) &&
|
|
this.config.controls.includes("play-large") &&
|
|
this.elements.container.appendChild(i.call(this, "play-large"));
|
|
const c = $("div", D(this.config.selectors.controls.wrapper));
|
|
this.elements.controls = c;
|
|
const u = { class: "plyr__controls__item" };
|
|
return (
|
|
se(S.array(this.config.controls) ? this.config.controls : []).forEach(
|
|
(l) => {
|
|
if (
|
|
("restart" === l && c.appendChild(i.call(this, "restart", u)),
|
|
"rewind" === l && c.appendChild(i.call(this, "rewind", u)),
|
|
"play" === l && c.appendChild(i.call(this, "play", u)),
|
|
"fast-forward" === l &&
|
|
c.appendChild(i.call(this, "fast-forward", u)),
|
|
"progress" === l)
|
|
) {
|
|
const t = $("div", {
|
|
class: `${u.class} plyr__progress__container`,
|
|
}),
|
|
i = $("div", D(this.config.selectors.progress));
|
|
if (
|
|
(i.appendChild(
|
|
n.call(this, "seek", { id: `plyr-seek-${e.id}` })
|
|
),
|
|
i.appendChild(s.call(this, "buffer")),
|
|
this.config.tooltips.seek)
|
|
) {
|
|
const e = $(
|
|
"span",
|
|
{ class: this.config.classNames.tooltip },
|
|
"00:00"
|
|
);
|
|
i.appendChild(e), (this.elements.display.seekTooltip = e);
|
|
}
|
|
(this.elements.progress = i),
|
|
t.appendChild(this.elements.progress),
|
|
c.appendChild(t);
|
|
}
|
|
if (
|
|
("current-time" === l &&
|
|
c.appendChild(a.call(this, "currentTime", u)),
|
|
"duration" === l && c.appendChild(a.call(this, "duration", u)),
|
|
"mute" === l || "volume" === l)
|
|
) {
|
|
let { volume: t } = this.elements;
|
|
if (
|
|
((S.element(t) && c.contains(t)) ||
|
|
((t = $(
|
|
"div",
|
|
x({}, u, { class: `${u.class} plyr__volume`.trim() })
|
|
)),
|
|
(this.elements.volume = t),
|
|
c.appendChild(t)),
|
|
"mute" === l && t.appendChild(i.call(this, "mute")),
|
|
"volume" === l && !M.isIos && !M.isIPadOS)
|
|
) {
|
|
const i = { max: 1, step: 0.05, value: this.config.volume };
|
|
t.appendChild(
|
|
n.call(this, "volume", x(i, { id: `plyr-volume-${e.id}` }))
|
|
);
|
|
}
|
|
}
|
|
if (
|
|
("captions" === l && c.appendChild(i.call(this, "captions", u)),
|
|
"settings" === l && !S.empty(this.config.settings))
|
|
) {
|
|
const s = $(
|
|
"div",
|
|
x({}, u, {
|
|
class: `${u.class} plyr__menu`.trim(),
|
|
hidden: "",
|
|
})
|
|
);
|
|
s.appendChild(
|
|
i.call(this, "settings", {
|
|
"aria-haspopup": !0,
|
|
"aria-controls": `plyr-settings-${e.id}`,
|
|
"aria-expanded": !1,
|
|
})
|
|
);
|
|
const n = $("div", {
|
|
class: "plyr__menu__container",
|
|
id: `plyr-settings-${e.id}`,
|
|
hidden: "",
|
|
}),
|
|
a = $("div"),
|
|
l = $("div", { id: `plyr-settings-${e.id}-home` }),
|
|
r = $("div", { role: "menu" });
|
|
l.appendChild(r),
|
|
a.appendChild(l),
|
|
(this.elements.settings.panels.home = l),
|
|
this.config.settings.forEach((i) => {
|
|
const s = $(
|
|
"button",
|
|
x(D(this.config.selectors.buttons.settings), {
|
|
type: "button",
|
|
class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,
|
|
role: "menuitem",
|
|
"aria-haspopup": !0,
|
|
hidden: "",
|
|
})
|
|
);
|
|
t.call(this, s, i),
|
|
X.call(this, s, "click", () => {
|
|
o.call(this, i, !1);
|
|
});
|
|
const n = $("span", null, ve.get(i, this.config)),
|
|
l = $("span", {
|
|
class: this.config.classNames.menu.value,
|
|
});
|
|
(l.innerHTML = e[i]),
|
|
n.appendChild(l),
|
|
s.appendChild(n),
|
|
r.appendChild(s);
|
|
const c = $("div", {
|
|
id: `plyr-settings-${e.id}-${i}`,
|
|
hidden: "",
|
|
}),
|
|
u = $("button", {
|
|
type: "button",
|
|
class: `${this.config.classNames.control} ${this.config.classNames.control}--back`,
|
|
});
|
|
u.appendChild(
|
|
$("span", { "aria-hidden": !0 }, ve.get(i, this.config))
|
|
),
|
|
u.appendChild(
|
|
$(
|
|
"span",
|
|
{ class: this.config.classNames.hidden },
|
|
ve.get("menuBack", this.config)
|
|
)
|
|
),
|
|
X.call(
|
|
this,
|
|
c,
|
|
"keydown",
|
|
(e) => {
|
|
"ArrowLeft" === e.key &&
|
|
(e.preventDefault(),
|
|
e.stopPropagation(),
|
|
o.call(this, "home", !0));
|
|
},
|
|
!1
|
|
),
|
|
X.call(this, u, "click", () => {
|
|
o.call(this, "home", !1);
|
|
}),
|
|
c.appendChild(u),
|
|
c.appendChild($("div", { role: "menu" })),
|
|
a.appendChild(c),
|
|
(this.elements.settings.buttons[i] = s),
|
|
(this.elements.settings.panels[i] = c);
|
|
}),
|
|
n.appendChild(a),
|
|
s.appendChild(n),
|
|
c.appendChild(s),
|
|
(this.elements.settings.popup = n),
|
|
(this.elements.settings.menu = s);
|
|
}
|
|
if (
|
|
("pip" === l && K.pip && c.appendChild(i.call(this, "pip", u)),
|
|
"airplay" === l &&
|
|
K.airplay &&
|
|
c.appendChild(i.call(this, "airplay", u)),
|
|
"download" === l)
|
|
) {
|
|
const e = x({}, u, {
|
|
element: "a",
|
|
href: this.download,
|
|
target: "_blank",
|
|
});
|
|
this.isHTML5 && (e.download = "");
|
|
const { download: t } = this.config.urls;
|
|
!S.url(t) &&
|
|
this.isEmbed &&
|
|
x(e, { icon: `logo-${this.provider}`, label: this.provider }),
|
|
c.appendChild(i.call(this, "download", e));
|
|
}
|
|
"fullscreen" === l &&
|
|
c.appendChild(i.call(this, "fullscreen", u));
|
|
}
|
|
),
|
|
this.isHTML5 && l.call(this, de.getQualityOptions.call(this)),
|
|
r.call(this),
|
|
c
|
|
);
|
|
},
|
|
inject() {
|
|
if (this.config.loadSprite) {
|
|
const e = Pe.getIconUrl.call(this);
|
|
e.cors && ke(e.url, "sprite-plyr");
|
|
}
|
|
this.id = Math.floor(1e4 * Math.random());
|
|
let e = null;
|
|
this.elements.controls = null;
|
|
const t = {
|
|
id: this.id,
|
|
seektime: this.config.seekTime,
|
|
title: this.config.title,
|
|
};
|
|
let i = !0;
|
|
S.function(this.config.controls) &&
|
|
(this.config.controls = this.config.controls.call(this, t)),
|
|
this.config.controls || (this.config.controls = []),
|
|
S.element(this.config.controls) || S.string(this.config.controls)
|
|
? (e = this.config.controls)
|
|
: ((e = Pe.create.call(this, {
|
|
id: this.id,
|
|
seektime: this.config.seekTime,
|
|
speed: this.speed,
|
|
quality: this.quality,
|
|
captions: xe.getLabel.call(this),
|
|
})),
|
|
(i = !1));
|
|
let s;
|
|
i &&
|
|
S.string(this.config.controls) &&
|
|
(e = ((e) => {
|
|
let i = e;
|
|
return (
|
|
Object.entries(t).forEach(([e, t]) => {
|
|
i = pe(i, `{${e}}`, t);
|
|
}),
|
|
i
|
|
);
|
|
})(e)),
|
|
S.string(this.config.selectors.controls.container) &&
|
|
(s = document.querySelector(
|
|
this.config.selectors.controls.container
|
|
)),
|
|
S.element(s) || (s = this.elements.container);
|
|
if (
|
|
(s[S.element(e) ? "insertAdjacentElement" : "insertAdjacentHTML"](
|
|
"afterbegin",
|
|
e
|
|
),
|
|
S.element(this.elements.controls) || Pe.findElements.call(this),
|
|
!S.empty(this.elements.buttons))
|
|
) {
|
|
const e = (e) => {
|
|
const t = this.config.classNames.controlPressed;
|
|
e.setAttribute("aria-pressed", "false"),
|
|
Object.defineProperty(e, "pressed", {
|
|
configurable: !0,
|
|
enumerable: !0,
|
|
get: () => F(e, t),
|
|
set(i = !1) {
|
|
R(e, t, i),
|
|
e.setAttribute("aria-pressed", i ? "true" : "false");
|
|
},
|
|
});
|
|
};
|
|
Object.values(this.elements.buttons)
|
|
.filter(Boolean)
|
|
.forEach((t) => {
|
|
S.array(t) || S.nodeList(t)
|
|
? Array.from(t).filter(Boolean).forEach(e)
|
|
: e(t);
|
|
});
|
|
}
|
|
if ((M.isEdge && P(s), this.config.tooltips.controls)) {
|
|
const { classNames: e, selectors: t } = this.config,
|
|
i = `${t.controls.wrapper} ${t.labels} .${e.hidden}`,
|
|
s = U.call(this, i);
|
|
Array.from(s).forEach((e) => {
|
|
R(e, this.config.classNames.hidden, !1),
|
|
R(e, this.config.classNames.tooltip, !0);
|
|
});
|
|
}
|
|
},
|
|
setMediaMetadata() {
|
|
try {
|
|
"mediaSession" in navigator &&
|
|
(navigator.mediaSession.metadata = new window.MediaMetadata({
|
|
title: this.config.mediaMetadata.title,
|
|
artist: this.config.mediaMetadata.artist,
|
|
album: this.config.mediaMetadata.album,
|
|
artwork: this.config.mediaMetadata.artwork,
|
|
}));
|
|
} catch (e) { }
|
|
},
|
|
setMarkers() {
|
|
var e, t;
|
|
if (!this.duration || this.elements.markers) return;
|
|
const i =
|
|
null === (e = this.config.markers) ||
|
|
void 0 === e ||
|
|
null === (t = e.points) ||
|
|
void 0 === t
|
|
? void 0
|
|
: t.filter(({ time: e }) => e > 0 && e < this.duration);
|
|
if (null == i || !i.length) return;
|
|
const s = document.createDocumentFragment(),
|
|
n = document.createDocumentFragment();
|
|
let a = null;
|
|
const l = `${this.config.classNames.tooltip}--visible`,
|
|
r = (e) => R(a, l, e);
|
|
i.forEach((e) => {
|
|
const t = $("span", { class: this.config.classNames.marker }, ""),
|
|
i = (e.time / this.duration) * 100 + "%";
|
|
a &&
|
|
(t.addEventListener("mouseenter", () => {
|
|
e.label || ((a.style.left = i), (a.innerHTML = e.label), r(!0));
|
|
}),
|
|
t.addEventListener("mouseleave", () => {
|
|
r(!1);
|
|
})),
|
|
t.addEventListener("click", () => {
|
|
this.currentTime = e.time;
|
|
}),
|
|
(t.style.left = i),
|
|
n.appendChild(t);
|
|
}),
|
|
s.appendChild(n),
|
|
this.config.tooltips.seek ||
|
|
((a = $("span", { class: this.config.classNames.tooltip }, "")),
|
|
s.appendChild(a)),
|
|
(this.elements.markers = { points: n, tip: a }),
|
|
this.elements.progress.appendChild(s);
|
|
},
|
|
};
|
|
function Me(e, t = !0) {
|
|
let i = e;
|
|
if (t) {
|
|
const e = document.createElement("a");
|
|
(e.href = i), (i = e.href);
|
|
}
|
|
try {
|
|
return new URL(i);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
function Ne(e) {
|
|
const t = new URLSearchParams();
|
|
return (
|
|
S.object(e) &&
|
|
Object.entries(e).forEach(([e, i]) => {
|
|
t.set(e, i);
|
|
}),
|
|
t
|
|
);
|
|
}
|
|
const xe = {
|
|
setup() {
|
|
if (!this.supported.ui) return;
|
|
if (
|
|
!this.isVideo ||
|
|
this.isYouTube ||
|
|
(this.isHTML5 && !K.textTracks)
|
|
)
|
|
return void (
|
|
S.array(this.config.controls) &&
|
|
this.config.controls.includes("settings") &&
|
|
this.config.settings.includes("captions") &&
|
|
Pe.setCaptionsMenu.call(this)
|
|
);
|
|
var e, t;
|
|
if (
|
|
(S.element(this.elements.captions) ||
|
|
((this.elements.captions = $(
|
|
"div",
|
|
D(this.config.selectors.captions)
|
|
)),
|
|
this.elements.captions.setAttribute("dir", "auto"),
|
|
(e = this.elements.captions),
|
|
(t = this.elements.wrapper),
|
|
S.element(e) &&
|
|
S.element(t) &&
|
|
t.parentNode.insertBefore(e, t.nextSibling)),
|
|
M.isIE && window.URL)
|
|
) {
|
|
const e = this.media.querySelectorAll("track");
|
|
Array.from(e).forEach((e) => {
|
|
const t = e.getAttribute("src"),
|
|
i = Me(t);
|
|
null !== i &&
|
|
i.hostname !== window.location.href.hostname &&
|
|
["http:", "https:"].includes(i.protocol) &&
|
|
Te(t, "blob")
|
|
.then((t) => {
|
|
e.setAttribute("src", window.URL.createObjectURL(t));
|
|
})
|
|
.catch(() => {
|
|
O(e);
|
|
});
|
|
});
|
|
}
|
|
const i = se(
|
|
(
|
|
navigator.languages || [
|
|
navigator.language || navigator.userLanguage || "en",
|
|
]
|
|
).map((e) => e.split("-")[0])
|
|
);
|
|
let s = (
|
|
this.storage.get("language") ||
|
|
this.config.captions.language ||
|
|
"auto"
|
|
).toLowerCase();
|
|
"auto" === s && ([s] = i);
|
|
let n = this.storage.get("captions");
|
|
if (
|
|
(S.boolean(n) || ({ active: n } = this.config.captions),
|
|
Object.assign(this.captions, {
|
|
toggled: !1,
|
|
active: n,
|
|
language: s,
|
|
languages: i,
|
|
}),
|
|
this.isHTML5)
|
|
) {
|
|
const e = this.config.captions.update
|
|
? "addtrack removetrack"
|
|
: "removetrack";
|
|
X.call(this, this.media.textTracks, e, xe.update.bind(this));
|
|
}
|
|
setTimeout(xe.update.bind(this), 0);
|
|
},
|
|
update() {
|
|
const e = xe.getTracks.call(this, !0),
|
|
{
|
|
active: t,
|
|
language: i,
|
|
meta: s,
|
|
currentTrackNode: n,
|
|
} = this.captions,
|
|
a = Boolean(e.find((e) => e.language === i));
|
|
this.isHTML5 &&
|
|
this.isVideo &&
|
|
e
|
|
.filter((e) => !s.get(e))
|
|
.forEach((e) => {
|
|
this.debug.log("Track added", e),
|
|
s.set(e, { default: "showing" === e.mode }),
|
|
"showing" === e.mode && (e.mode = "hidden"),
|
|
X.call(this, e, "cuechange", () => xe.updateCues.call(this));
|
|
}),
|
|
((a && this.language !== i) || !e.includes(n)) &&
|
|
(xe.setLanguage.call(this, i), xe.toggle.call(this, t && a)),
|
|
this.elements &&
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.captions.enabled,
|
|
!S.empty(e)
|
|
),
|
|
S.array(this.config.controls) &&
|
|
this.config.controls.includes("settings") &&
|
|
this.config.settings.includes("captions") &&
|
|
Pe.setCaptionsMenu.call(this);
|
|
},
|
|
toggle(e, t = !0) {
|
|
if (!this.supported.ui) return;
|
|
const { toggled: i } = this.captions,
|
|
s = this.config.classNames.captions.active,
|
|
n = S.nullOrUndefined(e) ? !i : e;
|
|
if (n !== i) {
|
|
if (
|
|
(t ||
|
|
((this.captions.active = n), this.storage.set({ captions: n })),
|
|
!this.language && n && !t)
|
|
) {
|
|
const e = xe.getTracks.call(this),
|
|
t = xe.findTrack.call(
|
|
this,
|
|
[this.captions.language, ...this.captions.languages],
|
|
!0
|
|
);
|
|
return (
|
|
(this.captions.language = t.language),
|
|
void xe.set.call(this, e.indexOf(t))
|
|
);
|
|
}
|
|
this.elements.buttons.captions &&
|
|
(this.elements.buttons.captions.pressed = n),
|
|
R(this.elements.container, s, n),
|
|
(this.captions.toggled = n),
|
|
Pe.updateSetting.call(this, "captions"),
|
|
Z.call(
|
|
this,
|
|
this.media,
|
|
n ? "captionsenabled" : "captionsdisabled"
|
|
);
|
|
}
|
|
setTimeout(() => {
|
|
n &&
|
|
this.captions.toggled &&
|
|
(this.captions.currentTrackNode.mode = "hidden");
|
|
});
|
|
},
|
|
set(e, t = !0) {
|
|
const i = xe.getTracks.call(this);
|
|
if (-1 !== e)
|
|
if (S.number(e))
|
|
if (e in i) {
|
|
if (this.captions.currentTrack !== e) {
|
|
this.captions.currentTrack = e;
|
|
const s = i[e],
|
|
{ language: n } = s || {};
|
|
(this.captions.currentTrackNode = s),
|
|
Pe.updateSetting.call(this, "captions"),
|
|
t ||
|
|
((this.captions.language = n),
|
|
this.storage.set({ language: n })),
|
|
this.isVimeo && this.embed.enableTextTrack(n),
|
|
Z.call(this, this.media, "languagechange");
|
|
}
|
|
xe.toggle.call(this, !0, t),
|
|
this.isHTML5 && this.isVideo && xe.updateCues.call(this);
|
|
} else this.debug.warn("Track not found", e);
|
|
else this.debug.warn("Invalid caption argument", e);
|
|
else xe.toggle.call(this, !1, t);
|
|
},
|
|
setLanguage(e, t = !0) {
|
|
if (!S.string(e))
|
|
return void this.debug.warn("Invalid language argument", e);
|
|
const i = e.toLowerCase();
|
|
this.captions.language = i;
|
|
const s = xe.getTracks.call(this),
|
|
n = xe.findTrack.call(this, [i]);
|
|
xe.set.call(this, s.indexOf(n), t);
|
|
},
|
|
getTracks(e = !1) {
|
|
return Array.from((this.media || {}).textTracks || [])
|
|
.filter((t) => !this.isHTML5 || e || this.captions.meta.has(t))
|
|
.filter((e) => ["captions", "subtitles"].includes(e.kind));
|
|
},
|
|
findTrack(e, t = !1) {
|
|
const i = xe.getTracks.call(this),
|
|
s = (e) => Number((this.captions.meta.get(e) || {}).default),
|
|
n = Array.from(i).sort((e, t) => s(t) - s(e));
|
|
let a;
|
|
return (
|
|
e.every((e) => ((a = n.find((t) => t.language === e)), !a)),
|
|
a || (t ? n[0] : void 0)
|
|
);
|
|
},
|
|
getCurrentTrack() {
|
|
return xe.getTracks.call(this)[this.currentTrack];
|
|
},
|
|
getLabel(e) {
|
|
let t = e;
|
|
return (
|
|
!S.track(t) &&
|
|
K.textTracks &&
|
|
this.captions.toggled &&
|
|
(t = xe.getCurrentTrack.call(this)),
|
|
S.track(t)
|
|
? S.empty(t.label)
|
|
? S.empty(t.language)
|
|
? ve.get("enabled", this.config)
|
|
: e.language.toUpperCase()
|
|
: t.label
|
|
: ve.get("disabled", this.config)
|
|
);
|
|
},
|
|
updateCues(e) {
|
|
if (!this.supported.ui) return;
|
|
if (!S.element(this.elements.captions))
|
|
return void this.debug.warn("No captions element to render to");
|
|
if (!S.nullOrUndefined(e) && !Array.isArray(e))
|
|
return void this.debug.warn("updateCues: Invalid input", e);
|
|
let t = e;
|
|
if (!t) {
|
|
const e = xe.getCurrentTrack.call(this);
|
|
t = Array.from((e || {}).activeCues || [])
|
|
.map((e) => e.getCueAsHTML())
|
|
.map(ye);
|
|
}
|
|
const i = t.map((e) => e.trim()).join("\n");
|
|
if (i !== this.elements.captions.innerHTML) {
|
|
j(this.elements.captions);
|
|
const e = $("span", D(this.config.selectors.caption));
|
|
(e.innerHTML = i),
|
|
this.elements.captions.appendChild(e),
|
|
Z.call(this, this.media, "cuechange");
|
|
}
|
|
},
|
|
},
|
|
Le = {
|
|
enabled: !0,
|
|
title: "",
|
|
debug: !1,
|
|
autoplay: !1,
|
|
autopause: !0,
|
|
playsinline: !0,
|
|
seekTime: 10,
|
|
volume: 1,
|
|
muted: !1,
|
|
duration: null,
|
|
displayDuration: !0,
|
|
invertTime: !0,
|
|
toggleInvert: !0,
|
|
ratio: null,
|
|
clickToPlay: !0,
|
|
hideControls: !0,
|
|
resetOnEnd: !1,
|
|
disableContextMenu: !0,
|
|
loadSprite: !0,
|
|
iconPrefix: "plyr",
|
|
iconUrl: "https://cdn.plyr.io/3.7.8/plyr.svg",
|
|
blankVideo: "https://cdn.plyr.io/static/blank.mp4",
|
|
quality: {
|
|
default: 576,
|
|
options: [4320, 2880, 2160, 1440, 1080, 720, 576, 480, 360, 240],
|
|
forced: !1,
|
|
onChange: null,
|
|
},
|
|
loop: { active: !1 },
|
|
speed: { selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 4] },
|
|
keyboard: { focused: !0, global: !1 },
|
|
tooltips: { controls: !1, seek: !0 },
|
|
captions: { active: !1, language: "auto", update: !1 },
|
|
fullscreen: { enabled: !0, fallback: !0, iosNative: !1 },
|
|
storage: { enabled: !0, key: "plyr" },
|
|
controls: [
|
|
"play-large",
|
|
"play",
|
|
"progress",
|
|
"current-time",
|
|
"mute",
|
|
"volume",
|
|
"captions",
|
|
"settings",
|
|
"pip",
|
|
"airplay",
|
|
"fullscreen",
|
|
],
|
|
settings: ["captions", "quality", "speed"],
|
|
i18n: {
|
|
restart: "Restart",
|
|
rewind: "Rewind {seektime}s",
|
|
play: "Play",
|
|
pause: "Pause",
|
|
fastForward: "Forward {seektime}s",
|
|
seek: "Seek",
|
|
seekLabel: "{currentTime} of {duration}",
|
|
played: "Played",
|
|
buffered: "Buffered",
|
|
currentTime: "Current time",
|
|
duration: "Duration",
|
|
volume: "Volume",
|
|
mute: "Mute",
|
|
unmute: "Unmute",
|
|
enableCaptions: "Enable captions",
|
|
disableCaptions: "Disable captions",
|
|
download: "Download",
|
|
enterFullscreen: "Enter fullscreen",
|
|
exitFullscreen: "Exit fullscreen",
|
|
frameTitle: "Player for {title}",
|
|
captions: "Captions",
|
|
settings: "Settings",
|
|
pip: "PIP",
|
|
menuBack: "Go back to previous menu",
|
|
speed: "Speed",
|
|
normal: "Normal",
|
|
quality: "Quality",
|
|
loop: "Loop",
|
|
start: "Start",
|
|
end: "End",
|
|
all: "All",
|
|
reset: "Reset",
|
|
disabled: "Disabled",
|
|
enabled: "Enabled",
|
|
advertisement: "Ad",
|
|
qualityBadge: {
|
|
2160: "4K",
|
|
1440: "HD",
|
|
1080: "HD",
|
|
720: "HD",
|
|
576: "SD",
|
|
480: "SD",
|
|
},
|
|
},
|
|
urls: {
|
|
download: null,
|
|
vimeo: {
|
|
sdk: "https://player.vimeo.com/api/player.js",
|
|
iframe: "https://player.vimeo.com/video/{0}?{1}",
|
|
api: "https://vimeo.com/api/oembed.json?url={0}",
|
|
},
|
|
youtube: {
|
|
sdk: "https://www.youtube.com/iframe_api",
|
|
api: "https://noembed.com/embed?url=https://www.youtube.com/watch?v={0}",
|
|
},
|
|
googleIMA: {
|
|
sdk: "https://imasdk.googleapis.com/js/sdkloader/ima3.js",
|
|
},
|
|
},
|
|
listeners: {
|
|
seek: null,
|
|
play: null,
|
|
pause: null,
|
|
restart: null,
|
|
rewind: null,
|
|
fastForward: null,
|
|
mute: null,
|
|
volume: null,
|
|
captions: null,
|
|
download: null,
|
|
fullscreen: null,
|
|
pip: null,
|
|
airplay: null,
|
|
speed: null,
|
|
quality: null,
|
|
loop: null,
|
|
language: null,
|
|
},
|
|
events: [
|
|
"ended",
|
|
"progress",
|
|
"stalled",
|
|
"playing",
|
|
"waiting",
|
|
"canplay",
|
|
"canplaythrough",
|
|
"loadstart",
|
|
"loadeddata",
|
|
"loadedmetadata",
|
|
"timeupdate",
|
|
"volumechange",
|
|
"play",
|
|
"pause",
|
|
"error",
|
|
"seeking",
|
|
"seeked",
|
|
"emptied",
|
|
"ratechange",
|
|
"cuechange",
|
|
"download",
|
|
"enterfullscreen",
|
|
"exitfullscreen",
|
|
"captionsenabled",
|
|
"captionsdisabled",
|
|
"languagechange",
|
|
"controlshidden",
|
|
"controlsshown",
|
|
"ready",
|
|
"statechange",
|
|
"qualitychange",
|
|
"adsloaded",
|
|
"adscontentpause",
|
|
"adscontentresume",
|
|
"adstarted",
|
|
"adsmidpoint",
|
|
"adscomplete",
|
|
"adsallcomplete",
|
|
"adsimpression",
|
|
"adsclick",
|
|
],
|
|
selectors: {
|
|
editable: "input, textarea, select, [contenteditable]",
|
|
container: ".plyr",
|
|
controls: { container: null, wrapper: ".plyr__controls" },
|
|
labels: "[data-plyr]",
|
|
buttons: {
|
|
play: '[data-plyr="play"]',
|
|
pause: '[data-plyr="pause"]',
|
|
restart: '[data-plyr="restart"]',
|
|
rewind: '[data-plyr="rewind"]',
|
|
fastForward: '[data-plyr="fast-forward"]',
|
|
mute: '[data-plyr="mute"]',
|
|
captions: '[data-plyr="captions"]',
|
|
download: '[data-plyr="download"]',
|
|
fullscreen: '[data-plyr="fullscreen"]',
|
|
pip: '[data-plyr="pip"]',
|
|
airplay: '[data-plyr="airplay"]',
|
|
settings: '[data-plyr="settings"]',
|
|
loop: '[data-plyr="loop"]',
|
|
},
|
|
inputs: {
|
|
seek: '[data-plyr="seek"]',
|
|
volume: '[data-plyr="volume"]',
|
|
speed: '[data-plyr="speed"]',
|
|
language: '[data-plyr="language"]',
|
|
quality: '[data-plyr="quality"]',
|
|
},
|
|
display: {
|
|
currentTime: ".plyr__time--current",
|
|
duration: ".plyr__time--duration",
|
|
buffer: ".plyr__progress__buffer",
|
|
loop: ".plyr__progress__loop",
|
|
volume: ".plyr__volume--display",
|
|
},
|
|
progress: ".plyr__progress",
|
|
captions: ".plyr__captions",
|
|
caption: ".plyr__caption",
|
|
},
|
|
classNames: {
|
|
type: "plyr--{0}",
|
|
provider: "plyr--{0}",
|
|
video: "plyr__video-wrapper",
|
|
embed: "plyr__video-embed",
|
|
videoFixedRatio: "plyr__video-wrapper--fixed-ratio",
|
|
embedContainer: "plyr__video-embed__container",
|
|
poster: "plyr__poster",
|
|
posterEnabled: "plyr__poster-enabled",
|
|
ads: "plyr__ads",
|
|
control: "plyr__control",
|
|
controlPressed: "plyr__control--pressed",
|
|
playing: "plyr--playing",
|
|
paused: "plyr--paused",
|
|
stopped: "plyr--stopped",
|
|
loading: "plyr--loading",
|
|
hover: "plyr--hover",
|
|
tooltip: "plyr__tooltip",
|
|
cues: "plyr__cues",
|
|
marker: "plyr__progress__marker",
|
|
hidden: "plyr__sr-only",
|
|
hideControls: "plyr--hide-controls",
|
|
isTouch: "plyr--is-touch",
|
|
uiSupported: "plyr--full-ui",
|
|
noTransition: "plyr--no-transition",
|
|
display: { time: "plyr__time" },
|
|
menu: {
|
|
value: "plyr__menu__value",
|
|
badge: "plyr__badge",
|
|
open: "plyr--menu-open",
|
|
},
|
|
captions: {
|
|
enabled: "plyr--captions-enabled",
|
|
active: "plyr--captions-active",
|
|
},
|
|
fullscreen: {
|
|
enabled: "plyr--fullscreen-enabled",
|
|
fallback: "plyr--fullscreen-fallback",
|
|
},
|
|
pip: { supported: "plyr--pip-supported", active: "plyr--pip-active" },
|
|
airplay: {
|
|
supported: "plyr--airplay-supported",
|
|
active: "plyr--airplay-active",
|
|
},
|
|
previewThumbnails: {
|
|
thumbContainer: "plyr__preview-thumb",
|
|
thumbContainerShown: "plyr__preview-thumb--is-shown",
|
|
imageContainer: "plyr__preview-thumb__image-container",
|
|
timeContainer: "plyr__preview-thumb__time-container",
|
|
scrubbingContainer: "plyr__preview-scrubbing",
|
|
scrubbingContainerShown: "plyr__preview-scrubbing--is-shown",
|
|
},
|
|
},
|
|
attributes: {
|
|
embed: {
|
|
provider: "data-plyr-provider",
|
|
id: "data-plyr-embed-id",
|
|
hash: "data-plyr-embed-hash",
|
|
},
|
|
},
|
|
ads: { enabled: !1, publisherId: "", tagUrl: "" },
|
|
previewThumbnails: { enabled: !1, src: "" },
|
|
vimeo: {
|
|
byline: !1,
|
|
portrait: !1,
|
|
title: !1,
|
|
speed: !0,
|
|
transparent: !1,
|
|
customControls: !0,
|
|
referrerPolicy: null,
|
|
premium: !1,
|
|
},
|
|
youtube: {
|
|
rel: 0,
|
|
showinfo: 0,
|
|
iv_load_policy: 3,
|
|
modestbranding: 1,
|
|
customControls: !0,
|
|
noCookie: !1,
|
|
},
|
|
mediaMetadata: { title: "", artist: "", album: "", artwork: [] },
|
|
markers: { enabled: !1, points: [] },
|
|
},
|
|
Ie = "picture-in-picture",
|
|
$e = "inline",
|
|
_e = { html5: "html5", youtube: "youtube", vimeo: "vimeo" },
|
|
Oe = "audio",
|
|
je = "video";
|
|
const qe = () => { };
|
|
class De {
|
|
constructor(e = !1) {
|
|
(this.enabled = window.console && e),
|
|
this.enabled && this.log("Debugging enabled");
|
|
}
|
|
get log() {
|
|
return this.enabled
|
|
? Function.prototype.bind.call(console.log, console)
|
|
: qe;
|
|
}
|
|
get warn() {
|
|
return this.enabled
|
|
? Function.prototype.bind.call(console.warn, console)
|
|
: qe;
|
|
}
|
|
get error() {
|
|
return this.enabled
|
|
? Function.prototype.bind.call(console.error, console)
|
|
: qe;
|
|
}
|
|
}
|
|
class He {
|
|
constructor(t) {
|
|
e(this, "onChange", () => {
|
|
if (!this.supported) return;
|
|
const e = this.player.elements.buttons.fullscreen;
|
|
S.element(e) && (e.pressed = this.active);
|
|
const t =
|
|
this.target === this.player.media
|
|
? this.target
|
|
: this.player.elements.container;
|
|
Z.call(
|
|
this.player,
|
|
t,
|
|
this.active ? "enterfullscreen" : "exitfullscreen",
|
|
!0
|
|
);
|
|
}),
|
|
e(this, "toggleFallback", (e = !1) => {
|
|
if (
|
|
(e
|
|
? (this.scrollPosition = {
|
|
x: window.scrollX ?? 0,
|
|
y: window.scrollY ?? 0,
|
|
})
|
|
: window.scrollTo(this.scrollPosition.x, this.scrollPosition.y),
|
|
(document.body.style.overflow = e ? "hidden" : ""),
|
|
R(
|
|
this.target,
|
|
this.player.config.classNames.fullscreen.fallback,
|
|
e
|
|
),
|
|
M.isIos)
|
|
) {
|
|
let t = document.head.querySelector('meta[name="viewport"]');
|
|
const i = "viewport-fit=cover";
|
|
t ||
|
|
((t = document.createElement("meta")),
|
|
t.setAttribute("name", "viewport"));
|
|
const s = S.string(t.content) && t.content.includes(i);
|
|
e
|
|
? ((this.cleanupViewport = !s), s || (t.content += `,${i}`))
|
|
: this.cleanupViewport &&
|
|
(t.content = t.content
|
|
.split(",")
|
|
.filter((e) => e.trim() !== i)
|
|
.join(","));
|
|
}
|
|
this.onChange();
|
|
}),
|
|
e(this, "trapFocus", (e) => {
|
|
if (M.isIos || M.isIPadOS || !this.active || "Tab" !== e.key)
|
|
return;
|
|
const t = document.activeElement,
|
|
i = U.call(
|
|
this.player,
|
|
"a[href], button:not(:disabled), input:not(:disabled), [tabindex]"
|
|
),
|
|
[s] = i,
|
|
n = i[i.length - 1];
|
|
t !== n || e.shiftKey
|
|
? t === s && e.shiftKey && (n.focus(), e.preventDefault())
|
|
: (s.focus(), e.preventDefault());
|
|
}),
|
|
e(this, "update", () => {
|
|
if (this.supported) {
|
|
let e;
|
|
(e = this.forceFallback
|
|
? "Fallback (forced)"
|
|
: He.nativeSupported
|
|
? "Native"
|
|
: "Fallback"),
|
|
this.player.debug.log(`${e} fullscreen enabled`);
|
|
} else
|
|
this.player.debug.log(
|
|
"Fullscreen not supported and fallback disabled"
|
|
);
|
|
R(
|
|
this.player.elements.container,
|
|
this.player.config.classNames.fullscreen.enabled,
|
|
this.supported
|
|
);
|
|
}),
|
|
e(this, "enter", () => {
|
|
this.supported &&
|
|
(M.isIos && this.player.config.fullscreen.iosNative
|
|
? this.player.isVimeo
|
|
? this.player.embed.requestFullscreen()
|
|
: this.target.webkitEnterFullscreen()
|
|
: !He.nativeSupported || this.forceFallback
|
|
? this.toggleFallback(!0)
|
|
: this.prefix
|
|
? S.empty(this.prefix) ||
|
|
this.target[`${this.prefix}Request${this.property}`]()
|
|
: this.target.requestFullscreen({ navigationUI: "hide" }));
|
|
}),
|
|
e(this, "exit", () => {
|
|
if (this.supported)
|
|
if (M.isIos && this.player.config.fullscreen.iosNative)
|
|
this.player.isVimeo
|
|
? this.player.embed.exitFullscreen()
|
|
: this.target.webkitEnterFullscreen(),
|
|
ie(this.player.play());
|
|
else if (!He.nativeSupported || this.forceFallback)
|
|
this.toggleFallback(!1);
|
|
else if (this.prefix) {
|
|
if (!S.empty(this.prefix)) {
|
|
const e = "moz" === this.prefix ? "Cancel" : "Exit";
|
|
document[`${this.prefix}${e}${this.property}`]();
|
|
}
|
|
} else
|
|
(document.cancelFullScreen || document.exitFullscreen).call(
|
|
document
|
|
);
|
|
}),
|
|
e(this, "toggle", () => {
|
|
this.active ? this.exit() : this.enter();
|
|
}),
|
|
(this.player = t),
|
|
(this.prefix = He.prefix),
|
|
(this.property = He.property),
|
|
(this.scrollPosition = { x: 0, y: 0 }),
|
|
(this.forceFallback = "force" === t.config.fullscreen.fallback),
|
|
(this.player.elements.fullscreen =
|
|
t.config.fullscreen.container &&
|
|
(function (e, t) {
|
|
const { prototype: i } = Element;
|
|
return (
|
|
i.closest ||
|
|
function () {
|
|
let e = this;
|
|
do {
|
|
if (V.matches(e, t)) return e;
|
|
e = e.parentElement || e.parentNode;
|
|
} while (null !== e && 1 === e.nodeType);
|
|
return null;
|
|
}
|
|
).call(e, t);
|
|
})(this.player.elements.container, t.config.fullscreen.container)),
|
|
X.call(
|
|
this.player,
|
|
document,
|
|
"ms" === this.prefix
|
|
? "MSFullscreenChange"
|
|
: `${this.prefix}fullscreenchange`,
|
|
() => {
|
|
this.onChange();
|
|
}
|
|
),
|
|
X.call(
|
|
this.player,
|
|
this.player.elements.container,
|
|
"dblclick",
|
|
(e) => {
|
|
(S.element(this.player.elements.controls) &&
|
|
this.player.elements.controls.contains(e.target)) ||
|
|
this.player.listeners.proxy(e, this.toggle, "fullscreen");
|
|
}
|
|
),
|
|
X.call(this, this.player.elements.container, "keydown", (e) =>
|
|
this.trapFocus(e)
|
|
),
|
|
this.update();
|
|
}
|
|
static get nativeSupported() {
|
|
return !!(
|
|
document.fullscreenEnabled ||
|
|
document.webkitFullscreenEnabled ||
|
|
document.mozFullScreenEnabled ||
|
|
document.msFullscreenEnabled
|
|
);
|
|
}
|
|
get useNative() {
|
|
return He.nativeSupported && !this.forceFallback;
|
|
}
|
|
static get prefix() {
|
|
if (S.function(document.exitFullscreen)) return "";
|
|
let e = "";
|
|
return (
|
|
["webkit", "moz", "ms"].some(
|
|
(t) =>
|
|
!(
|
|
!S.function(document[`${t}ExitFullscreen`]) &&
|
|
!S.function(document[`${t}CancelFullScreen`])
|
|
) && ((e = t), !0)
|
|
),
|
|
e
|
|
);
|
|
}
|
|
static get property() {
|
|
return "moz" === this.prefix ? "FullScreen" : "Fullscreen";
|
|
}
|
|
get supported() {
|
|
return [
|
|
this.player.config.fullscreen.enabled,
|
|
this.player.isVideo,
|
|
He.nativeSupported || this.player.config.fullscreen.fallback,
|
|
!this.player.isYouTube ||
|
|
He.nativeSupported ||
|
|
!M.isIos ||
|
|
(this.player.config.playsinline &&
|
|
!this.player.config.fullscreen.iosNative),
|
|
].every(Boolean);
|
|
}
|
|
get active() {
|
|
if (!this.supported) return !1;
|
|
if (!He.nativeSupported || this.forceFallback)
|
|
return F(
|
|
this.target,
|
|
this.player.config.classNames.fullscreen.fallback
|
|
);
|
|
const e = this.prefix
|
|
? this.target.getRootNode()[`${this.prefix}${this.property}Element`]
|
|
: this.target.getRootNode().fullscreenElement;
|
|
return e && e.shadowRoot
|
|
? e === this.target.getRootNode().host
|
|
: e === this.target;
|
|
}
|
|
get target() {
|
|
return M.isIos && this.player.config.fullscreen.iosNative
|
|
? this.player.media
|
|
: this.player.elements.fullscreen ?? this.player.elements.container;
|
|
}
|
|
}
|
|
function Re(e, t = 1) {
|
|
return new Promise((i, s) => {
|
|
const n = new Image(),
|
|
a = () => {
|
|
delete n.onload, delete n.onerror, (n.naturalWidth >= t ? i : s)(n);
|
|
};
|
|
Object.assign(n, { onload: a, onerror: a, src: e });
|
|
});
|
|
}
|
|
const Fe = {
|
|
addStyleHook() {
|
|
R(
|
|
this.elements.container,
|
|
this.config.selectors.container.replace(".", ""),
|
|
!0
|
|
),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.uiSupported,
|
|
this.supported.ui
|
|
);
|
|
},
|
|
toggleNativeControls(e = !1) {
|
|
e && this.isHTML5
|
|
? this.media.setAttribute("controls", "")
|
|
: this.media.removeAttribute("controls");
|
|
},
|
|
build() {
|
|
if ((this.listeners.media(), !this.supported.ui))
|
|
return (
|
|
this.debug.warn(
|
|
`Basic support only for ${this.provider} ${this.type}`
|
|
),
|
|
void Fe.toggleNativeControls.call(this, !0)
|
|
);
|
|
S.element(this.elements.controls) ||
|
|
(Pe.inject.call(this), this.listeners.controls()),
|
|
Fe.toggleNativeControls.call(this),
|
|
this.isHTML5 && xe.setup.call(this),
|
|
(this.volume = null),
|
|
(this.muted = null),
|
|
(this.loop = null),
|
|
(this.quality = null),
|
|
(this.speed = null),
|
|
Pe.updateVolume.call(this),
|
|
Pe.timeUpdate.call(this),
|
|
Pe.durationUpdate.call(this),
|
|
Fe.checkPlaying.call(this),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.pip.supported,
|
|
K.pip && this.isHTML5 && this.isVideo
|
|
),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.airplay.supported,
|
|
K.airplay && this.isHTML5
|
|
),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.isTouch,
|
|
this.touch
|
|
),
|
|
(this.ready = !0),
|
|
setTimeout(() => {
|
|
Z.call(this, this.media, "ready");
|
|
}, 0),
|
|
Fe.setTitle.call(this),
|
|
this.poster &&
|
|
Fe.setPoster.call(this, this.poster, !1).catch(() => { }),
|
|
this.config.duration && Pe.durationUpdate.call(this),
|
|
this.config.mediaMetadata && Pe.setMediaMetadata.call(this);
|
|
},
|
|
setTitle() {
|
|
let e = ve.get("play", this.config);
|
|
if (
|
|
(S.string(this.config.title) &&
|
|
!S.empty(this.config.title) &&
|
|
(e += `, ${this.config.title}`),
|
|
Array.from(this.elements.buttons.play || []).forEach((t) => {
|
|
t.setAttribute("aria-label", e);
|
|
}),
|
|
this.isEmbed)
|
|
) {
|
|
const e = B.call(this, "iframe");
|
|
if (!S.element(e)) return;
|
|
const t = S.empty(this.config.title) ? "video" : this.config.title,
|
|
i = ve.get("frameTitle", this.config);
|
|
e.setAttribute("title", i.replace("{title}", t));
|
|
}
|
|
},
|
|
togglePoster(e) {
|
|
R(this.elements.container, this.config.classNames.posterEnabled, e);
|
|
},
|
|
setPoster(e, t = !0) {
|
|
return t && this.poster
|
|
? Promise.reject(new Error("Poster already set"))
|
|
: (this.media.setAttribute("data-poster", e),
|
|
this.elements.poster.removeAttribute("hidden"),
|
|
te
|
|
.call(this)
|
|
.then(() => Re(e))
|
|
.catch((t) => {
|
|
throw (e === this.poster && Fe.togglePoster.call(this, !1), t);
|
|
})
|
|
.then(() => {
|
|
if (e !== this.poster)
|
|
throw new Error(
|
|
"setPoster cancelled by later call to setPoster"
|
|
);
|
|
})
|
|
.then(
|
|
() => (
|
|
Object.assign(this.elements.poster.style, {
|
|
backgroundImage: `url('${e}')`,
|
|
backgroundSize: "",
|
|
}),
|
|
Fe.togglePoster.call(this, !0),
|
|
e
|
|
)
|
|
));
|
|
},
|
|
checkPlaying(e) {
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.playing,
|
|
this.playing
|
|
),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.paused,
|
|
this.paused
|
|
),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.stopped,
|
|
this.stopped
|
|
),
|
|
Array.from(this.elements.buttons.play || []).forEach((e) => {
|
|
Object.assign(e, { pressed: this.playing }),
|
|
e.setAttribute(
|
|
"aria-label",
|
|
ve.get(this.playing ? "pause" : "play", this.config)
|
|
);
|
|
}),
|
|
(S.event(e) && "timeupdate" === e.type) ||
|
|
Fe.toggleControls.call(this);
|
|
},
|
|
checkLoading(e) {
|
|
(this.loading = ["stalled", "waiting"].includes(e.type)),
|
|
clearTimeout(this.timers.loading),
|
|
(this.timers.loading = setTimeout(
|
|
() => {
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.loading,
|
|
this.loading
|
|
),
|
|
Fe.toggleControls.call(this);
|
|
},
|
|
this.loading ? 250 : 0
|
|
));
|
|
},
|
|
toggleControls(e) {
|
|
const { controls: t } = this.elements;
|
|
if (t && this.config.hideControls) {
|
|
const i = this.touch && this.lastSeekTime + 2e3 > Date.now();
|
|
this.toggleControls(
|
|
Boolean(
|
|
e || this.loading || this.paused || t.pressed || t.hover || i
|
|
)
|
|
);
|
|
}
|
|
},
|
|
migrateStyles() {
|
|
Object.values({ ...this.media.style })
|
|
.filter((e) => !S.empty(e) && S.string(e) && e.startsWith("--plyr"))
|
|
.forEach((e) => {
|
|
this.elements.container.style.setProperty(
|
|
e,
|
|
this.media.style.getPropertyValue(e)
|
|
),
|
|
this.media.style.removeProperty(e);
|
|
}),
|
|
S.empty(this.media.style) && this.media.removeAttribute("style");
|
|
},
|
|
};
|
|
class Ve {
|
|
constructor(t) {
|
|
e(this, "firstTouch", () => {
|
|
const { player: e } = this,
|
|
{ elements: t } = e;
|
|
(e.touch = !0), R(t.container, e.config.classNames.isTouch, !0);
|
|
}),
|
|
e(this, "global", (e = !0) => {
|
|
const { player: t } = this;
|
|
t.config.keyboard.global &&
|
|
Q.call(t, window, "keydown keyup", this.handleKey, e, !1),
|
|
Q.call(t, document.body, "click", this.toggleMenu, e),
|
|
G.call(t, document.body, "touchstart", this.firstTouch);
|
|
}),
|
|
e(this, "container", () => {
|
|
const { player: e } = this,
|
|
{ config: t, elements: i, timers: s } = e;
|
|
!t.keyboard.global &&
|
|
t.keyboard.focused &&
|
|
X.call(e, i.container, "keydown keyup", this.handleKey, !1),
|
|
X.call(
|
|
e,
|
|
i.container,
|
|
"mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen",
|
|
(t) => {
|
|
const { controls: n } = i;
|
|
n &&
|
|
"enterfullscreen" === t.type &&
|
|
((n.pressed = !1), (n.hover = !1));
|
|
let a = 0;
|
|
["touchstart", "touchmove", "mousemove"].includes(t.type) &&
|
|
(Fe.toggleControls.call(e, !0), (a = e.touch ? 3e3 : 2e3)),
|
|
clearTimeout(s.controls),
|
|
(s.controls = setTimeout(
|
|
() => Fe.toggleControls.call(e, !1),
|
|
a
|
|
));
|
|
}
|
|
);
|
|
const n = () => {
|
|
if (!e.isVimeo || e.config.vimeo.premium) return;
|
|
const t = i.wrapper,
|
|
{ active: s } = e.fullscreen,
|
|
[n, a] = ce.call(e),
|
|
l = ae(`aspect-ratio: ${n} / ${a}`);
|
|
if (!s)
|
|
return void (l
|
|
? ((t.style.width = null), (t.style.height = null))
|
|
: ((t.style.maxWidth = null), (t.style.margin = null)));
|
|
const [r, o] = [
|
|
Math.max(
|
|
document.documentElement.clientWidth || 0,
|
|
window.innerWidth || 0
|
|
),
|
|
Math.max(
|
|
document.documentElement.clientHeight || 0,
|
|
window.innerHeight || 0
|
|
),
|
|
],
|
|
c = r / o > n / a;
|
|
l
|
|
? ((t.style.width = c ? "auto" : "100%"),
|
|
(t.style.height = c ? "100%" : "auto"))
|
|
: ((t.style.maxWidth = c ? (o / a) * n + "px" : null),
|
|
(t.style.margin = c ? "0 auto" : null));
|
|
},
|
|
a = () => {
|
|
clearTimeout(s.resized), (s.resized = setTimeout(n, 50));
|
|
};
|
|
X.call(e, i.container, "enterfullscreen exitfullscreen", (t) => {
|
|
const { target: s } = e.fullscreen;
|
|
if (s !== i.container) return;
|
|
if (!e.isEmbed && S.empty(e.config.ratio)) return;
|
|
n();
|
|
("enterfullscreen" === t.type ? X : J).call(
|
|
e,
|
|
window,
|
|
"resize",
|
|
a
|
|
);
|
|
});
|
|
}),
|
|
e(this, "media", () => {
|
|
const { player: e } = this,
|
|
{ elements: t } = e;
|
|
if (
|
|
(X.call(e, e.media, "timeupdate seeking seeked", (t) =>
|
|
Pe.timeUpdate.call(e, t)
|
|
),
|
|
X.call(
|
|
e,
|
|
e.media,
|
|
"durationchange loadeddata loadedmetadata",
|
|
(t) => Pe.durationUpdate.call(e, t)
|
|
),
|
|
X.call(e, e.media, "ended", () => {
|
|
e.isHTML5 &&
|
|
e.isVideo &&
|
|
e.config.resetOnEnd &&
|
|
(e.restart(), e.pause());
|
|
}),
|
|
X.call(e, e.media, "progress playing seeking seeked", (t) =>
|
|
Pe.updateProgress.call(e, t)
|
|
),
|
|
X.call(e, e.media, "volumechange", (t) =>
|
|
Pe.updateVolume.call(e, t)
|
|
),
|
|
X.call(
|
|
e,
|
|
e.media,
|
|
"playing play pause ended emptied timeupdate",
|
|
(t) => Fe.checkPlaying.call(e, t)
|
|
),
|
|
X.call(e, e.media, "waiting canplay seeked playing", (t) =>
|
|
Fe.checkLoading.call(e, t)
|
|
),
|
|
e.supported.ui && e.config.clickToPlay && !e.isAudio)
|
|
) {
|
|
const i = B.call(e, `.${e.config.classNames.video}`);
|
|
if (!S.element(i)) return;
|
|
X.call(e, t.container, "click", (s) => {
|
|
([t.container, i].includes(s.target) || i.contains(s.target)) &&
|
|
((e.touch && e.config.hideControls) ||
|
|
(e.ended
|
|
? (this.proxy(s, e.restart, "restart"),
|
|
this.proxy(
|
|
s,
|
|
() => {
|
|
ie(e.play());
|
|
},
|
|
"play"
|
|
))
|
|
: this.proxy(
|
|
s,
|
|
() => {
|
|
ie(e.togglePlay());
|
|
},
|
|
"play"
|
|
)));
|
|
});
|
|
}
|
|
e.supported.ui &&
|
|
e.config.disableContextMenu &&
|
|
X.call(
|
|
e,
|
|
t.wrapper,
|
|
"contextmenu",
|
|
(e) => {
|
|
e.preventDefault();
|
|
},
|
|
!1
|
|
),
|
|
X.call(e, e.media, "volumechange", () => {
|
|
e.storage.set({ volume: e.volume, muted: e.muted });
|
|
}),
|
|
X.call(e, e.media, "ratechange", () => {
|
|
Pe.updateSetting.call(e, "speed"),
|
|
e.storage.set({ speed: e.speed });
|
|
}),
|
|
X.call(e, e.media, "qualitychange", (t) => {
|
|
Pe.updateSetting.call(e, "quality", null, t.detail.quality);
|
|
}),
|
|
X.call(e, e.media, "ready qualitychange", () => {
|
|
Pe.setDownloadUrl.call(e);
|
|
});
|
|
const i = e.config.events.concat(["keyup", "keydown"]).join(" ");
|
|
X.call(e, e.media, i, (i) => {
|
|
let { detail: s = {} } = i;
|
|
"error" === i.type && (s = e.media.error),
|
|
Z.call(e, t.container, i.type, !0, s);
|
|
});
|
|
}),
|
|
e(this, "proxy", (e, t, i) => {
|
|
const { player: s } = this,
|
|
n = s.config.listeners[i];
|
|
let a = !0;
|
|
S.function(n) && (a = n.call(s, e)),
|
|
!1 !== a && S.function(t) && t.call(s, e);
|
|
}),
|
|
e(this, "bind", (e, t, i, s, n = !0) => {
|
|
const { player: a } = this,
|
|
l = a.config.listeners[s],
|
|
r = S.function(l);
|
|
X.call(a, e, t, (e) => this.proxy(e, i, s), n && !r);
|
|
}),
|
|
e(this, "controls", () => {
|
|
const { player: e } = this,
|
|
{ elements: t } = e,
|
|
i = M.isIE ? "change" : "input";
|
|
if (
|
|
(t.buttons.play &&
|
|
Array.from(t.buttons.play).forEach((t) => {
|
|
this.bind(
|
|
t,
|
|
"click",
|
|
() => {
|
|
ie(e.togglePlay());
|
|
},
|
|
"play"
|
|
);
|
|
}),
|
|
this.bind(t.buttons.restart, "click", e.restart, "restart"),
|
|
this.bind(
|
|
t.buttons.rewind,
|
|
"click",
|
|
() => {
|
|
(e.lastSeekTime = Date.now()), e.rewind();
|
|
},
|
|
"rewind"
|
|
),
|
|
this.bind(
|
|
t.buttons.fastForward,
|
|
"click",
|
|
() => {
|
|
(e.lastSeekTime = Date.now()), e.forward();
|
|
},
|
|
"fastForward"
|
|
),
|
|
this.bind(
|
|
t.buttons.mute,
|
|
"click",
|
|
() => {
|
|
e.muted = !e.muted;
|
|
},
|
|
"mute"
|
|
),
|
|
this.bind(t.buttons.captions, "click", () => e.toggleCaptions()),
|
|
this.bind(
|
|
t.buttons.download,
|
|
"click",
|
|
() => {
|
|
Z.call(e, e.media, "download");
|
|
},
|
|
"download"
|
|
),
|
|
this.bind(
|
|
t.buttons.fullscreen,
|
|
"click",
|
|
() => {
|
|
e.fullscreen.toggle();
|
|
},
|
|
"fullscreen"
|
|
),
|
|
this.bind(
|
|
t.buttons.pip,
|
|
"click",
|
|
() => {
|
|
e.pip = "toggle";
|
|
},
|
|
"pip"
|
|
),
|
|
this.bind(t.buttons.airplay, "click", e.airplay, "airplay"),
|
|
this.bind(
|
|
t.buttons.settings,
|
|
"click",
|
|
(t) => {
|
|
t.stopPropagation(),
|
|
t.preventDefault(),
|
|
Pe.toggleMenu.call(e, t);
|
|
},
|
|
null,
|
|
!1
|
|
),
|
|
this.bind(
|
|
t.buttons.settings,
|
|
"keyup",
|
|
(t) => {
|
|
[" ", "Enter"].includes(t.key) &&
|
|
("Enter" !== t.key
|
|
? (t.preventDefault(),
|
|
t.stopPropagation(),
|
|
Pe.toggleMenu.call(e, t))
|
|
: Pe.focusFirstMenuItem.call(e, null, !0));
|
|
},
|
|
null,
|
|
!1
|
|
),
|
|
this.bind(t.settings.menu, "keydown", (t) => {
|
|
"Escape" === t.key && Pe.toggleMenu.call(e, t);
|
|
}),
|
|
this.bind(t.inputs.seek, "mousedown mousemove", (e) => {
|
|
const i = t.progress.getBoundingClientRect(),
|
|
s = (100 / i.width) * (e.pageX - i.left);
|
|
e.currentTarget.setAttribute("seek-value", s);
|
|
}),
|
|
this.bind(
|
|
t.inputs.seek,
|
|
"mousedown mouseup keydown keyup touchstart touchend",
|
|
(t) => {
|
|
const i = t.currentTarget,
|
|
s = "play-on-seeked";
|
|
if (
|
|
S.keyboardEvent(t) &&
|
|
!["ArrowLeft", "ArrowRight"].includes(t.key)
|
|
)
|
|
return;
|
|
e.lastSeekTime = Date.now();
|
|
const n = i.hasAttribute(s),
|
|
a = ["mouseup", "touchend", "keyup"].includes(t.type);
|
|
n && a
|
|
? (i.removeAttribute(s), ie(e.play()))
|
|
: !a && e.playing && (i.setAttribute(s, ""), e.pause());
|
|
}
|
|
),
|
|
M.isIos)
|
|
) {
|
|
const t = U.call(e, 'input[type="range"]');
|
|
Array.from(t).forEach((e) => this.bind(e, i, (e) => P(e.target)));
|
|
}
|
|
this.bind(
|
|
t.inputs.seek,
|
|
i,
|
|
(t) => {
|
|
const i = t.currentTarget;
|
|
let s = i.getAttribute("seek-value");
|
|
S.empty(s) && (s = i.value),
|
|
i.removeAttribute("seek-value"),
|
|
(e.currentTime = (s / i.max) * e.duration);
|
|
},
|
|
"seek"
|
|
),
|
|
this.bind(t.progress, "mouseenter mouseleave mousemove", (t) =>
|
|
Pe.updateSeekTooltip.call(e, t)
|
|
),
|
|
this.bind(t.progress, "mousemove touchmove", (t) => {
|
|
const { previewThumbnails: i } = e;
|
|
i && i.loaded && i.startMove(t);
|
|
}),
|
|
this.bind(t.progress, "mouseleave touchend click", () => {
|
|
const { previewThumbnails: t } = e;
|
|
t && t.loaded && t.endMove(!1, !0);
|
|
}),
|
|
this.bind(t.progress, "mousedown touchstart", (t) => {
|
|
const { previewThumbnails: i } = e;
|
|
i && i.loaded && i.startScrubbing(t);
|
|
}),
|
|
this.bind(t.progress, "mouseup touchend", (t) => {
|
|
const { previewThumbnails: i } = e;
|
|
i && i.loaded && i.endScrubbing(t);
|
|
}),
|
|
M.isWebKit &&
|
|
Array.from(U.call(e, 'input[type="range"]')).forEach((t) => {
|
|
this.bind(t, "input", (t) =>
|
|
Pe.updateRangeFill.call(e, t.target)
|
|
);
|
|
}),
|
|
e.config.toggleInvert &&
|
|
!S.element(t.display.duration) &&
|
|
this.bind(t.display.currentTime, "click", () => {
|
|
0 !== e.currentTime &&
|
|
((e.config.invertTime = !e.config.invertTime),
|
|
Pe.timeUpdate.call(e));
|
|
}),
|
|
this.bind(
|
|
t.inputs.volume,
|
|
i,
|
|
(t) => {
|
|
e.volume = t.target.value;
|
|
},
|
|
"volume"
|
|
),
|
|
this.bind(t.controls, "mouseenter mouseleave", (i) => {
|
|
t.controls.hover = !e.touch && "mouseenter" === i.type;
|
|
}),
|
|
t.fullscreen &&
|
|
Array.from(t.fullscreen.children)
|
|
.filter((e) => !e.contains(t.container))
|
|
.forEach((i) => {
|
|
this.bind(i, "mouseenter mouseleave", (i) => {
|
|
t.controls &&
|
|
(t.controls.hover =
|
|
!e.touch && "mouseenter" === i.type);
|
|
});
|
|
}),
|
|
this.bind(
|
|
t.controls,
|
|
"mousedown mouseup touchstart touchend touchcancel",
|
|
(e) => {
|
|
t.controls.pressed = ["mousedown", "touchstart"].includes(
|
|
e.type
|
|
);
|
|
}
|
|
),
|
|
this.bind(t.controls, "focusin", () => {
|
|
const { config: i, timers: s } = e;
|
|
R(t.controls, i.classNames.noTransition, !0),
|
|
Fe.toggleControls.call(e, !0),
|
|
setTimeout(() => {
|
|
R(t.controls, i.classNames.noTransition, !1);
|
|
}, 0);
|
|
const n = this.touch ? 3e3 : 4e3;
|
|
clearTimeout(s.controls),
|
|
(s.controls = setTimeout(
|
|
() => Fe.toggleControls.call(e, !1),
|
|
n
|
|
));
|
|
}),
|
|
this.bind(
|
|
t.inputs.volume,
|
|
"wheel",
|
|
(t) => {
|
|
const i = t.webkitDirectionInvertedFromDevice,
|
|
[s, n] = [t.deltaX, -t.deltaY].map((e) => (i ? -e : e)),
|
|
a = Math.sign(Math.abs(s) > Math.abs(n) ? s : n);
|
|
e.increaseVolume(a / 50);
|
|
const { volume: l } = e.media;
|
|
((1 === a && l < 1) || (-1 === a && l > 0)) &&
|
|
t.preventDefault();
|
|
},
|
|
"volume",
|
|
!1
|
|
);
|
|
}),
|
|
(this.player = t),
|
|
(this.lastKey = null),
|
|
(this.focusTimer = null),
|
|
(this.lastKeyDown = null),
|
|
(this.handleKey = this.handleKey.bind(this)),
|
|
(this.toggleMenu = this.toggleMenu.bind(this)),
|
|
(this.firstTouch = this.firstTouch.bind(this));
|
|
}
|
|
handleKey(e) {
|
|
const { player: t } = this,
|
|
{ elements: i } = t,
|
|
{
|
|
key: s,
|
|
type: n,
|
|
altKey: a,
|
|
ctrlKey: l,
|
|
metaKey: r,
|
|
shiftKey: o,
|
|
} = e,
|
|
c = "keydown" === n,
|
|
u = c && s === this.lastKey;
|
|
if (a || l || r || o) return;
|
|
if (!s) return;
|
|
if (c) {
|
|
const n = document.activeElement;
|
|
if (S.element(n)) {
|
|
const { editable: s } = t.config.selectors,
|
|
{ seek: a } = i.inputs;
|
|
if (n !== a && V(n, s)) return;
|
|
if (" " === e.key && V(n, 'button, [role^="menuitem"]')) return;
|
|
}
|
|
switch (
|
|
([
|
|
" ",
|
|
"ArrowLeft",
|
|
"ArrowUp",
|
|
"ArrowRight",
|
|
"ArrowDown",
|
|
"0",
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
"7",
|
|
"8",
|
|
"9",
|
|
"c",
|
|
"f",
|
|
"k",
|
|
"l",
|
|
"m",
|
|
].includes(s) && (e.preventDefault(), e.stopPropagation()),
|
|
s)
|
|
) {
|
|
case "0":
|
|
case "1":
|
|
case "2":
|
|
case "3":
|
|
case "4":
|
|
case "5":
|
|
case "6":
|
|
case "7":
|
|
case "8":
|
|
case "9":
|
|
u ||
|
|
((h = parseInt(s, 10)),
|
|
(t.currentTime = (t.duration / 10) * h));
|
|
break;
|
|
case " ":
|
|
case "k":
|
|
u || ie(t.togglePlay());
|
|
break;
|
|
case "ArrowUp":
|
|
t.increaseVolume(0.1);
|
|
break;
|
|
case "ArrowDown":
|
|
t.decreaseVolume(0.1);
|
|
break;
|
|
case "m":
|
|
u || (t.muted = !t.muted);
|
|
break;
|
|
case "ArrowRight":
|
|
t.forward();
|
|
break;
|
|
case "ArrowLeft":
|
|
t.rewind();
|
|
break;
|
|
case "f":
|
|
t.fullscreen.toggle();
|
|
break;
|
|
case "c":
|
|
u || t.toggleCaptions();
|
|
break;
|
|
case "l":
|
|
t.loop = !t.loop;
|
|
}
|
|
"Escape" === s &&
|
|
!t.fullscreen.usingNative &&
|
|
t.fullscreen.active &&
|
|
t.fullscreen.toggle(),
|
|
(this.lastKey = s);
|
|
} else this.lastKey = null;
|
|
var h;
|
|
}
|
|
toggleMenu(e) {
|
|
Pe.toggleMenu.call(this.player, e);
|
|
}
|
|
}
|
|
"undefined" != typeof globalThis
|
|
? globalThis
|
|
: "undefined" != typeof window
|
|
? window
|
|
: "undefined" != typeof global
|
|
? global
|
|
: "undefined" != typeof self && self;
|
|
var Ue = (function (e, t) {
|
|
return e((t = { exports: {} }), t.exports), t.exports;
|
|
})(function (e, t) {
|
|
e.exports = (function () {
|
|
var e = function () { },
|
|
t = {},
|
|
i = {},
|
|
s = {};
|
|
function n(e, t) {
|
|
e = e.push ? e : [e];
|
|
var n,
|
|
a,
|
|
l,
|
|
r = [],
|
|
o = e.length,
|
|
c = o;
|
|
for (
|
|
n = function (e, i) {
|
|
i.length && r.push(e), --c || t(r);
|
|
};
|
|
o--;
|
|
|
|
)
|
|
(a = e[o]), (l = i[a]) ? n(a, l) : (s[a] = s[a] || []).push(n);
|
|
}
|
|
function a(e, t) {
|
|
if (e) {
|
|
var n = s[e];
|
|
if (((i[e] = t), n)) for (; n.length;) n[0](e, t), n.splice(0, 1);
|
|
}
|
|
}
|
|
function l(t, i) {
|
|
t.call && (t = { success: t }),
|
|
i.length ? (t.error || e)(i) : (t.success || e)(t);
|
|
}
|
|
function r(t, i, s, n) {
|
|
var a,
|
|
l,
|
|
o = document,
|
|
c = s.async,
|
|
u = (s.numRetries || 0) + 1,
|
|
h = s.before || e,
|
|
d = t.replace(/[\?|#].*$/, ""),
|
|
m = t.replace(/^(css|img)!/, "");
|
|
(n = n || 0),
|
|
/(^css!|\.css$)/.test(d)
|
|
? (((l = o.createElement("link")).rel = "stylesheet"),
|
|
(l.href = m),
|
|
(a = "hideFocus" in l) &&
|
|
l.relList &&
|
|
((a = 0), (l.rel = "preload"), (l.as = "style")))
|
|
: /(^img!|\.(png|gif|jpg|svg|webp)$)/.test(d)
|
|
? ((l = o.createElement("img")).src = m)
|
|
: (((l = o.createElement("script")).src = t),
|
|
(l.async = void 0 === c || c)),
|
|
(l.onload =
|
|
l.onerror =
|
|
l.onbeforeload =
|
|
function (e) {
|
|
var o = e.type[0];
|
|
if (a)
|
|
try {
|
|
l.sheet.cssText.length || (o = "e");
|
|
} catch (e) {
|
|
18 != e.code && (o = "e");
|
|
}
|
|
if ("e" == o) {
|
|
if ((n += 1) < u) return r(t, i, s, n);
|
|
} else if ("preload" == l.rel && "style" == l.as)
|
|
return (l.rel = "stylesheet");
|
|
i(t, o, e.defaultPrevented);
|
|
}),
|
|
!1 !== h(t, l) && o.head.appendChild(l);
|
|
}
|
|
function o(e, t, i) {
|
|
var s,
|
|
n,
|
|
a = (e = e.push ? e : [e]).length,
|
|
l = a,
|
|
o = [];
|
|
for (
|
|
s = function (e, i, s) {
|
|
if (("e" == i && o.push(e), "b" == i)) {
|
|
if (!s) return;
|
|
o.push(e);
|
|
}
|
|
--a || t(o);
|
|
},
|
|
n = 0;
|
|
n < l;
|
|
n++
|
|
)
|
|
r(e[n], s, i);
|
|
}
|
|
function c(e, i, s) {
|
|
var n, r;
|
|
if ((i && i.trim && (n = i), (r = (n ? s : i) || {}), n)) {
|
|
if (n in t) throw "LoadJS";
|
|
t[n] = !0;
|
|
}
|
|
function c(t, i) {
|
|
o(
|
|
e,
|
|
function (e) {
|
|
l(r, e), t && l({ success: t, error: i }, e), a(n, e);
|
|
},
|
|
r
|
|
);
|
|
}
|
|
if (r.returnPromise) return new Promise(c);
|
|
c();
|
|
}
|
|
return (
|
|
(c.ready = function (e, t) {
|
|
return (
|
|
n(e, function (e) {
|
|
l(t, e);
|
|
}),
|
|
c
|
|
);
|
|
}),
|
|
(c.done = function (e) {
|
|
a(e, []);
|
|
}),
|
|
(c.reset = function () {
|
|
(t = {}), (i = {}), (s = {});
|
|
}),
|
|
(c.isDefined = function (e) {
|
|
return e in t;
|
|
}),
|
|
c
|
|
);
|
|
})();
|
|
});
|
|
function Be(e) {
|
|
return new Promise((t, i) => {
|
|
Ue(e, { success: t, error: i });
|
|
});
|
|
}
|
|
function We(e) {
|
|
e && !this.embed.hasPlayed && (this.embed.hasPlayed = !0),
|
|
this.media.paused === e &&
|
|
((this.media.paused = !e),
|
|
Z.call(this, this.media, e ? "play" : "pause"));
|
|
}
|
|
const ze = {
|
|
setup() {
|
|
const e = this;
|
|
R(e.elements.wrapper, e.config.classNames.embed, !0),
|
|
(e.options.speed = e.config.speed.options),
|
|
ue.call(e),
|
|
S.object(window.Vimeo)
|
|
? ze.ready.call(e)
|
|
: Be(e.config.urls.vimeo.sdk)
|
|
.then(() => {
|
|
ze.ready.call(e);
|
|
})
|
|
.catch((t) => {
|
|
e.debug.warn("Vimeo SDK (player.js) failed to load", t);
|
|
});
|
|
},
|
|
ready() {
|
|
const e = this,
|
|
t = e.config.vimeo,
|
|
{ premium: i, referrerPolicy: s, ...n } = t;
|
|
let a = e.media.getAttribute("src"),
|
|
l = "";
|
|
S.empty(a)
|
|
? ((a = e.media.getAttribute(e.config.attributes.embed.id)),
|
|
(l = e.media.getAttribute(e.config.attributes.embed.hash)))
|
|
: (l = (function (e) {
|
|
const t = e.match(
|
|
/^.*(vimeo.com\/|video\/)(\d+)(\?.*&*h=|\/)+([\d,a-f]+)/
|
|
);
|
|
return t && 5 === t.length ? t[4] : null;
|
|
})(a));
|
|
const r = l ? { h: l } : {};
|
|
i && Object.assign(n, { controls: !1, sidedock: !1 });
|
|
const o = Ne({
|
|
loop: e.config.loop.active,
|
|
autoplay: e.autoplay,
|
|
muted: e.muted,
|
|
gesture: "media",
|
|
playsinline: e.config.playsinline,
|
|
...r,
|
|
...n,
|
|
}),
|
|
c =
|
|
((u = a),
|
|
S.empty(u)
|
|
? null
|
|
: S.number(Number(u))
|
|
? u
|
|
: u.match(/^.*(vimeo.com\/|video\/)(\d+).*/)
|
|
? RegExp.$2
|
|
: u);
|
|
var u;
|
|
const h = $("iframe"),
|
|
d = me(e.config.urls.vimeo.iframe, c, o);
|
|
if (
|
|
(h.setAttribute("src", d),
|
|
h.setAttribute("allowfullscreen", ""),
|
|
h.setAttribute(
|
|
"allow",
|
|
[
|
|
"autoplay",
|
|
"fullscreen",
|
|
"picture-in-picture",
|
|
"encrypted-media",
|
|
"accelerometer",
|
|
"gyroscope",
|
|
].join("; ")
|
|
),
|
|
S.empty(s) || h.setAttribute("referrerPolicy", s),
|
|
i || !t.customControls)
|
|
)
|
|
h.setAttribute("data-poster", e.poster), (e.media = q(h, e.media));
|
|
else {
|
|
const t = $("div", {
|
|
class: e.config.classNames.embedContainer,
|
|
"data-poster": e.poster,
|
|
});
|
|
t.appendChild(h), (e.media = q(t, e.media));
|
|
}
|
|
t.customControls ||
|
|
Te(me(e.config.urls.vimeo.api, d)).then((t) => {
|
|
!S.empty(t) &&
|
|
t.thumbnail_url &&
|
|
Fe.setPoster.call(e, t.thumbnail_url).catch(() => { });
|
|
}),
|
|
(e.embed = new window.Vimeo.Player(h, {
|
|
autopause: e.config.autopause,
|
|
muted: e.muted,
|
|
})),
|
|
(e.media.paused = !0),
|
|
(e.media.currentTime = 0),
|
|
e.supported.ui && e.embed.disableTextTrack(),
|
|
(e.media.play = () => (We.call(e, !0), e.embed.play())),
|
|
(e.media.pause = () => (We.call(e, !1), e.embed.pause())),
|
|
(e.media.stop = () => {
|
|
e.pause(), (e.currentTime = 0);
|
|
});
|
|
let { currentTime: m } = e.media;
|
|
Object.defineProperty(e.media, "currentTime", {
|
|
get: () => m,
|
|
set(t) {
|
|
const { embed: i, media: s, paused: n, volume: a } = e,
|
|
l = n && !i.hasPlayed;
|
|
(s.seeking = !0),
|
|
Z.call(e, s, "seeking"),
|
|
Promise.resolve(l && i.setVolume(0))
|
|
.then(() => i.setCurrentTime(t))
|
|
.then(() => l && i.pause())
|
|
.then(() => l && i.setVolume(a))
|
|
.catch(() => { });
|
|
},
|
|
});
|
|
let p = e.config.speed.selected;
|
|
Object.defineProperty(e.media, "playbackRate", {
|
|
get: () => p,
|
|
set(t) {
|
|
e.embed
|
|
.setPlaybackRate(t)
|
|
.then(() => {
|
|
(p = t), Z.call(e, e.media, "ratechange");
|
|
})
|
|
.catch(() => {
|
|
e.options.speed = [1];
|
|
});
|
|
},
|
|
});
|
|
let { volume: g } = e.config;
|
|
Object.defineProperty(e.media, "volume", {
|
|
get: () => g,
|
|
set(t) {
|
|
e.embed.setVolume(t).then(() => {
|
|
(g = t), Z.call(e, e.media, "volumechange");
|
|
});
|
|
},
|
|
});
|
|
let { muted: f } = e.config;
|
|
Object.defineProperty(e.media, "muted", {
|
|
get: () => f,
|
|
set(t) {
|
|
const i = !!S.boolean(t) && t;
|
|
e.embed.setMuted(!!i || e.config.muted).then(() => {
|
|
(f = i), Z.call(e, e.media, "volumechange");
|
|
});
|
|
},
|
|
});
|
|
let y,
|
|
{ loop: b } = e.config;
|
|
Object.defineProperty(e.media, "loop", {
|
|
get: () => b,
|
|
set(t) {
|
|
const i = S.boolean(t) ? t : e.config.loop.active;
|
|
e.embed.setLoop(i).then(() => {
|
|
b = i;
|
|
});
|
|
},
|
|
}),
|
|
e.embed
|
|
.getVideoUrl()
|
|
.then((t) => {
|
|
(y = t), Pe.setDownloadUrl.call(e);
|
|
})
|
|
.catch((e) => {
|
|
this.debug.warn(e);
|
|
}),
|
|
Object.defineProperty(e.media, "currentSrc", { get: () => y }),
|
|
Object.defineProperty(e.media, "ended", {
|
|
get: () => e.currentTime === e.duration,
|
|
}),
|
|
Promise.all([e.embed.getVideoWidth(), e.embed.getVideoHeight()]).then(
|
|
(t) => {
|
|
const [i, s] = t;
|
|
(e.embed.ratio = he(i, s)), ue.call(this);
|
|
}
|
|
),
|
|
e.embed.setAutopause(e.config.autopause).then((t) => {
|
|
e.config.autopause = t;
|
|
}),
|
|
e.embed.getVideoTitle().then((t) => {
|
|
(e.config.title = t), Fe.setTitle.call(this);
|
|
}),
|
|
e.embed.getCurrentTime().then((t) => {
|
|
(m = t), Z.call(e, e.media, "timeupdate");
|
|
}),
|
|
e.embed.getDuration().then((t) => {
|
|
(e.media.duration = t), Z.call(e, e.media, "durationchange");
|
|
}),
|
|
e.embed.getTextTracks().then((t) => {
|
|
(e.media.textTracks = t), xe.setup.call(e);
|
|
}),
|
|
e.embed.on("cuechange", ({ cues: t = [] }) => {
|
|
const i = t.map((e) =>
|
|
(function (e) {
|
|
const t = document.createDocumentFragment(),
|
|
i = document.createElement("div");
|
|
return (
|
|
t.appendChild(i), (i.innerHTML = e), t.firstChild.innerText
|
|
);
|
|
})(e.text)
|
|
);
|
|
xe.updateCues.call(e, i);
|
|
}),
|
|
e.embed.on("loaded", () => {
|
|
if (
|
|
(e.embed.getPaused().then((t) => {
|
|
We.call(e, !t), t || Z.call(e, e.media, "playing");
|
|
}),
|
|
S.element(e.embed.element) && e.supported.ui)
|
|
) {
|
|
e.embed.element.setAttribute("tabindex", -1);
|
|
}
|
|
}),
|
|
e.embed.on("bufferstart", () => {
|
|
Z.call(e, e.media, "waiting");
|
|
}),
|
|
e.embed.on("bufferend", () => {
|
|
Z.call(e, e.media, "playing");
|
|
}),
|
|
e.embed.on("play", () => {
|
|
We.call(e, !0), Z.call(e, e.media, "playing");
|
|
}),
|
|
e.embed.on("pause", () => {
|
|
We.call(e, !1);
|
|
}),
|
|
e.embed.on("timeupdate", (t) => {
|
|
(e.media.seeking = !1),
|
|
(m = t.seconds),
|
|
Z.call(e, e.media, "timeupdate");
|
|
}),
|
|
e.embed.on("progress", (t) => {
|
|
(e.media.buffered = t.percent),
|
|
Z.call(e, e.media, "progress"),
|
|
1 === parseInt(t.percent, 10) &&
|
|
Z.call(e, e.media, "canplaythrough"),
|
|
e.embed.getDuration().then((t) => {
|
|
t !== e.media.duration &&
|
|
((e.media.duration = t),
|
|
Z.call(e, e.media, "durationchange"));
|
|
});
|
|
}),
|
|
e.embed.on("seeked", () => {
|
|
(e.media.seeking = !1), Z.call(e, e.media, "seeked");
|
|
}),
|
|
e.embed.on("ended", () => {
|
|
(e.media.paused = !0), Z.call(e, e.media, "ended");
|
|
}),
|
|
e.embed.on("error", (t) => {
|
|
(e.media.error = t), Z.call(e, e.media, "error");
|
|
}),
|
|
t.customControls && setTimeout(() => Fe.build.call(e), 0);
|
|
},
|
|
};
|
|
function Ke(e) {
|
|
e && !this.embed.hasPlayed && (this.embed.hasPlayed = !0),
|
|
this.media.paused === e &&
|
|
((this.media.paused = !e),
|
|
Z.call(this, this.media, e ? "play" : "pause"));
|
|
}
|
|
function Ye(e) {
|
|
return e.noCookie
|
|
? "https://www.youtube-nocookie.com"
|
|
: "http:" === window.location.protocol
|
|
? "http://www.youtube.com"
|
|
: void 0;
|
|
}
|
|
const Qe = {
|
|
setup() {
|
|
if (
|
|
(R(this.elements.wrapper, this.config.classNames.embed, !0),
|
|
S.object(window.YT) && S.function(window.YT.Player))
|
|
)
|
|
Qe.ready.call(this);
|
|
else {
|
|
const e = window.onYouTubeIframeAPIReady;
|
|
(window.onYouTubeIframeAPIReady = () => {
|
|
S.function(e) && e(), Qe.ready.call(this);
|
|
}),
|
|
Be(this.config.urls.youtube.sdk).catch((e) => {
|
|
this.debug.warn("YouTube API failed to load", e);
|
|
});
|
|
}
|
|
},
|
|
getTitle(e) {
|
|
Te(me(this.config.urls.youtube.api, e))
|
|
.then((e) => {
|
|
if (S.object(e)) {
|
|
const { title: t, height: i, width: s } = e;
|
|
(this.config.title = t),
|
|
Fe.setTitle.call(this),
|
|
(this.embed.ratio = he(s, i));
|
|
}
|
|
ue.call(this);
|
|
})
|
|
.catch(() => {
|
|
ue.call(this);
|
|
});
|
|
},
|
|
ready() {
|
|
const e = this,
|
|
t = e.config.youtube,
|
|
i = e.media && e.media.getAttribute("id");
|
|
if (!S.empty(i) && i.startsWith("youtube-")) return;
|
|
let s = e.media.getAttribute("src");
|
|
S.empty(s) &&
|
|
(s = e.media.getAttribute(this.config.attributes.embed.id));
|
|
const n =
|
|
((a = s),
|
|
S.empty(a)
|
|
? null
|
|
: a.match(
|
|
/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/
|
|
)
|
|
? RegExp.$2
|
|
: a);
|
|
var a;
|
|
const l = $("div", {
|
|
id: `${e.provider}-${Math.floor(1e4 * Math.random())}`,
|
|
"data-poster": t.customControls ? e.poster : void 0,
|
|
});
|
|
if (((e.media = q(l, e.media)), t.customControls)) {
|
|
const t = (e) => `https://i.ytimg.com/vi/${n}/${e}default.jpg`;
|
|
Re(t("maxres"), 121)
|
|
.catch(() => Re(t("sd"), 121))
|
|
.catch(() => Re(t("hq")))
|
|
.then((t) => Fe.setPoster.call(e, t.src))
|
|
.then((t) => {
|
|
t.includes("maxres") ||
|
|
(e.elements.poster.style.backgroundSize = "cover");
|
|
})
|
|
.catch(() => { });
|
|
}
|
|
e.embed = new window.YT.Player(e.media, {
|
|
videoId: n,
|
|
host: Ye(t),
|
|
playerVars: x(
|
|
{},
|
|
{
|
|
autoplay: e.config.autoplay ? 1 : 0,
|
|
hl: e.config.hl,
|
|
controls: e.supported.ui && t.customControls ? 0 : 1,
|
|
disablekb: 1,
|
|
playsinline:
|
|
e.config.playsinline && !e.config.fullscreen.iosNative
|
|
? 1
|
|
: 0,
|
|
cc_load_policy: e.captions.active ? 1 : 0,
|
|
cc_lang_pref: e.config.captions.language,
|
|
widget_referrer: window ? window.location.href : null,
|
|
},
|
|
t
|
|
),
|
|
events: {
|
|
onError(t) {
|
|
if (!e.media.error) {
|
|
const i = t.data,
|
|
s =
|
|
{
|
|
2: "The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.",
|
|
5: "The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.",
|
|
100: "The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.",
|
|
101: "The owner of the requested video does not allow it to be played in embedded players.",
|
|
150: "The owner of the requested video does not allow it to be played in embedded players.",
|
|
}[i] || "An unknown error occurred";
|
|
(e.media.error = { code: i, message: s }),
|
|
Z.call(e, e.media, "error");
|
|
}
|
|
},
|
|
onPlaybackRateChange(t) {
|
|
const i = t.target;
|
|
(e.media.playbackRate = i.getPlaybackRate()),
|
|
Z.call(e, e.media, "ratechange");
|
|
},
|
|
onReady(i) {
|
|
if (S.function(e.media.play)) return;
|
|
const s = i.target;
|
|
Qe.getTitle.call(e, n),
|
|
(e.media.play = () => {
|
|
Ke.call(e, !0), s.playVideo();
|
|
}),
|
|
(e.media.pause = () => {
|
|
Ke.call(e, !1), s.pauseVideo();
|
|
}),
|
|
(e.media.stop = () => {
|
|
s.stopVideo();
|
|
}),
|
|
(e.media.duration = s.getDuration()),
|
|
(e.media.paused = !0),
|
|
(e.media.currentTime = 0),
|
|
Object.defineProperty(e.media, "currentTime", {
|
|
get: () => Number(s.getCurrentTime()),
|
|
set(t) {
|
|
e.paused && !e.embed.hasPlayed && e.embed.mute(),
|
|
(e.media.seeking = !0),
|
|
Z.call(e, e.media, "seeking"),
|
|
s.seekTo(t);
|
|
},
|
|
}),
|
|
Object.defineProperty(e.media, "playbackRate", {
|
|
get: () => s.getPlaybackRate(),
|
|
set(e) {
|
|
s.setPlaybackRate(e);
|
|
},
|
|
});
|
|
let { volume: a } = e.config;
|
|
Object.defineProperty(e.media, "volume", {
|
|
get: () => a,
|
|
set(t) {
|
|
(a = t),
|
|
s.setVolume(100 * a),
|
|
Z.call(e, e.media, "volumechange");
|
|
},
|
|
});
|
|
let { muted: l } = e.config;
|
|
Object.defineProperty(e.media, "muted", {
|
|
get: () => l,
|
|
set(t) {
|
|
const i = S.boolean(t) ? t : l;
|
|
(l = i),
|
|
s[i ? "mute" : "unMute"](),
|
|
s.setVolume(100 * a),
|
|
Z.call(e, e.media, "volumechange");
|
|
},
|
|
}),
|
|
Object.defineProperty(e.media, "currentSrc", {
|
|
get: () => s.getVideoUrl(),
|
|
}),
|
|
Object.defineProperty(e.media, "ended", {
|
|
get: () => e.currentTime === e.duration,
|
|
});
|
|
const r = s.getAvailablePlaybackRates();
|
|
(e.options.speed = r.filter((t) =>
|
|
e.config.speed.options.includes(t)
|
|
)),
|
|
e.supported.ui &&
|
|
t.customControls &&
|
|
e.media.setAttribute("tabindex", -1),
|
|
Z.call(e, e.media, "timeupdate"),
|
|
Z.call(e, e.media, "durationchange"),
|
|
clearInterval(e.timers.buffering),
|
|
(e.timers.buffering = setInterval(() => {
|
|
(e.media.buffered = s.getVideoLoadedFraction()),
|
|
(null === e.media.lastBuffered ||
|
|
e.media.lastBuffered < e.media.buffered) &&
|
|
Z.call(e, e.media, "progress"),
|
|
(e.media.lastBuffered = e.media.buffered),
|
|
1 === e.media.buffered &&
|
|
(clearInterval(e.timers.buffering),
|
|
Z.call(e, e.media, "canplaythrough"));
|
|
}, 200)),
|
|
t.customControls && setTimeout(() => Fe.build.call(e), 50);
|
|
},
|
|
onStateChange(i) {
|
|
const s = i.target;
|
|
clearInterval(e.timers.playing);
|
|
switch (
|
|
(e.media.seeking &&
|
|
[1, 2].includes(i.data) &&
|
|
((e.media.seeking = !1), Z.call(e, e.media, "seeked")),
|
|
i.data)
|
|
) {
|
|
case -1:
|
|
Z.call(e, e.media, "timeupdate"),
|
|
(e.media.buffered = s.getVideoLoadedFraction()),
|
|
Z.call(e, e.media, "progress");
|
|
break;
|
|
case 0:
|
|
Ke.call(e, !1),
|
|
e.media.loop
|
|
? (s.stopVideo(), s.playVideo())
|
|
: Z.call(e, e.media, "ended");
|
|
break;
|
|
case 1:
|
|
t.customControls &&
|
|
!e.config.autoplay &&
|
|
e.media.paused &&
|
|
!e.embed.hasPlayed
|
|
? e.media.pause()
|
|
: (Ke.call(e, !0),
|
|
Z.call(e, e.media, "playing"),
|
|
(e.timers.playing = setInterval(() => {
|
|
Z.call(e, e.media, "timeupdate");
|
|
}, 50)),
|
|
e.media.duration !== s.getDuration() &&
|
|
((e.media.duration = s.getDuration()),
|
|
Z.call(e, e.media, "durationchange")));
|
|
break;
|
|
case 2:
|
|
e.muted || e.embed.unMute(), Ke.call(e, !1);
|
|
break;
|
|
case 3:
|
|
Z.call(e, e.media, "waiting");
|
|
}
|
|
Z.call(e, e.elements.container, "statechange", !1, {
|
|
code: i.data,
|
|
});
|
|
},
|
|
},
|
|
});
|
|
},
|
|
},
|
|
Xe = {
|
|
setup() {
|
|
this.media
|
|
? (R(
|
|
this.elements.container,
|
|
this.config.classNames.type.replace("{0}", this.type),
|
|
!0
|
|
),
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.provider.replace("{0}", this.provider),
|
|
!0
|
|
),
|
|
this.isEmbed &&
|
|
R(
|
|
this.elements.container,
|
|
this.config.classNames.type.replace("{0}", "video"),
|
|
!0
|
|
),
|
|
this.isVideo &&
|
|
((this.elements.wrapper = $("div", {
|
|
class: this.config.classNames.video,
|
|
})),
|
|
L(this.media, this.elements.wrapper),
|
|
(this.elements.poster = $("div", {
|
|
class: this.config.classNames.poster,
|
|
})),
|
|
this.elements.wrapper.appendChild(this.elements.poster)),
|
|
this.isHTML5
|
|
? de.setup.call(this)
|
|
: this.isYouTube
|
|
? Qe.setup.call(this)
|
|
: this.isVimeo && ze.setup.call(this))
|
|
: this.debug.warn("No media element found!");
|
|
},
|
|
};
|
|
class Je {
|
|
constructor(t) {
|
|
e(this, "load", () => {
|
|
this.enabled &&
|
|
(S.object(window.google) && S.object(window.google.ima)
|
|
? this.ready()
|
|
: Be(this.player.config.urls.googleIMA.sdk)
|
|
.then(() => {
|
|
this.ready();
|
|
})
|
|
.catch(() => {
|
|
this.trigger(
|
|
"error",
|
|
new Error("Google IMA SDK failed to load")
|
|
);
|
|
}));
|
|
}),
|
|
e(this, "ready", () => {
|
|
var e;
|
|
this.enabled ||
|
|
((e = this).manager && e.manager.destroy(),
|
|
e.elements.displayContainer &&
|
|
e.elements.displayContainer.destroy(),
|
|
e.elements.container.remove()),
|
|
this.startSafetyTimer(12e3, "ready()"),
|
|
this.managerPromise.then(() => {
|
|
this.clearSafetyTimer("onAdsManagerLoaded()");
|
|
}),
|
|
this.listeners(),
|
|
this.setupIMA();
|
|
}),
|
|
e(this, "setupIMA", () => {
|
|
(this.elements.container = $("div", {
|
|
class: this.player.config.classNames.ads,
|
|
})),
|
|
this.player.elements.container.appendChild(
|
|
this.elements.container
|
|
),
|
|
google.ima.settings.setVpaidMode(
|
|
google.ima.ImaSdkSettings.VpaidMode.ENABLED
|
|
),
|
|
google.ima.settings.setLocale(this.player.config.ads.language),
|
|
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(
|
|
this.player.config.playsinline
|
|
),
|
|
(this.elements.displayContainer =
|
|
new google.ima.AdDisplayContainer(
|
|
this.elements.container,
|
|
this.player.media
|
|
)),
|
|
(this.loader = new google.ima.AdsLoader(
|
|
this.elements.displayContainer
|
|
)),
|
|
this.loader.addEventListener(
|
|
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
|
|
(e) => this.onAdsManagerLoaded(e),
|
|
!1
|
|
),
|
|
this.loader.addEventListener(
|
|
google.ima.AdErrorEvent.Type.AD_ERROR,
|
|
(e) => this.onAdError(e),
|
|
!1
|
|
),
|
|
this.requestAds();
|
|
}),
|
|
e(this, "requestAds", () => {
|
|
const { container: e } = this.player.elements;
|
|
try {
|
|
const t = new google.ima.AdsRequest();
|
|
(t.adTagUrl = this.tagUrl),
|
|
(t.linearAdSlotWidth = e.offsetWidth),
|
|
(t.linearAdSlotHeight = e.offsetHeight),
|
|
(t.nonLinearAdSlotWidth = e.offsetWidth),
|
|
(t.nonLinearAdSlotHeight = e.offsetHeight),
|
|
(t.forceNonLinearFullSlot = !1),
|
|
t.setAdWillPlayMuted(!this.player.muted),
|
|
this.loader.requestAds(t);
|
|
} catch (e) {
|
|
this.onAdError(e);
|
|
}
|
|
}),
|
|
e(this, "pollCountdown", (e = !1) => {
|
|
if (!e)
|
|
return (
|
|
clearInterval(this.countdownTimer),
|
|
void this.elements.container.removeAttribute("data-badge-text")
|
|
);
|
|
this.countdownTimer = setInterval(() => {
|
|
const e = Ee(Math.max(this.manager.getRemainingTime(), 0)),
|
|
t = `${ve.get("advertisement", this.player.config)} - ${e}`;
|
|
this.elements.container.setAttribute("data-badge-text", t);
|
|
}, 100);
|
|
}),
|
|
e(this, "onAdsManagerLoaded", (e) => {
|
|
if (!this.enabled) return;
|
|
const t = new google.ima.AdsRenderingSettings();
|
|
(t.restoreCustomPlaybackStateOnAdBreakComplete = !0),
|
|
(t.enablePreloading = !0),
|
|
(this.manager = e.getAdsManager(this.player, t)),
|
|
(this.cuePoints = this.manager.getCuePoints()),
|
|
this.manager.addEventListener(
|
|
google.ima.AdErrorEvent.Type.AD_ERROR,
|
|
(e) => this.onAdError(e)
|
|
),
|
|
Object.keys(google.ima.AdEvent.Type).forEach((e) => {
|
|
this.manager.addEventListener(google.ima.AdEvent.Type[e], (e) =>
|
|
this.onAdEvent(e)
|
|
);
|
|
}),
|
|
this.trigger("loaded");
|
|
}),
|
|
e(this, "addCuePoints", () => {
|
|
S.empty(this.cuePoints) ||
|
|
this.cuePoints.forEach((e) => {
|
|
if (0 !== e && -1 !== e && e < this.player.duration) {
|
|
const t = this.player.elements.progress;
|
|
if (S.element(t)) {
|
|
const i = (100 / this.player.duration) * e,
|
|
s = $("span", {
|
|
class: this.player.config.classNames.cues,
|
|
});
|
|
(s.style.left = `${i.toString()}%`), t.appendChild(s);
|
|
}
|
|
}
|
|
});
|
|
}),
|
|
e(this, "onAdEvent", (e) => {
|
|
const { container: t } = this.player.elements,
|
|
i = e.getAd(),
|
|
s = e.getAdData();
|
|
switch (
|
|
(((e) => {
|
|
Z.call(
|
|
this.player,
|
|
this.player.media,
|
|
`ads${e.replace(/_/g, "").toLowerCase()}`
|
|
);
|
|
})(e.type),
|
|
e.type)
|
|
) {
|
|
case google.ima.AdEvent.Type.LOADED:
|
|
this.trigger("loaded"),
|
|
this.pollCountdown(!0),
|
|
i.isLinear() ||
|
|
((i.width = t.offsetWidth), (i.height = t.offsetHeight));
|
|
break;
|
|
case google.ima.AdEvent.Type.STARTED:
|
|
this.manager.setVolume(this.player.volume);
|
|
break;
|
|
case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:
|
|
this.player.ended
|
|
? this.loadAds()
|
|
: this.loader.contentComplete();
|
|
break;
|
|
case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:
|
|
this.pauseContent();
|
|
break;
|
|
case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:
|
|
this.pollCountdown(), this.resumeContent();
|
|
break;
|
|
case google.ima.AdEvent.Type.LOG:
|
|
s.adError &&
|
|
this.player.debug.warn(
|
|
`Non-fatal ad error: ${s.adError.getMessage()}`
|
|
);
|
|
}
|
|
}),
|
|
e(this, "onAdError", (e) => {
|
|
this.cancel(), this.player.debug.warn("Ads error", e);
|
|
}),
|
|
e(this, "listeners", () => {
|
|
const { container: e } = this.player.elements;
|
|
let t;
|
|
this.player.on("canplay", () => {
|
|
this.addCuePoints();
|
|
}),
|
|
this.player.on("ended", () => {
|
|
this.loader.contentComplete();
|
|
}),
|
|
this.player.on("timeupdate", () => {
|
|
t = this.player.currentTime;
|
|
}),
|
|
this.player.on("seeked", () => {
|
|
const e = this.player.currentTime;
|
|
S.empty(this.cuePoints) ||
|
|
this.cuePoints.forEach((i, s) => {
|
|
t < i &&
|
|
i < e &&
|
|
(this.manager.discardAdBreak(),
|
|
this.cuePoints.splice(s, 1));
|
|
});
|
|
}),
|
|
window.addEventListener("resize", () => {
|
|
this.manager &&
|
|
this.manager.resize(
|
|
e.offsetWidth,
|
|
e.offsetHeight,
|
|
google.ima.ViewMode.NORMAL
|
|
);
|
|
});
|
|
}),
|
|
e(this, "play", () => {
|
|
const { container: e } = this.player.elements;
|
|
this.managerPromise || this.resumeContent(),
|
|
this.managerPromise
|
|
.then(() => {
|
|
this.manager.setVolume(this.player.volume),
|
|
this.elements.displayContainer.initialize();
|
|
try {
|
|
this.initialized ||
|
|
(this.manager.init(
|
|
e.offsetWidth,
|
|
e.offsetHeight,
|
|
google.ima.ViewMode.NORMAL
|
|
),
|
|
this.manager.start()),
|
|
(this.initialized = !0);
|
|
} catch (e) {
|
|
this.onAdError(e);
|
|
}
|
|
})
|
|
.catch(() => { });
|
|
}),
|
|
e(this, "resumeContent", () => {
|
|
(this.elements.container.style.zIndex = ""),
|
|
(this.playing = !1),
|
|
ie(this.player.media.play());
|
|
}),
|
|
e(this, "pauseContent", () => {
|
|
(this.elements.container.style.zIndex = 3),
|
|
(this.playing = !0),
|
|
this.player.media.pause();
|
|
}),
|
|
e(this, "cancel", () => {
|
|
this.initialized && this.resumeContent(),
|
|
this.trigger("error"),
|
|
this.loadAds();
|
|
}),
|
|
e(this, "loadAds", () => {
|
|
this.managerPromise
|
|
.then(() => {
|
|
this.manager && this.manager.destroy(),
|
|
(this.managerPromise = new Promise((e) => {
|
|
this.on("loaded", e), this.player.debug.log(this.manager);
|
|
})),
|
|
(this.initialized = !1),
|
|
this.requestAds();
|
|
})
|
|
.catch(() => { });
|
|
}),
|
|
e(this, "trigger", (e, ...t) => {
|
|
const i = this.events[e];
|
|
S.array(i) &&
|
|
i.forEach((e) => {
|
|
S.function(e) && e.apply(this, t);
|
|
});
|
|
}),
|
|
e(
|
|
this,
|
|
"on",
|
|
(e, t) => (
|
|
S.array(this.events[e]) || (this.events[e] = []),
|
|
this.events[e].push(t),
|
|
this
|
|
)
|
|
),
|
|
e(this, "startSafetyTimer", (e, t) => {
|
|
this.player.debug.log(`Safety timer invoked from: ${t}`),
|
|
(this.safetyTimer = setTimeout(() => {
|
|
this.cancel(), this.clearSafetyTimer("startSafetyTimer()");
|
|
}, e));
|
|
}),
|
|
e(this, "clearSafetyTimer", (e) => {
|
|
S.nullOrUndefined(this.safetyTimer) ||
|
|
(this.player.debug.log(`Safety timer cleared from: ${e}`),
|
|
clearTimeout(this.safetyTimer),
|
|
(this.safetyTimer = null));
|
|
}),
|
|
(this.player = t),
|
|
(this.config = t.config.ads),
|
|
(this.playing = !1),
|
|
(this.initialized = !1),
|
|
(this.elements = { container: null, displayContainer: null }),
|
|
(this.manager = null),
|
|
(this.loader = null),
|
|
(this.cuePoints = null),
|
|
(this.events = {}),
|
|
(this.safetyTimer = null),
|
|
(this.countdownTimer = null),
|
|
(this.managerPromise = new Promise((e, t) => {
|
|
this.on("loaded", e), this.on("error", t);
|
|
})),
|
|
this.load();
|
|
}
|
|
get enabled() {
|
|
const { config: e } = this;
|
|
return (
|
|
this.player.isHTML5 &&
|
|
this.player.isVideo &&
|
|
e.enabled &&
|
|
(!S.empty(e.publisherId) || S.url(e.tagUrl))
|
|
);
|
|
}
|
|
get tagUrl() {
|
|
const { config: e } = this;
|
|
if (S.url(e.tagUrl)) return e.tagUrl;
|
|
return `https://go.aniview.com/api/adserver6/vast/?${Ne({
|
|
AV_PUBLISHERID: "58c25bb0073ef448b1087ad6",
|
|
AV_CHANNELID: "5a0458dc28a06145e4519d21",
|
|
AV_URL: window.location.hostname,
|
|
cb: Date.now(),
|
|
AV_WIDTH: 640,
|
|
AV_HEIGHT: 480,
|
|
AV_CDIM2: e.publisherId,
|
|
})}`;
|
|
}
|
|
}
|
|
function Ge(e = 0, t = 0, i = 255) {
|
|
return Math.min(Math.max(e, t), i);
|
|
}
|
|
const Ze = (e) => {
|
|
const t = [];
|
|
return (
|
|
e.split(/\r\n\r\n|\n\n|\r\r/).forEach((e) => {
|
|
const i = {};
|
|
e.split(/\r\n|\n|\r/).forEach((e) => {
|
|
if (S.number(i.startTime)) {
|
|
if (!S.empty(e.trim()) && S.empty(i.text)) {
|
|
const t = e.trim().split("#xywh=");
|
|
([i.text] = t),
|
|
t[1] && ([i.x, i.y, i.w, i.h] = t[1].split(","));
|
|
}
|
|
} else {
|
|
const t = e.match(
|
|
/([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})/
|
|
);
|
|
t &&
|
|
((i.startTime =
|
|
60 * Number(t[1] || 0) * 60 +
|
|
60 * Number(t[2]) +
|
|
Number(t[3]) +
|
|
Number(`0.${t[4]}`)),
|
|
(i.endTime =
|
|
60 * Number(t[6] || 0) * 60 +
|
|
60 * Number(t[7]) +
|
|
Number(t[8]) +
|
|
Number(`0.${t[9]}`)));
|
|
}
|
|
}),
|
|
i.text && t.push(i);
|
|
}),
|
|
t
|
|
);
|
|
},
|
|
et = (e, t) => {
|
|
const i = {};
|
|
return (
|
|
e > t.width / t.height
|
|
? ((i.width = t.width), (i.height = (1 / e) * t.width))
|
|
: ((i.height = t.height), (i.width = e * t.height)),
|
|
i
|
|
);
|
|
};
|
|
class tt {
|
|
constructor(t) {
|
|
e(this, "load", () => {
|
|
this.player.elements.display.seekTooltip &&
|
|
(this.player.elements.display.seekTooltip.hidden = this.enabled),
|
|
this.enabled &&
|
|
this.getThumbnails().then(() => {
|
|
this.enabled &&
|
|
(this.render(),
|
|
this.determineContainerAutoSizing(),
|
|
this.listeners(),
|
|
(this.loaded = !0));
|
|
});
|
|
}),
|
|
e(
|
|
this,
|
|
"getThumbnails",
|
|
() =>
|
|
new Promise((e) => {
|
|
const { src: t } = this.player.config.previewThumbnails;
|
|
if (S.empty(t))
|
|
throw new Error(
|
|
"Missing previewThumbnails.src config attribute"
|
|
);
|
|
const i = () => {
|
|
this.thumbnails.sort((e, t) => e.height - t.height),
|
|
this.player.debug.log(
|
|
"Preview thumbnails",
|
|
this.thumbnails
|
|
),
|
|
e();
|
|
};
|
|
if (S.function(t))
|
|
t((e) => {
|
|
(this.thumbnails = e), i();
|
|
});
|
|
else {
|
|
const e = (S.string(t) ? [t] : t).map((e) =>
|
|
this.getThumbnail(e)
|
|
);
|
|
Promise.all(e).then(i);
|
|
}
|
|
})
|
|
),
|
|
e(
|
|
this,
|
|
"getThumbnail",
|
|
(e) =>
|
|
new Promise((t) => {
|
|
Te(e).then((i) => {
|
|
const s = { frames: Ze(i), height: null, urlPrefix: "" };
|
|
s.frames[0].text.startsWith("/") ||
|
|
s.frames[0].text.startsWith("http://") ||
|
|
s.frames[0].text.startsWith("https://") ||
|
|
(s.urlPrefix = e.substring(0, e.lastIndexOf("/") + 1));
|
|
const n = new Image();
|
|
(n.onload = () => {
|
|
(s.height = n.naturalHeight),
|
|
(s.width = n.naturalWidth),
|
|
this.thumbnails.push(s),
|
|
t();
|
|
}),
|
|
(n.src = s.urlPrefix + s.frames[0].text);
|
|
});
|
|
})
|
|
),
|
|
e(this, "startMove", (e) => {
|
|
if (
|
|
this.loaded &&
|
|
S.event(e) &&
|
|
["touchmove", "mousemove"].includes(e.type) &&
|
|
this.player.media.duration
|
|
) {
|
|
if ("touchmove" === e.type)
|
|
this.seekTime =
|
|
this.player.media.duration *
|
|
(this.player.elements.inputs.seek.value / 100);
|
|
else {
|
|
var t, i;
|
|
const s = this.player.elements.progress.getBoundingClientRect(),
|
|
n = (100 / s.width) * (e.pageX - s.left);
|
|
(this.seekTime = this.player.media.duration * (n / 100)),
|
|
this.seekTime < 0 && (this.seekTime = 0),
|
|
this.seekTime > this.player.media.duration - 1 &&
|
|
(this.seekTime = this.player.media.duration - 1),
|
|
(this.mousePosX = e.pageX),
|
|
(this.elements.thumb.time.innerText = Ee(this.seekTime));
|
|
const a =
|
|
null === (t = this.player.config.markers) ||
|
|
void 0 === t ||
|
|
null === (i = t.points) ||
|
|
void 0 === i
|
|
? void 0
|
|
: i.find(({ time: e }) => e === Math.round(this.seekTime));
|
|
a &&
|
|
this.elements.thumb.time.insertAdjacentHTML(
|
|
"afterbegin",
|
|
`${a.label}<br>`
|
|
);
|
|
}
|
|
this.showImageAtCurrentTime();
|
|
}
|
|
}),
|
|
e(this, "endMove", () => {
|
|
this.toggleThumbContainer(!1, !0);
|
|
}),
|
|
e(this, "startScrubbing", (e) => {
|
|
(S.nullOrUndefined(e.button) ||
|
|
!1 === e.button ||
|
|
0 === e.button) &&
|
|
((this.mouseDown = !0),
|
|
this.player.media.duration &&
|
|
(this.toggleScrubbingContainer(!0),
|
|
this.toggleThumbContainer(!1, !0),
|
|
this.showImageAtCurrentTime()));
|
|
}),
|
|
e(this, "endScrubbing", () => {
|
|
(this.mouseDown = !1),
|
|
Math.ceil(this.lastTime) ===
|
|
Math.ceil(this.player.media.currentTime)
|
|
? this.toggleScrubbingContainer(!1)
|
|
: G.call(this.player, this.player.media, "timeupdate", () => {
|
|
this.mouseDown || this.toggleScrubbingContainer(!1);
|
|
});
|
|
}),
|
|
e(this, "listeners", () => {
|
|
this.player.on("play", () => {
|
|
this.toggleThumbContainer(!1, !0);
|
|
}),
|
|
this.player.on("seeked", () => {
|
|
this.toggleThumbContainer(!1);
|
|
}),
|
|
this.player.on("timeupdate", () => {
|
|
this.lastTime = this.player.media.currentTime;
|
|
});
|
|
}),
|
|
e(this, "render", () => {
|
|
(this.elements.thumb.container = $("div", {
|
|
class:
|
|
this.player.config.classNames.previewThumbnails.thumbContainer,
|
|
})),
|
|
(this.elements.thumb.imageContainer = $("div", {
|
|
class:
|
|
this.player.config.classNames.previewThumbnails
|
|
.imageContainer,
|
|
})),
|
|
this.elements.thumb.container.appendChild(
|
|
this.elements.thumb.imageContainer
|
|
);
|
|
const e = $("div", {
|
|
class:
|
|
this.player.config.classNames.previewThumbnails.timeContainer,
|
|
});
|
|
(this.elements.thumb.time = $("span", {}, "00:00")),
|
|
e.appendChild(this.elements.thumb.time),
|
|
this.elements.thumb.imageContainer.appendChild(e),
|
|
S.element(this.player.elements.progress) &&
|
|
this.player.elements.progress.appendChild(
|
|
this.elements.thumb.container
|
|
),
|
|
(this.elements.scrubbing.container = $("div", {
|
|
class:
|
|
this.player.config.classNames.previewThumbnails
|
|
.scrubbingContainer,
|
|
})),
|
|
this.player.elements.wrapper.appendChild(
|
|
this.elements.scrubbing.container
|
|
);
|
|
}),
|
|
e(this, "destroy", () => {
|
|
this.elements.thumb.container &&
|
|
this.elements.thumb.container.remove(),
|
|
this.elements.scrubbing.container &&
|
|
this.elements.scrubbing.container.remove();
|
|
}),
|
|
e(this, "showImageAtCurrentTime", () => {
|
|
this.mouseDown
|
|
? this.setScrubbingContainerSize()
|
|
: this.setThumbContainerSizeAndPos();
|
|
const e = this.thumbnails[0].frames.findIndex(
|
|
(e) =>
|
|
this.seekTime >= e.startTime && this.seekTime <= e.endTime
|
|
),
|
|
t = e >= 0;
|
|
let i = 0;
|
|
this.mouseDown || this.toggleThumbContainer(t),
|
|
t &&
|
|
(this.thumbnails.forEach((t, s) => {
|
|
this.loadedImages.includes(t.frames[e].text) && (i = s);
|
|
}),
|
|
e !== this.showingThumb &&
|
|
((this.showingThumb = e), this.loadImage(i)));
|
|
}),
|
|
e(this, "loadImage", (e = 0) => {
|
|
const t = this.showingThumb,
|
|
i = this.thumbnails[e],
|
|
{ urlPrefix: s } = i,
|
|
n = i.frames[t],
|
|
a = i.frames[t].text,
|
|
l = s + a;
|
|
if (
|
|
this.currentImageElement &&
|
|
this.currentImageElement.dataset.filename === a
|
|
)
|
|
this.showImage(this.currentImageElement, n, e, t, a, !1),
|
|
(this.currentImageElement.dataset.index = t),
|
|
this.removeOldImages(this.currentImageElement);
|
|
else {
|
|
this.loadingImage &&
|
|
this.usingSprites &&
|
|
(this.loadingImage.onload = null);
|
|
const i = new Image();
|
|
(i.src = l),
|
|
(i.dataset.index = t),
|
|
(i.dataset.filename = a),
|
|
(this.showingThumbFilename = a),
|
|
this.player.debug.log(`Loading image: ${l}`),
|
|
(i.onload = () => this.showImage(i, n, e, t, a, !0)),
|
|
(this.loadingImage = i),
|
|
this.removeOldImages(i);
|
|
}
|
|
}),
|
|
e(this, "showImage", (e, t, i, s, n, a = !0) => {
|
|
this.player.debug.log(
|
|
`Showing thumb: ${n}. num: ${s}. qual: ${i}. newimg: ${a}`
|
|
),
|
|
this.setImageSizeAndOffset(e, t),
|
|
a &&
|
|
(this.currentImageContainer.appendChild(e),
|
|
(this.currentImageElement = e),
|
|
this.loadedImages.includes(n) || this.loadedImages.push(n)),
|
|
this.preloadNearby(s, !0)
|
|
.then(this.preloadNearby(s, !1))
|
|
.then(this.getHigherQuality(i, e, t, n));
|
|
}),
|
|
e(this, "removeOldImages", (e) => {
|
|
Array.from(this.currentImageContainer.children).forEach((t) => {
|
|
if ("img" !== t.tagName.toLowerCase()) return;
|
|
const i = this.usingSprites ? 500 : 1e3;
|
|
if (t.dataset.index !== e.dataset.index && !t.dataset.deleting) {
|
|
t.dataset.deleting = !0;
|
|
const { currentImageContainer: e } = this;
|
|
setTimeout(() => {
|
|
e.removeChild(t),
|
|
this.player.debug.log(
|
|
`Removing thumb: ${t.dataset.filename}`
|
|
);
|
|
}, i);
|
|
}
|
|
});
|
|
}),
|
|
e(
|
|
this,
|
|
"preloadNearby",
|
|
(e, t = !0) =>
|
|
new Promise((i) => {
|
|
setTimeout(() => {
|
|
const s = this.thumbnails[0].frames[e].text;
|
|
if (this.showingThumbFilename === s) {
|
|
let n;
|
|
n = t
|
|
? this.thumbnails[0].frames.slice(e)
|
|
: this.thumbnails[0].frames.slice(0, e).reverse();
|
|
let a = !1;
|
|
n.forEach((e) => {
|
|
const t = e.text;
|
|
if (t !== s && !this.loadedImages.includes(t)) {
|
|
(a = !0),
|
|
this.player.debug.log(
|
|
`Preloading thumb filename: ${t}`
|
|
);
|
|
const { urlPrefix: e } = this.thumbnails[0],
|
|
s = e + t,
|
|
n = new Image();
|
|
(n.src = s),
|
|
(n.onload = () => {
|
|
this.player.debug.log(
|
|
`Preloaded thumb filename: ${t}`
|
|
),
|
|
this.loadedImages.includes(t) ||
|
|
this.loadedImages.push(t),
|
|
i();
|
|
});
|
|
}
|
|
}),
|
|
a || i();
|
|
}
|
|
}, 300);
|
|
})
|
|
),
|
|
e(this, "getHigherQuality", (e, t, i, s) => {
|
|
if (e < this.thumbnails.length - 1) {
|
|
let n = t.naturalHeight;
|
|
this.usingSprites && (n = i.h),
|
|
n < this.thumbContainerHeight &&
|
|
setTimeout(() => {
|
|
this.showingThumbFilename === s &&
|
|
(this.player.debug.log(
|
|
`Showing higher quality thumb for: ${s}`
|
|
),
|
|
this.loadImage(e + 1));
|
|
}, 300);
|
|
}
|
|
}),
|
|
e(this, "toggleThumbContainer", (e = !1, t = !1) => {
|
|
const i =
|
|
this.player.config.classNames.previewThumbnails
|
|
.thumbContainerShown;
|
|
this.elements.thumb.container.classList.toggle(i, e),
|
|
!e &&
|
|
t &&
|
|
((this.showingThumb = null),
|
|
(this.showingThumbFilename = null));
|
|
}),
|
|
e(this, "toggleScrubbingContainer", (e = !1) => {
|
|
const t =
|
|
this.player.config.classNames.previewThumbnails
|
|
.scrubbingContainerShown;
|
|
this.elements.scrubbing.container.classList.toggle(t, e),
|
|
e ||
|
|
((this.showingThumb = null),
|
|
(this.showingThumbFilename = null));
|
|
}),
|
|
e(this, "determineContainerAutoSizing", () => {
|
|
(this.elements.thumb.imageContainer.clientHeight > 20 ||
|
|
this.elements.thumb.imageContainer.clientWidth > 20) &&
|
|
(this.sizeSpecifiedInCSS = !0);
|
|
}),
|
|
e(this, "setThumbContainerSizeAndPos", () => {
|
|
const { imageContainer: e } = this.elements.thumb;
|
|
if (this.sizeSpecifiedInCSS) {
|
|
if (e.clientHeight > 20 && e.clientWidth < 20) {
|
|
const t = Math.floor(e.clientHeight * this.thumbAspectRatio);
|
|
e.style.width = `${t}px`;
|
|
} else if (e.clientHeight < 20 && e.clientWidth > 20) {
|
|
const t = Math.floor(e.clientWidth / this.thumbAspectRatio);
|
|
e.style.height = `${t}px`;
|
|
}
|
|
} else {
|
|
const t = Math.floor(
|
|
this.thumbContainerHeight * this.thumbAspectRatio
|
|
);
|
|
(e.style.height = `${this.thumbContainerHeight}px`),
|
|
(e.style.width = `${t}px`);
|
|
}
|
|
this.setThumbContainerPos();
|
|
}),
|
|
e(this, "setThumbContainerPos", () => {
|
|
const e = this.player.elements.progress.getBoundingClientRect(),
|
|
t = this.player.elements.container.getBoundingClientRect(),
|
|
{ container: i } = this.elements.thumb,
|
|
s = t.left - e.left + 10,
|
|
n = t.right - e.left - i.clientWidth - 10,
|
|
a = this.mousePosX - e.left - i.clientWidth / 2,
|
|
l = Ge(a, s, n);
|
|
(i.style.left = `${l}px`),
|
|
i.style.setProperty("--preview-arrow-offset", a - l + "px");
|
|
}),
|
|
e(this, "setScrubbingContainerSize", () => {
|
|
const { width: e, height: t } = et(this.thumbAspectRatio, {
|
|
width: this.player.media.clientWidth,
|
|
height: this.player.media.clientHeight,
|
|
});
|
|
(this.elements.scrubbing.container.style.width = `${e}px`),
|
|
(this.elements.scrubbing.container.style.height = `${t}px`);
|
|
}),
|
|
e(this, "setImageSizeAndOffset", (e, t) => {
|
|
if (!this.usingSprites) return;
|
|
const i = this.thumbContainerHeight / t.h;
|
|
(e.style.height = e.naturalHeight * i + "px"),
|
|
(e.style.width = e.naturalWidth * i + "px"),
|
|
(e.style.left = `-${t.x * i}px`),
|
|
(e.style.top = `-${t.y * i}px`);
|
|
}),
|
|
(this.player = t),
|
|
(this.thumbnails = []),
|
|
(this.loaded = !1),
|
|
(this.lastMouseMoveTime = Date.now()),
|
|
(this.mouseDown = !1),
|
|
(this.loadedImages = []),
|
|
(this.elements = { thumb: {}, scrubbing: {} }),
|
|
this.load();
|
|
}
|
|
get enabled() {
|
|
return (
|
|
this.player.isHTML5 &&
|
|
this.player.isVideo &&
|
|
this.player.config.previewThumbnails.enabled
|
|
);
|
|
}
|
|
get currentImageContainer() {
|
|
return this.mouseDown
|
|
? this.elements.scrubbing.container
|
|
: this.elements.thumb.imageContainer;
|
|
}
|
|
get usingSprites() {
|
|
return Object.keys(this.thumbnails[0].frames[0]).includes("w");
|
|
}
|
|
get thumbAspectRatio() {
|
|
return this.usingSprites
|
|
? this.thumbnails[0].frames[0].w / this.thumbnails[0].frames[0].h
|
|
: this.thumbnails[0].width / this.thumbnails[0].height;
|
|
}
|
|
get thumbContainerHeight() {
|
|
if (this.mouseDown) {
|
|
const { height: e } = et(this.thumbAspectRatio, {
|
|
width: this.player.media.clientWidth,
|
|
height: this.player.media.clientHeight,
|
|
});
|
|
return e;
|
|
}
|
|
return this.sizeSpecifiedInCSS
|
|
? this.elements.thumb.imageContainer.clientHeight
|
|
: Math.floor(
|
|
this.player.media.clientWidth / this.thumbAspectRatio / 4
|
|
);
|
|
}
|
|
get currentImageElement() {
|
|
return this.mouseDown
|
|
? this.currentScrubbingImageElement
|
|
: this.currentThumbnailImageElement;
|
|
}
|
|
set currentImageElement(e) {
|
|
this.mouseDown
|
|
? (this.currentScrubbingImageElement = e)
|
|
: (this.currentThumbnailImageElement = e);
|
|
}
|
|
}
|
|
const it = {
|
|
insertElements(e, t) {
|
|
S.string(t)
|
|
? _(e, this.media, { src: t })
|
|
: S.array(t) &&
|
|
t.forEach((t) => {
|
|
_(e, this.media, t);
|
|
});
|
|
},
|
|
change(e) {
|
|
N(e, "sources.length")
|
|
? (de.cancelRequests.call(this),
|
|
this.destroy.call(
|
|
this,
|
|
() => {
|
|
(this.options.quality = []),
|
|
O(this.media),
|
|
(this.media = null),
|
|
S.element(this.elements.container) &&
|
|
this.elements.container.removeAttribute("class");
|
|
const { sources: t, type: i } = e,
|
|
[{ provider: s = _e.html5, src: n }] = t,
|
|
a = "html5" === s ? i : "div",
|
|
l = "html5" === s ? {} : { src: n };
|
|
Object.assign(this, {
|
|
provider: s,
|
|
type: i,
|
|
supported: K.check(i, s, this.config.playsinline),
|
|
media: $(a, l),
|
|
}),
|
|
this.elements.container.appendChild(this.media),
|
|
S.boolean(e.autoplay) && (this.config.autoplay = e.autoplay),
|
|
this.isHTML5 &&
|
|
(this.config.crossorigin &&
|
|
this.media.setAttribute("crossorigin", ""),
|
|
this.config.autoplay &&
|
|
this.media.setAttribute("autoplay", ""),
|
|
S.empty(e.poster) || (this.poster = e.poster),
|
|
this.config.loop.active &&
|
|
this.media.setAttribute("loop", ""),
|
|
this.config.muted && this.media.setAttribute("muted", ""),
|
|
this.config.playsinline &&
|
|
this.media.setAttribute("playsinline", "")),
|
|
Fe.addStyleHook.call(this),
|
|
this.isHTML5 && it.insertElements.call(this, "source", t),
|
|
(this.config.title = e.title),
|
|
Xe.setup.call(this),
|
|
this.isHTML5 &&
|
|
Object.keys(e).includes("tracks") &&
|
|
it.insertElements.call(this, "track", e.tracks),
|
|
(this.isHTML5 || (this.isEmbed && !this.supported.ui)) &&
|
|
Fe.build.call(this),
|
|
this.isHTML5 && this.media.load(),
|
|
S.empty(e.previewThumbnails) ||
|
|
(Object.assign(
|
|
this.config.previewThumbnails,
|
|
e.previewThumbnails
|
|
),
|
|
this.previewThumbnails &&
|
|
this.previewThumbnails.loaded &&
|
|
(this.previewThumbnails.destroy(),
|
|
(this.previewThumbnails = null)),
|
|
this.config.previewThumbnails.enabled &&
|
|
(this.previewThumbnails = new tt(this))),
|
|
this.fullscreen.update();
|
|
},
|
|
!0
|
|
))
|
|
: this.debug.warn("Invalid source format");
|
|
},
|
|
};
|
|
class st {
|
|
constructor(t, i) {
|
|
if (
|
|
(e(this, "play", () =>
|
|
S.function(this.media.play)
|
|
? (this.ads &&
|
|
this.ads.enabled &&
|
|
this.ads.managerPromise
|
|
.then(() => this.ads.play())
|
|
.catch(() => ie(this.media.play())),
|
|
this.media.play())
|
|
: null
|
|
),
|
|
e(this, "pause", () =>
|
|
this.playing && S.function(this.media.pause)
|
|
? this.media.pause()
|
|
: null
|
|
),
|
|
e(this, "togglePlay", (e) =>
|
|
(S.boolean(e) ? e : !this.playing) ? this.play() : this.pause()
|
|
),
|
|
e(this, "stop", () => {
|
|
this.isHTML5
|
|
? (this.pause(), this.restart())
|
|
: S.function(this.media.stop) && this.media.stop();
|
|
}),
|
|
e(this, "restart", () => {
|
|
this.currentTime = 0;
|
|
}),
|
|
e(this, "rewind", (e) => {
|
|
this.currentTime -= S.number(e) ? e : this.config.seekTime;
|
|
}),
|
|
e(this, "forward", (e) => {
|
|
this.currentTime += S.number(e) ? e : this.config.seekTime;
|
|
}),
|
|
e(this, "increaseVolume", (e) => {
|
|
const t = this.media.muted ? 0 : this.volume;
|
|
this.volume = t + (S.number(e) ? e : 0);
|
|
}),
|
|
e(this, "decreaseVolume", (e) => {
|
|
this.increaseVolume(-e);
|
|
}),
|
|
e(this, "airplay", () => {
|
|
K.airplay && this.media.webkitShowPlaybackTargetPicker();
|
|
}),
|
|
e(this, "toggleControls", (e) => {
|
|
if (this.supported.ui && !this.isAudio) {
|
|
const t = F(
|
|
this.elements.container,
|
|
this.config.classNames.hideControls
|
|
),
|
|
i = void 0 === e ? void 0 : !e,
|
|
s = R(
|
|
this.elements.container,
|
|
this.config.classNames.hideControls,
|
|
i
|
|
);
|
|
if (
|
|
(s &&
|
|
S.array(this.config.controls) &&
|
|
this.config.controls.includes("settings") &&
|
|
!S.empty(this.config.settings) &&
|
|
Pe.toggleMenu.call(this, !1),
|
|
s !== t)
|
|
) {
|
|
const e = s ? "controlshidden" : "controlsshown";
|
|
Z.call(this, this.media, e);
|
|
}
|
|
return !s;
|
|
}
|
|
return !1;
|
|
}),
|
|
e(this, "on", (e, t) => {
|
|
X.call(this, this.elements.container, e, t);
|
|
}),
|
|
e(this, "once", (e, t) => {
|
|
G.call(this, this.elements.container, e, t);
|
|
}),
|
|
e(this, "off", (e, t) => {
|
|
J(this.elements.container, e, t);
|
|
}),
|
|
e(this, "destroy", (e, t = !1) => {
|
|
if (!this.ready) return;
|
|
const i = () => {
|
|
(document.body.style.overflow = ""),
|
|
(this.embed = null),
|
|
t
|
|
? (Object.keys(this.elements).length &&
|
|
(O(this.elements.buttons.play),
|
|
O(this.elements.captions),
|
|
O(this.elements.controls),
|
|
O(this.elements.wrapper),
|
|
(this.elements.buttons.play = null),
|
|
(this.elements.captions = null),
|
|
(this.elements.controls = null),
|
|
(this.elements.wrapper = null)),
|
|
S.function(e) && e())
|
|
: (ee.call(this),
|
|
de.cancelRequests.call(this),
|
|
q(this.elements.original, this.elements.container),
|
|
Z.call(this, this.elements.original, "destroyed", !0),
|
|
S.function(e) && e.call(this.elements.original),
|
|
(this.ready = !1),
|
|
setTimeout(() => {
|
|
(this.elements = null), (this.media = null);
|
|
}, 200));
|
|
};
|
|
this.stop(),
|
|
clearTimeout(this.timers.loading),
|
|
clearTimeout(this.timers.controls),
|
|
clearTimeout(this.timers.resized),
|
|
this.isHTML5
|
|
? (Fe.toggleNativeControls.call(this, !0), i())
|
|
: this.isYouTube
|
|
? (clearInterval(this.timers.buffering),
|
|
clearInterval(this.timers.playing),
|
|
null !== this.embed &&
|
|
S.function(this.embed.destroy) &&
|
|
this.embed.destroy(),
|
|
i())
|
|
: this.isVimeo &&
|
|
(null !== this.embed && this.embed.unload().then(i),
|
|
setTimeout(i, 200));
|
|
}),
|
|
e(this, "supports", (e) => K.mime.call(this, e)),
|
|
(this.timers = {}),
|
|
(this.ready = !1),
|
|
(this.loading = !1),
|
|
(this.failed = !1),
|
|
(this.touch = K.touch),
|
|
(this.media = t),
|
|
S.string(this.media) &&
|
|
(this.media = document.querySelectorAll(this.media)),
|
|
((window.jQuery && this.media instanceof jQuery) ||
|
|
S.nodeList(this.media) ||
|
|
S.array(this.media)) &&
|
|
(this.media = this.media[0]),
|
|
(this.config = x(
|
|
{},
|
|
Le,
|
|
st.defaults,
|
|
i || {},
|
|
(() => {
|
|
try {
|
|
return JSON.parse(this.media.getAttribute("data-plyr-config"));
|
|
} catch (e) {
|
|
return {};
|
|
}
|
|
})()
|
|
)),
|
|
(this.elements = {
|
|
container: null,
|
|
fullscreen: null,
|
|
captions: null,
|
|
buttons: {},
|
|
display: {},
|
|
progress: {},
|
|
inputs: {},
|
|
settings: { popup: null, menu: null, panels: {}, buttons: {} },
|
|
}),
|
|
(this.captions = {
|
|
active: null,
|
|
currentTrack: -1,
|
|
meta: new WeakMap(),
|
|
}),
|
|
(this.fullscreen = { active: !1 }),
|
|
(this.options = { speed: [], quality: [] }),
|
|
(this.debug = new De(this.config.debug)),
|
|
this.debug.log("Config", this.config),
|
|
this.debug.log("Support", K),
|
|
S.nullOrUndefined(this.media) || !S.element(this.media))
|
|
)
|
|
return void this.debug.error(
|
|
"Setup failed: no suitable element passed"
|
|
);
|
|
if (this.media.plyr)
|
|
return void this.debug.warn("Target already setup");
|
|
if (!this.config.enabled)
|
|
return void this.debug.error("Setup failed: disabled by config");
|
|
if (!K.check().api)
|
|
return void this.debug.error("Setup failed: no support");
|
|
const s = this.media.cloneNode(!0);
|
|
(s.autoplay = !1), (this.elements.original = s);
|
|
const n = this.media.tagName.toLowerCase();
|
|
let a = null,
|
|
l = null;
|
|
switch (n) {
|
|
case "div":
|
|
if (((a = this.media.querySelector("iframe")), S.element(a))) {
|
|
if (
|
|
((l = Me(a.getAttribute("src"))),
|
|
(this.provider = (function (e) {
|
|
return /^(https?:\/\/)?(www\.)?(youtube\.com|youtube-nocookie\.com|youtu\.?be)\/.+$/.test(
|
|
e
|
|
)
|
|
? _e.youtube
|
|
: /^https?:\/\/player.vimeo.com\/video\/\d{0,9}(?=\b|\/)/.test(
|
|
e
|
|
)
|
|
? _e.vimeo
|
|
: null;
|
|
})(l.toString())),
|
|
(this.elements.container = this.media),
|
|
(this.media = a),
|
|
(this.elements.container.className = ""),
|
|
l.search.length)
|
|
) {
|
|
const e = ["1", "true"];
|
|
e.includes(l.searchParams.get("autoplay")) &&
|
|
(this.config.autoplay = !0),
|
|
e.includes(l.searchParams.get("loop")) &&
|
|
(this.config.loop.active = !0),
|
|
this.isYouTube
|
|
? ((this.config.playsinline = e.includes(
|
|
l.searchParams.get("playsinline")
|
|
)),
|
|
(this.config.youtube.hl = l.searchParams.get("hl")))
|
|
: (this.config.playsinline = !0);
|
|
}
|
|
} else (this.provider = this.media.getAttribute(this.config.attributes.embed.provider)), this.media.removeAttribute(this.config.attributes.embed.provider);
|
|
if (
|
|
S.empty(this.provider) ||
|
|
!Object.values(_e).includes(this.provider)
|
|
)
|
|
return void this.debug.error("Setup failed: Invalid provider");
|
|
this.type = je;
|
|
break;
|
|
case "video":
|
|
case "audio":
|
|
(this.type = n),
|
|
(this.provider = _e.html5),
|
|
this.media.hasAttribute("crossorigin") &&
|
|
(this.config.crossorigin = !0),
|
|
this.media.hasAttribute("autoplay") &&
|
|
(this.config.autoplay = !0),
|
|
(this.media.hasAttribute("playsinline") ||
|
|
this.media.hasAttribute("webkit-playsinline")) &&
|
|
(this.config.playsinline = !0),
|
|
this.media.hasAttribute("muted") && (this.config.muted = !0),
|
|
this.media.hasAttribute("loop") && (this.config.loop.active = !0);
|
|
break;
|
|
default:
|
|
return void this.debug.error("Setup failed: unsupported type");
|
|
}
|
|
(this.supported = K.check(this.type, this.provider)),
|
|
this.supported.api
|
|
? ((this.eventListeners = []),
|
|
(this.listeners = new Ve(this)),
|
|
(this.storage = new we(this)),
|
|
(this.media.plyr = this),
|
|
S.element(this.elements.container) ||
|
|
((this.elements.container = $("div")),
|
|
L(this.media, this.elements.container)),
|
|
Fe.migrateStyles.call(this),
|
|
Fe.addStyleHook.call(this),
|
|
Xe.setup.call(this),
|
|
this.config.debug &&
|
|
X.call(
|
|
this,
|
|
this.elements.container,
|
|
this.config.events.join(" "),
|
|
(e) => {
|
|
this.debug.log(`event: ${e.type}`);
|
|
}
|
|
),
|
|
(this.fullscreen = new He(this)),
|
|
(this.isHTML5 || (this.isEmbed && !this.supported.ui)) &&
|
|
Fe.build.call(this),
|
|
this.listeners.container(),
|
|
this.listeners.global(),
|
|
this.config.ads.enabled && (this.ads = new Je(this)),
|
|
this.isHTML5 &&
|
|
this.config.autoplay &&
|
|
this.once("canplay", () => ie(this.play())),
|
|
(this.lastSeekTime = 0),
|
|
this.config.previewThumbnails.enabled &&
|
|
(this.previewThumbnails = new tt(this)))
|
|
: this.debug.error("Setup failed: no support");
|
|
}
|
|
get isHTML5() {
|
|
return this.provider === _e.html5;
|
|
}
|
|
get isEmbed() {
|
|
return this.isYouTube || this.isVimeo;
|
|
}
|
|
get isYouTube() {
|
|
return this.provider === _e.youtube;
|
|
}
|
|
get isVimeo() {
|
|
return this.provider === _e.vimeo;
|
|
}
|
|
get isVideo() {
|
|
return this.type === je;
|
|
}
|
|
get isAudio() {
|
|
return this.type === Oe;
|
|
}
|
|
get playing() {
|
|
return Boolean(this.ready && !this.paused && !this.ended);
|
|
}
|
|
get paused() {
|
|
return Boolean(this.media.paused);
|
|
}
|
|
get stopped() {
|
|
return Boolean(this.paused && 0 === this.currentTime);
|
|
}
|
|
get ended() {
|
|
return Boolean(this.media.ended);
|
|
}
|
|
set currentTime(e) {
|
|
if (!this.duration) return;
|
|
const t = S.number(e) && e > 0;
|
|
(this.media.currentTime = t ? Math.min(e, this.duration) : 0),
|
|
this.debug.log(`Seeking to ${this.currentTime} seconds`);
|
|
}
|
|
get currentTime() {
|
|
return Number(this.media.currentTime);
|
|
}
|
|
get buffered() {
|
|
const { buffered: e } = this.media;
|
|
return S.number(e)
|
|
? e
|
|
: e && e.length && this.duration > 0
|
|
? e.end(0) / this.duration
|
|
: 0;
|
|
}
|
|
get seeking() {
|
|
return Boolean(this.media.seeking);
|
|
}
|
|
get duration() {
|
|
const e = parseFloat(this.config.duration),
|
|
t = (this.media || {}).duration,
|
|
i = S.number(t) && t !== 1 / 0 ? t : 0;
|
|
return e || i;
|
|
}
|
|
set volume(e) {
|
|
let t = e;
|
|
S.string(t) && (t = Number(t)),
|
|
S.number(t) || (t = this.storage.get("volume")),
|
|
S.number(t) || ({ volume: t } = this.config),
|
|
t > 1 && (t = 1),
|
|
t < 0 && (t = 0),
|
|
(this.config.volume = t),
|
|
(this.media.volume = t),
|
|
!S.empty(e) && this.muted && t > 0 && (this.muted = !1);
|
|
}
|
|
get volume() {
|
|
return Number(this.media.volume);
|
|
}
|
|
set muted(e) {
|
|
let t = e;
|
|
S.boolean(t) || (t = this.storage.get("muted")),
|
|
S.boolean(t) || (t = this.config.muted),
|
|
(this.config.muted = t),
|
|
(this.media.muted = t);
|
|
}
|
|
get muted() {
|
|
return Boolean(this.media.muted);
|
|
}
|
|
get hasAudio() {
|
|
return (
|
|
!this.isHTML5 ||
|
|
!!this.isAudio ||
|
|
Boolean(this.media.mozHasAudio) ||
|
|
Boolean(this.media.webkitAudioDecodedByteCount) ||
|
|
Boolean(this.media.audioTracks && this.media.audioTracks.length)
|
|
);
|
|
}
|
|
set speed(e) {
|
|
let t = null;
|
|
S.number(e) && (t = e),
|
|
S.number(t) || (t = this.storage.get("speed")),
|
|
S.number(t) || (t = this.config.speed.selected);
|
|
const { minimumSpeed: i, maximumSpeed: s } = this;
|
|
(t = Ge(t, i, s)),
|
|
(this.config.speed.selected = t),
|
|
setTimeout(() => {
|
|
this.media && (this.media.playbackRate = t);
|
|
}, 0);
|
|
}
|
|
get speed() {
|
|
return Number(this.media.playbackRate);
|
|
}
|
|
get minimumSpeed() {
|
|
return this.isYouTube
|
|
? Math.min(...this.options.speed)
|
|
: this.isVimeo
|
|
? 0.5
|
|
: 0.0625;
|
|
}
|
|
get maximumSpeed() {
|
|
return this.isYouTube
|
|
? Math.max(...this.options.speed)
|
|
: this.isVimeo
|
|
? 2
|
|
: 16;
|
|
}
|
|
set quality(e) {
|
|
const t = this.config.quality,
|
|
i = this.options.quality;
|
|
if (!i.length) return;
|
|
let s = [
|
|
!S.empty(e) && Number(e),
|
|
this.storage.get("quality"),
|
|
t.selected,
|
|
t.default,
|
|
].find(S.number),
|
|
n = !0;
|
|
if (!i.includes(s)) {
|
|
const e = ne(i, s);
|
|
this.debug.warn(
|
|
`Unsupported quality option: ${s}, using ${e} instead`
|
|
),
|
|
(s = e),
|
|
(n = !1);
|
|
}
|
|
(t.selected = s),
|
|
(this.media.quality = s),
|
|
n && this.storage.set({ quality: s });
|
|
}
|
|
get quality() {
|
|
return this.media.quality;
|
|
}
|
|
set loop(e) {
|
|
const t = S.boolean(e) ? e : this.config.loop.active;
|
|
(this.config.loop.active = t), (this.media.loop = t);
|
|
}
|
|
get loop() {
|
|
return Boolean(this.media.loop);
|
|
}
|
|
set source(e) {
|
|
it.change.call(this, e);
|
|
}
|
|
get source() {
|
|
return this.media.currentSrc;
|
|
}
|
|
get download() {
|
|
const { download: e } = this.config.urls;
|
|
return S.url(e) ? e : this.source;
|
|
}
|
|
set download(e) {
|
|
S.url(e) &&
|
|
((this.config.urls.download = e), Pe.setDownloadUrl.call(this));
|
|
}
|
|
set poster(e) {
|
|
this.isVideo
|
|
? Fe.setPoster.call(this, e, !1).catch(() => { })
|
|
: this.debug.warn("Poster can only be set for video");
|
|
}
|
|
get poster() {
|
|
return this.isVideo
|
|
? this.media.getAttribute("poster") ||
|
|
this.media.getAttribute("data-poster")
|
|
: null;
|
|
}
|
|
get ratio() {
|
|
if (!this.isVideo) return null;
|
|
const e = oe(ce.call(this));
|
|
return S.array(e) ? e.join(":") : e;
|
|
}
|
|
set ratio(e) {
|
|
this.isVideo
|
|
? S.string(e) && re(e)
|
|
? ((this.config.ratio = oe(e)), ue.call(this))
|
|
: this.debug.error(`Invalid aspect ratio specified (${e})`)
|
|
: this.debug.warn("Aspect ratio can only be set for video");
|
|
}
|
|
set autoplay(e) {
|
|
this.config.autoplay = S.boolean(e) ? e : this.config.autoplay;
|
|
}
|
|
get autoplay() {
|
|
return Boolean(this.config.autoplay);
|
|
}
|
|
toggleCaptions(e) {
|
|
xe.toggle.call(this, e, !1);
|
|
}
|
|
set currentTrack(e) {
|
|
xe.set.call(this, e, !1), xe.setup.call(this);
|
|
}
|
|
get currentTrack() {
|
|
const { toggled: e, currentTrack: t } = this.captions;
|
|
return e ? t : -1;
|
|
}
|
|
set language(e) {
|
|
xe.setLanguage.call(this, e, !1);
|
|
}
|
|
get language() {
|
|
return (xe.getCurrentTrack.call(this) || {}).language;
|
|
}
|
|
set pip(e) {
|
|
if (!K.pip) return;
|
|
const t = S.boolean(e) ? e : !this.pip;
|
|
S.function(this.media.webkitSetPresentationMode) &&
|
|
this.media.webkitSetPresentationMode(t ? Ie : $e),
|
|
S.function(this.media.requestPictureInPicture) &&
|
|
(!this.pip && t
|
|
? this.media.requestPictureInPicture()
|
|
: this.pip && !t && document.exitPictureInPicture());
|
|
}
|
|
get pip() {
|
|
return K.pip
|
|
? S.empty(this.media.webkitPresentationMode)
|
|
? this.media === document.pictureInPictureElement
|
|
: this.media.webkitPresentationMode === Ie
|
|
: null;
|
|
}
|
|
setPreviewThumbnails(e) {
|
|
this.previewThumbnails &&
|
|
this.previewThumbnails.loaded &&
|
|
(this.previewThumbnails.destroy(), (this.previewThumbnails = null)),
|
|
Object.assign(this.config.previewThumbnails, e),
|
|
this.config.previewThumbnails.enabled &&
|
|
(this.previewThumbnails = new tt(this));
|
|
}
|
|
static supported(e, t) {
|
|
return K.check(e, t);
|
|
}
|
|
static loadSprite(e, t) {
|
|
return ke(e, t);
|
|
}
|
|
static setup(e, t = {}) {
|
|
let i = null;
|
|
return (
|
|
S.string(e)
|
|
? (i = Array.from(document.querySelectorAll(e)))
|
|
: S.nodeList(e)
|
|
? (i = Array.from(e))
|
|
: S.array(e) && (i = e.filter(S.element)),
|
|
S.empty(i) ? null : i.map((e) => new st(e, t))
|
|
);
|
|
}
|
|
}
|
|
var nt;
|
|
return (st.defaults = ((nt = Le), JSON.parse(JSON.stringify(nt)))), st;
|
|
});
|
|
//# sourceMappingURL=plyr.min.js.map
|