UNPKG

@tidal-music/player

Version:
225 lines (224 loc) 7.12 kB
import { e as W, B as M, a as x, x as O } from "./index-C6ZwgBzI.js"; import { g as V } from "./_commonjsHelpers-DaMA6jEr.js"; var w, P; function q() { return P || (P = 1, w = /* @__PURE__ */ function() { function n(e, t, a, i, s) { return e < t || a < t ? e > a ? a + 1 : e + 1 : i === s ? t : t + 1; } return function(e, t) { if (e === t) return 0; if (e.length > t.length) { var a = e; e = t, t = a; } for (var i = e.length, s = t.length; i > 0 && e.charCodeAt(i - 1) === t.charCodeAt(s - 1); ) i--, s--; for (var c = 0; c < i && e.charCodeAt(c) === t.charCodeAt(c); ) c++; if (i -= c, s -= c, i === 0 || s < 3) return s; var o = 0, r, u, h, d, m, l, f, p, D, I, E, L, v = []; for (r = 0; r < i; r++) v.push(r + 1), v.push(e.charCodeAt(c + r)); for (var A = v.length - 1; o < s - 3; ) for (D = t.charCodeAt(c + (u = o)), I = t.charCodeAt(c + (h = o + 1)), E = t.charCodeAt(c + (d = o + 2)), L = t.charCodeAt(c + (m = o + 3)), l = o += 4, r = 0; r < A; r += 2) f = v[r], p = v[r + 1], u = n(f, u, h, D, p), h = n(u, h, d, I, p), d = n(h, d, m, E, p), l = n(d, m, l, L, p), v[r] = l, m = d, d = h, h = u, u = f; for (; o < s; ) for (D = t.charCodeAt(c + (u = o)), l = ++o, r = 0; r < A; r += 2) f = v[r], v[r] = l = n(f, u, l, D, v[r + 1]), u = f; return l; }; }()), w; } var B = q(); const N = /* @__PURE__ */ V(B); function U(n) { return new CustomEvent("device-change", { detail: { devices: n } }); } const g = M.parse(navigator.userAgent); class b { controllableVolume; id; name; nativeDeviceId; type; webDeviceId; constructor({ controllableVolume: e, name: t, nativeDeviceId: a, type: i, webDeviceId: s }) { this.name = t, this.id = a === "default" && s === "default" ? "default" : O(), this.nativeDeviceId = a, this.webDeviceId = s, this.type = i, this.controllableVolume = e !== !1; } } function y(n) { if (j(n)) return "windowsCommunication"; if ("id" in n && n.id === "BuiltInSpeakerDevice") return "builtIn"; if ("type" in n && n.type === "airplay") return "airplay"; if ("label" in n) { const e = n.label.toLowerCase(); if (e.includes("bluetooth")) return "bluetooth"; if (e.includes("displayport")) return "displayPort"; if (e.includes("hdmi")) return "hdmi"; if (e.includes("usb")) return "usb"; if (e.includes("built-in")) return "builtIn"; if (e.includes("airplay")) return "airplay"; } } function C(n, e) { const t = e.toLowerCase(); let a = n; return t.includes("mac") && (a = (n.split("(")[0] ?? "").trim()), a; } function j(n) { let e; return "label" in n && (e = n.label), "name" in n && (e = n.name), e?.startsWith("Communications") ?? !1; } function S(n, e) { if (e = C(e, g.os.name || ""), [...n].length === 0 || e === "") return; const t = [...n].find((i) => i.name === e); if (t) return t; const a = [...n].filter((i) => e.includes(i.name) || i.name.includes(e)).map((i) => ({ device: i, distance: N(i.name, e) })).sort((i, s) => i.distance - s.distance).reverse(); if (a.length > 0) { const i = a.pop(); if (i && i.distance <= 16) return i.device; } } class T { #i; #n; #a = "shared"; #e; #t; #s; outputDevices; constructor() { this.#t = /* @__PURE__ */ new Set(), this.#s = /* @__PURE__ */ new Set(), this.#e = new EventTarget(), this.#n = new b({ name: "System Default", nativeDeviceId: "default", type: "systemDefault", webDeviceId: "default" }), this.#i = this.#n, this.outputDevices = /* @__PURE__ */ new Set([this.#n]), this.hydrateWebDevices().then().catch(console.error), navigator.mediaDevices.addEventListener("devicechange", () => { this.hydrateWebDevices().then().catch(console.error); }), this.#e.addEventListener("native-devices", (e) => { this.#t = new Set(e.detail), this.queueUpdate().then().catch(console.error); }), this.#e.addEventListener("web-devices", (e) => { this.#s = new Set(e.detail), this.queueUpdate().then().catch(console.error); }); } addNativeDevices(e) { this.#e.dispatchEvent( new CustomEvent("native-devices", { detail: e }) ); } addWebDevices(e) { e = e.filter((t) => t.deviceId !== "default"), this.#e.dispatchEvent( new CustomEvent("web-devices", { detail: e }) ); } emitDeviceChange() { W.dispatchEvent(U([...this.outputDevices])); } getNativeDevice(e) { return [...this.#t].find((t) => t.id === e); } async hydrateWebDevices() { const t = (await navigator.mediaDevices.enumerateDevices()).filter((a) => a.kind === "audiooutput"); this.addWebDevices(t); } mergeDevices() { [...this.outputDevices].filter((e) => e.id !== "default").forEach((e) => { e.nativeDeviceId = void 0, e.webDeviceId = void 0; }), this.#t.forEach((e) => { const t = S(this.outputDevices, e.name); t ? (t.nativeDeviceId = e.id, t.controllableVolume = e.controllableVolume, t.type = y(e) || t.type) : this.outputDevices.add( new b({ controllableVolume: e.controllableVolume, name: C(e.name, g.os.name || ""), nativeDeviceId: e.id, type: y(e) }) ); }), this.#s.forEach((e) => { const t = S(this.outputDevices, e.label); t ? (t.webDeviceId = e.deviceId, t.type = y(e) || t.type) : this.outputDevices.add( new b({ name: C(e.label, g.os.name || ""), type: y(e), webDeviceId: e.deviceId }) ); }), [...this.outputDevices].filter( (e) => e.webDeviceId === void 0 && e.nativeDeviceId === void 0 || e.type === "airplay" || e.type === "windowsCommunication" ).forEach((e) => this.outputDevices.delete(e)); } async queueUpdate() { const e = new Promise( (i) => this.#e.addEventListener( "native-devices", (s) => i(s.detail), { once: !0 } ) ), t = new Promise( (i) => this.#e.addEventListener( "web-devices", (s) => i(s.detail), { once: !0 } ) ), a = (i) => new Promise((s) => setTimeout(() => s(), i)); await Promise.any([e, t, a(1e3)]), this.mergeDevices(), this.emitDeviceChange(); } set activeDevice(e) { this.#i = e, this.#a = "shared", x.activePlayer?.updateOutputDevice()?.catch(console.error); } get activeDevice() { return this.#i; } /** * Set the current device mode for the output device. */ set deviceMode(e) { const { activeDevice: t } = this, { activePlayer: a } = x; t && a && a.name === "nativePlayer" && this.deviceMode !== e && (this.#a = e, a.updateDeviceMode()); } get deviceMode() { return this.#a; } } const F = new T(); export { b as OutputDevice, T as OutputDevices, y as findOutputType, S as getOutputDeviceByName, j as isWindowsCommunicationsDevice, C as marshalLabel, F as outputDevices };