UNPKG

embedia-vue

Version:

A vue component package to embed videos such as TikTok, YouTube/Shorts, Twitter/X, Vimeo, and Dailymotion.

251 lines (250 loc) 9.63 kB
import { ref as y, onMounted as b, watch as v, openBlock as g, createElementBlock as x, normalizeClass as $, normalizeStyle as C, pushScopeId as E, popScopeId as _, createElementVNode as k } from "vue"; let I = 1; const T = (e) => { const t = e.match(/(?:video|hub)\/([^_]+)/) || e.match(/(?:^|\/)([a-z0-9]+)(?:_[\w-]*)?$/i); if (t && t[1]) return t[1]; throw new Error("Invalid Dailymotion video URL"); }, U = (e, t, o) => { const i = e.videoUrl, n = T(i), l = e.width || 640, r = e.height || 360; window.handleDailymotionResponse = (a) => { if (console.log("Dailymotion Response:", a), a.html) { const d = document.createElement("div"); d.className = `${o} custom-dailymotion`, d.innerHTML = a.html; const s = d.querySelector("iframe"); if (s) { s.style.width = `${l}px`, s.style.height = `${r}px`; const m = s.getAttribute("allow"); m ? s.setAttribute("allow", m.replace("autoplay", "")) : s.setAttribute("allow", "fullscreen; picture-in-picture; muted"); } t.appendChild(d); } }; const c = document.createElement("script"); c.src = `https://www.dailymotion.com/services/oembed?url=https://www.dailymotion.com/video/${n}&maxwidth=${l}&maxheight=${r}&format=json&callback=handleDailymotionResponse`, document.body.appendChild(c); }, V = (e) => { const t = e.match(/\/(\d+)/); return t && t[1] ? t[1] : (console.error("Invalid Vimeo video URL"), ""); }, S = (e, t, o) => { const i = e.width || 640, n = e.height || 360, l = e.controls !== void 0 ? e.controls : !0, r = e.autoplay === !0, c = e.loop === "true", a = e.fullscreen === !0, d = V(e.videoUrl), s = document.createElement("div"); s.className = `video-${d} ${o}`, s.dataset.eWidth = i, s.dataset.eHeight = n, s.dataset.efullscreen = a, s.dataset.eVideoId = d, t.appendChild(s); const m = document.createElement("script"); return m.src = "https://player.vimeo.com/api/player.js", m.async = !0, m.onload = () => { new window.Vimeo.Player(s, { id: d, width: i, height: n, controls: l, // Show controls autoplay: r, // Autoplay based on the passed value (true/false) muted: r, // Mute if autoplay is true (to comply with browser restrictions) loop: c, // Loop based on the loop value fullscreen: a }).ready().then(() => { if (console.log("Vimeo player is ready"), a === !1) { const u = s.querySelector("iframe"), w = u.contentDocument || u.contentWindow.document, f = setInterval(() => { const p = w.querySelector(".vimeo-control-bar .fullscreen"); p && (p.style.display = "none", clearInterval(f)); }, 100); } }).catch((u) => { console.error("Error loading Vimeo player:", u); }); }, document.body.appendChild(m), () => { s && (s.innerHTML = ""), m && m.parentNode && document.body.removeChild(m); }; }, M = (e, t, o) => { const i = (n) => { const l = /\/status\/(\d+)/, r = n.match(l); return r && r[1] ? r[1] : null; }; try { const n = e.videoUrl, l = i(n), r = document.createElement("div"); r.className = `video-${I} ${o}`, r.id = `tweet-${l}`; const c = document.createElement("script"); c.src = "https://platform.twitter.com/widgets.js", c.charset = "utf-8", c.async = !0, c.addEventListener("load", () => { window.twttr.widgets.createTweet(l, r); }), t.appendChild(r), t.appendChild(c); } catch (n) { console.error("Error embedding Twitter content:", n); } }, N = (e, t, o) => { const i = (n) => { n = n.replace("x.com", "twitter.com"); const l = /\/(?:i\/)?status\/(\d+)/, r = n.match(l); return r ? r[1] : null; }; try { if (!(t instanceof Node)) { console.error("Container is not a valid DOM node."); return; } const n = e.videoUrl, l = i(n), r = document.createElement("blockquote"); r.className = `twitter-tweet ${o}`, r.innerHTML = ` <p lang="en" style="min-width"> <a href="https://twitter.com/i/status/${l}" style="display: inline-block; min-width: ${e.width}px;"> </a> </p> `, t.appendChild(r); const c = document.createElement("script"); c.src = "https://platform.x.com/widgets.js", c.charset = "utf-8", c.async = !0, c.addEventListener("load", () => { window.twttr.widgets.load(); }), t.appendChild(c); } catch (n) { console.error("Error embedding Twitter content:", n); } }, h = /* @__PURE__ */ new Map(), R = (e, t, o) => { const i = e.videoUrl; if (h.has(i) || h.has(i)) return; h.set(i, !0); const n = e.width || "100%", l = e.height || "100%", r = new XMLHttpRequest(); r.open("GET", `https://www.tiktok.com/oembed?url=${encodeURIComponent(i)}`, !0), r.onload = function() { if (r.status >= 200 && r.status < 300) { const c = JSON.parse(r.responseText); c.html && (c.html = c.html.replace(/<script[^>]*>.*<\/script>/gi, "")); const a = document.createElement("div"), d = Date.now(); if (a.className = `video-${d} ${o}`, a.style.width = n, a.style.height = l, a.innerHTML = c.html, !document.querySelector('script[src="https://www.tiktok.com/embed.js"]')) { const s = document.createElement("script"); s.src = "https://www.tiktok.com/embed.js", document.body.appendChild(s); } t ? t.appendChild(a) : document.body && document.body.appendChild(a); } else console.error("Failed to fetch TikTok oEmbed data: " + r.statusText); }, r.onerror = function() { console.error("An error occurred while embedding TikTok video."); }, r.send(); }, D = (e) => { const t = e.match(/(?:shorts\/|v=)([a-zA-Z0-9_-]{11})/); if (t && t[1]) return t[1]; const o = e.match(/(\?v=|\/embed\/|\/watch\?v=|\/v\/|\/e\/|youtu.be\/)([^#&?]*).*/); if (o && o[2].length === 11) return o[2]; throw new Error("Invalid YouTube video URL"); }, L = (e, t, o) => { if (!t) { console.error("Container element not found."); return; } const i = e.autoplay ? 1 : 0, n = e.autoplay || e.muted ? 1 : 0, l = e.autoplay || e.loop ? 1 : 0, r = D(e.videoUrl), c = document.createElement("iframe"); c.src = `https://www.youtube.com/embed/${r}?autoplay=${i}&mute=${n}&loop=${l ? 1 : 0}&controls=${e.controls ? 1 : 0}`, c.width = e.width || 640, c.height = e.height || 360, c.frameborder = "0", c.style.border = "none", e.fullscreen && c.setAttribute("allow", "fullscreen"), c.className = o, t.appendChild(c); }, q = (e) => { var i; const t = ((i = e.cssname) == null ? void 0 : i.trim()) || ""; if (!t.match(/^[a-zA-Z_][\w-]*$/)) throw console.error("Invalid class name:", t), new Error("Invalid class name"); if (!document.querySelector(`#default-style-${t}`)) { const n = document.createElement("style"); n.id = `default-style-${t}`, n.textContent = ` .${t} { display: flex; max-width: 1920px !important; justify-content: center; align-items: center; min-width: 256px; min-height: 144px; margin: auto; } body { display: block !important; } `, document.head.appendChild(n); } const o = document.querySelector(`.${t}`); if (!o) throw console.error("Container not found for class:", t), new Error("Container not found"); for (; o.firstChild; ) o.removeChild(o.firstChild); if (e.videoUrl.includes("youtube.com") || e.videoUrl.includes("youtu.be")) L(e, o, t); else if (e.videoUrl.includes("tiktok.com") || e.videoUrl.includes("tiktok")) R(e, o, t); else if (e.videoUrl.includes("twitter.com")) M(e, o, t); else if (e.videoUrl.includes("x.com")) N(e, o, t); else if (e.videoUrl.includes("vimeo.com")) S(e, o, t); else if (e.videoUrl.includes("dailymotion.com") || e.videoUrl.includes("dailymotion")) U(e, o, t); else throw new Error("Invalid video URL"); }; const A = (e, t) => { const o = e.__vccOpts || e; for (const [i, n] of t) o[i] = n; return o; }, j = { name: "EmbediaVue", props: { clip: { type: String, required: !0 }, width: { type: [Number, String], default: 1366 // max default width }, height: { type: [Number, String], default: 768 // max default height }, autoplay: { type: Boolean, default: !1 }, fullscreen: { type: Boolean, default: !1 }, controls: { type: Boolean, default: !0 }, cssname: { type: String, default: "default-video-class" } }, setup(e) { const t = y("56.25%"); b(() => { q({ videoUrl: e.clip, width: e.width, height: e.height, autoplay: e.autoplay, fullscreen: e.fullscreen, controls: e.controls, cssname: e.cssname }), o(e.width, e.height); }), v(() => [e.width, e.height], ([i, n]) => { o(i, n); }, { immediate: !0 }); function o(i, n) { i && n ? t.value = `${n / i * 100}%` : t.value = "56.25%"; } return { aspectRatio: t }; } }, B = (e) => (E("data-v-1b3c3886"), e = e(), _(), e), H = /* @__PURE__ */ B(() => /* @__PURE__ */ k("div", { class: "video-content" }, null, -1)), W = [ H ]; function z(e, t, o, i, n, l) { return g(), x("div", { class: $([o.cssname, "responsive-container"]), style: C({ "--aspect-ratio": i.aspectRatio, width: "auto", maxWidth: "100%" }) }, W, 6); } const Y = /* @__PURE__ */ A(j, [["render", z], ["__scopeId", "data-v-1b3c3886"]]); export { Y as EmbediaVue };