@tidal-music/player-web-components 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/active-device-changed-DKzZonX1--oMxdziu.js +7 -0
- package/dist/active-device-mode-changed-Dj16yzUX-BbRjSd-6.js +7 -0
- package/dist/audio-context-store-Ccv6WKna-C-yxIXdl.js +36 -0
- package/dist/basePlayer-CxowZx76-CfK9Qp4M.js +380 -0
- package/dist/browserPlayer-CJUIZMXc-Cwz_EqKS.js +170 -0
- package/dist/generate-guid-DMif1b6n-WXvDGKGF.js +1716 -0
- package/dist/index.js +363 -10
- package/dist/load-D2Tka_Qx-BNIMgt7e.js +29305 -0
- package/dist/media-element-error-circuit-breaker-fMDQ6k4B-B9oZKZUK.js +22 -0
- package/dist/nativePlayer-Bk8Y048r-S6bg9D6D.js +232 -0
- package/dist/output-devices-kF_iC6GM-CnAUEjc9.js +156 -0
- package/dist/pushkin-BJAKy5lP-BDJR20nC.js +117 -0
- package/dist/pushkin-CVLqA7Zj-DJu6_unL.js +2 -0
- package/dist/shakaPlayer-BvtoIIdC-CizBy6it.js +1448 -0
- package/dist/src/helpers.d.ts +18 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/tidal-current-time.d.ts +9 -0
- package/dist/src/tidal-duration-time.d.ts +9 -0
- package/dist/src/tidal-play-trigger.d.ts +2 -0
- package/dist/src/tidal-progress-bar.d.ts +2 -0
- package/dist/src/tidal-video-view.d.ts +2 -0
- package/dist/state-B888KJag-C7pa4Xs7.js +210 -0
- package/package.json +15 -13
- package/dist/_commonjsHelpers-DaMA6jEr-DtILRGNx.js +0 -8
- package/dist/basePlayer-C5QIyqfj-Dxhlf4BZ.js +0 -528
- package/dist/browserPlayer-HE2uqs17-DJrIq6Jp.js +0 -259
- package/dist/index-vp_MoGvy.js +0 -3417
- package/dist/index.d.ts +0 -24
- package/dist/nativePlayer-B3eHKegV-DdXsvi0F.js +0 -323
- package/dist/output-devices-Jno8Kp5B-CAnEAv_Z.js +0 -224
- package/dist/shakaPlayer-CCJQsypf-DHT2kwDp.js +0 -24411
package/dist/index.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { CredentialsProvider } from '@tidal-music/common';
|
|
2
|
-
import { events } from '@tidal-music/player';
|
|
3
|
-
import { setCredentialsProvider } from '@tidal-music/player';
|
|
4
|
-
import { setEventSender } from '@tidal-music/player';
|
|
5
|
-
|
|
6
|
-
export { CredentialsProvider }
|
|
7
|
-
|
|
8
|
-
export { events }
|
|
9
|
-
|
|
10
|
-
export { setCredentialsProvider }
|
|
11
|
-
|
|
12
|
-
export { setEventSender }
|
|
13
|
-
|
|
14
|
-
export declare const TidalCurrentTime = "tidal-current-time";
|
|
15
|
-
|
|
16
|
-
export declare const TidalDurationTime = "tidal-duration-time";
|
|
17
|
-
|
|
18
|
-
export declare const TidalPlayButton = "tidal-play-trigger";
|
|
19
|
-
|
|
20
|
-
export declare const TidalProgressBar = "tidal-progress-bar";
|
|
21
|
-
|
|
22
|
-
export declare const TidalVideoView = "tidal-video-view";
|
|
23
|
-
|
|
24
|
-
export { }
|
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
import { k as v, b as s, x as u, q as k, y as p, P as o, l as g, j as P, G as S } from "./index-vp_MoGvy.js";
|
|
2
|
-
import { C as I, w as b, R as y } from "./basePlayer-C5QIyqfj-Dxhlf4BZ.js";
|
|
3
|
-
const f = "active-device-disconnected";
|
|
4
|
-
function E() {
|
|
5
|
-
return new CustomEvent(f);
|
|
6
|
-
}
|
|
7
|
-
const w = {
|
|
8
|
-
file_checksum_mismatch: "NPO02",
|
|
9
|
-
no_such_file: "NPO01",
|
|
10
|
-
unreadable_file: "NPO03"
|
|
11
|
-
}, N = {
|
|
12
|
-
devicedisconnected: "NPD01",
|
|
13
|
-
deviceexclusivemodenotallowed: "NPD02",
|
|
14
|
-
deviceformatnotsupported: "NPD03",
|
|
15
|
-
devicelocked: "NPD04",
|
|
16
|
-
devicenotfound: "NPD05",
|
|
17
|
-
deviceunknownerror: "NPD00"
|
|
18
|
-
};
|
|
19
|
-
let a;
|
|
20
|
-
class x extends I {
|
|
21
|
-
#s = "default";
|
|
22
|
-
/**
|
|
23
|
-
* A Boolean which is true if the media contained in the element has finished playing.
|
|
24
|
-
*
|
|
25
|
-
* (Native player sends multiple "complete" events.
|
|
26
|
-
* This variable should be set to true on the first call
|
|
27
|
-
* to be able to ignore subsequent onces; until reset
|
|
28
|
-
* for a new media product.)
|
|
29
|
-
*
|
|
30
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended
|
|
31
|
-
*/
|
|
32
|
-
#i;
|
|
33
|
-
#e;
|
|
34
|
-
#a;
|
|
35
|
-
name = "nativePlayer";
|
|
36
|
-
playbackEngineHandlerAttached = !1;
|
|
37
|
-
constructor() {
|
|
38
|
-
super(), v("outputDevicesEnabled") && (async () => (a = (await import("./output-devices-Jno8Kp5B-CAnEAv_Z.js")).outputDevices, this.#e.listDevices()))(), this.#e = // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
window.NativePlayerComponent.Player(), this.playbackState = "IDLE", this.registerEventListeners(), this.#e.setVolume(100);
|
|
41
|
-
}
|
|
42
|
-
#t(e) {
|
|
43
|
-
s.dispatchError(
|
|
44
|
-
new u("EUnexpected", N[e])
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
#r(e) {
|
|
48
|
-
this.debugLog("handleMediaError", e.target);
|
|
49
|
-
const t = e.target, i = w[t.errorCode];
|
|
50
|
-
this.currentStreamingSessionId && k({
|
|
51
|
-
errorCode: i,
|
|
52
|
-
errorMessage: JSON.stringify(e.target),
|
|
53
|
-
streamingSessionId: this.currentStreamingSessionId
|
|
54
|
-
}), s.dispatchError(new u("EUnexpected", i));
|
|
55
|
-
}
|
|
56
|
-
#d(e) {
|
|
57
|
-
switch (this.debugLog("handleNativePlayerStateChange", e), e) {
|
|
58
|
-
case "active":
|
|
59
|
-
this.playbackState = "PLAYING";
|
|
60
|
-
break;
|
|
61
|
-
case "idle":
|
|
62
|
-
case "seeking":
|
|
63
|
-
this.playbackState = "STALLED";
|
|
64
|
-
break;
|
|
65
|
-
case "paused":
|
|
66
|
-
case "ready":
|
|
67
|
-
this.playbackState = "NOT_PLAYING";
|
|
68
|
-
break;
|
|
69
|
-
case "stopped":
|
|
70
|
-
this.playbackState = "NOT_PLAYING";
|
|
71
|
-
break;
|
|
72
|
-
case "uninitialized":
|
|
73
|
-
this.playbackState = "IDLE";
|
|
74
|
-
break;
|
|
75
|
-
default:
|
|
76
|
-
this.debugLog("No handling for state", e);
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
async #n() {
|
|
81
|
-
this.debugLog("handleNetworkError");
|
|
82
|
-
const e = p.timestamp(
|
|
83
|
-
"streaming_metrics:playback_statistics:actualStartTimestamp"
|
|
84
|
-
);
|
|
85
|
-
if ((e !== void 0 ? Math.abs(p.now() - e) : 0) >= 36e5) {
|
|
86
|
-
const t = structuredClone(this.currentMediaProduct), i = this.currentTime;
|
|
87
|
-
this.finishCurrentMediaProduct("error"), t && (await this.hardReload(t, i), await this.play());
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
await Promise.race([
|
|
91
|
-
this.mediaStateChange("idle"),
|
|
92
|
-
new Promise((t) => {
|
|
93
|
-
window.addEventListener("online", () => t("online"));
|
|
94
|
-
})
|
|
95
|
-
]) === "idle" && s.dispatchError(new u("PENetwork", "NPN01"));
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Clean up native player before leaving for another player.
|
|
99
|
-
*/
|
|
100
|
-
abandon() {
|
|
101
|
-
a && a.deviceMode === "exclusive" && this.#e.selectSystemDevice();
|
|
102
|
-
}
|
|
103
|
-
getPosition() {
|
|
104
|
-
return this.currentTime;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* We cannot run multiple instances of native player so this function is
|
|
108
|
-
* for catching duration for a preloaded item in native player.
|
|
109
|
-
*
|
|
110
|
-
* I.e. wait for player to load it and emit mediaduration event, then we
|
|
111
|
-
* can gather the duration data and send a media product transition.
|
|
112
|
-
*/
|
|
113
|
-
async handleAutomaticTransitionToPreloadedMediaProduct() {
|
|
114
|
-
await this.nativeEvent("mediaduration"), this.#a = void 0;
|
|
115
|
-
const e = o.getMediaProductTransition(
|
|
116
|
-
this.preloadedStreamingSessionId
|
|
117
|
-
);
|
|
118
|
-
if (!e) {
|
|
119
|
-
console.warn(
|
|
120
|
-
"No media product transition saved for next item. Stopping playback."
|
|
121
|
-
), this.playbackState = "NOT_PLAYING";
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
const { mediaProduct: t, playbackContext: i } = e, r = {
|
|
125
|
-
...i,
|
|
126
|
-
actualDuration: this.#i
|
|
127
|
-
};
|
|
128
|
-
this.preloadedStreamingSessionId && o.saveMediaProductTransition(
|
|
129
|
-
this.preloadedStreamingSessionId,
|
|
130
|
-
{
|
|
131
|
-
mediaProduct: t,
|
|
132
|
-
playbackContext: r
|
|
133
|
-
}
|
|
134
|
-
), await this.mediaStateChange("active"), s.dispatchEvent(
|
|
135
|
-
b(t, r)
|
|
136
|
-
), this.currentStreamingSessionId = this.preloadedStreamingSessionId, this.mediaProductStarted(this.currentStreamingSessionId);
|
|
137
|
-
}
|
|
138
|
-
async load(e, t) {
|
|
139
|
-
this.debugLog("load", e), this.currentTime = e.assetPosition, this.startAssetPosition = e.assetPosition, await this.reset();
|
|
140
|
-
const { assetPosition: i, mediaProduct: r, playbackInfo: h, streamInfo: d } = e, { securityToken: c, streamFormat: n, streamUrl: l } = d;
|
|
141
|
-
this.currentStreamingSessionId = d.streamingSessionId, t === "explicit" && (this.playbackState = "NOT_PLAYING");
|
|
142
|
-
const L = this.nativeEvent("mediaduration");
|
|
143
|
-
if (n)
|
|
144
|
-
this.#e.load(l, n, c);
|
|
145
|
-
else
|
|
146
|
-
throw new Error("Stream format is undefined.");
|
|
147
|
-
if (await L, this.currentStreamingSessionId !== d.streamingSessionId)
|
|
148
|
-
return;
|
|
149
|
-
this.debugLog("load() duration is", this.#i), i !== 0 && i < this.#i ? (async () => {
|
|
150
|
-
await this.mediaStateChange("active"), await this.seek(i), this.currentTime = i;
|
|
151
|
-
})().catch(console.error) : this.currentTime = 0;
|
|
152
|
-
const m = y({
|
|
153
|
-
assetPosition: i,
|
|
154
|
-
duration: this.#i,
|
|
155
|
-
playbackInfo: h,
|
|
156
|
-
streamInfo: d
|
|
157
|
-
});
|
|
158
|
-
o.saveMediaProductTransition(
|
|
159
|
-
d.streamingSessionId,
|
|
160
|
-
{ mediaProduct: r, playbackContext: m }
|
|
161
|
-
), this.debugLog("load() mediaProductTransition"), s.dispatchEvent(
|
|
162
|
-
b(r, m)
|
|
163
|
-
), this.debugLog("load() pb NOT_PLAYING"), this.debugLog("load() done");
|
|
164
|
-
}
|
|
165
|
-
mediaStateChange(e) {
|
|
166
|
-
return new Promise((t) => {
|
|
167
|
-
this.#e.addEventListener(
|
|
168
|
-
"mediastate",
|
|
169
|
-
(i) => {
|
|
170
|
-
i.target === e && t(i.target);
|
|
171
|
-
}
|
|
172
|
-
);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
nativeEvent(e) {
|
|
176
|
-
return new Promise((t) => {
|
|
177
|
-
this.#e.addEventListener(
|
|
178
|
-
e,
|
|
179
|
-
(i) => t(i)
|
|
180
|
-
);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
async next(e) {
|
|
184
|
-
this.debugLog("next", e), this.hasNextItem() && await this.unloadPreloadedMediaProduct();
|
|
185
|
-
const { mediaProduct: t, playbackInfo: i, streamInfo: r } = e, { securityToken: h, streamFormat: d, streamUrl: c, streamingSessionId: n } = r;
|
|
186
|
-
this.preloadedStreamingSessionId = n, this.debugLog("preloading", c, "for", n), d ? (this.#e.preload(c, d, h), this.isActivePlayer || this.#e.pause()) : console.error("Stream format undefined for preload."), this.debugLog("preloading done");
|
|
187
|
-
const l = y({
|
|
188
|
-
assetPosition: 0,
|
|
189
|
-
duration: 0,
|
|
190
|
-
// TODO: Cannot get duration here, try to solve in some other way...
|
|
191
|
-
playbackInfo: i,
|
|
192
|
-
streamInfo: r
|
|
193
|
-
});
|
|
194
|
-
o.saveMediaProductTransition(n, {
|
|
195
|
-
mediaProduct: t,
|
|
196
|
-
playbackContext: l
|
|
197
|
-
}), this.#a = e;
|
|
198
|
-
}
|
|
199
|
-
pause() {
|
|
200
|
-
this.#e.pause();
|
|
201
|
-
}
|
|
202
|
-
async play() {
|
|
203
|
-
if (this.debugLog("play"), await this.maybeHardReload(), this.playbackState === "IDLE") {
|
|
204
|
-
this.debugLog("play()", this.playbackState, "returning early");
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
this.setStateToXIfNotYInZMs(1e3, "PLAYING", "STALLED"), await this.updateOutputDevice(), this.mediaProductStarted(this.currentStreamingSessionId), this.debugLog("nativePlayer", "play()"), this.#e.play();
|
|
208
|
-
}
|
|
209
|
-
async playbackEngineEndedHandler(e) {
|
|
210
|
-
if (this.isActivePlayer) {
|
|
211
|
-
const { reason: t } = e.detail;
|
|
212
|
-
t === "completed" && (this.hasNextItem() ? await this.handleAutomaticTransitionToPreloadedMediaProduct() : (g.preloadedStreamingSessionId ? this.debugLog(
|
|
213
|
-
`Switching player from ${this.name} to ${g.preloadPlayer?.name}`
|
|
214
|
-
) : this.debugLog("No next item queued."), this.playbackState = "NOT_PLAYING"));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
registerEventListeners() {
|
|
218
|
-
this.debugLog("registerEventListeners"), this.#e.addEventListener("mediacurrenttime", (e) => {
|
|
219
|
-
this.currentTime = Number(e.target);
|
|
220
|
-
}), this.#e.addEventListener(
|
|
221
|
-
"mediastate",
|
|
222
|
-
(e) => {
|
|
223
|
-
e.target === "completed" ? this.finishCurrentMediaProduct("completed") : this.#d(e.target);
|
|
224
|
-
}
|
|
225
|
-
), this.#e.addEventListener(
|
|
226
|
-
"devices",
|
|
227
|
-
(e) => {
|
|
228
|
-
a ? a.addNativeDevices(e.target) : console.error("Output devices not loaded.");
|
|
229
|
-
}
|
|
230
|
-
), this.#e.addEventListener("devicedisconnected", () => {
|
|
231
|
-
s.dispatchEvent(E()), this.#t("devicedisconnected");
|
|
232
|
-
}), this.#e.addEventListener(
|
|
233
|
-
"deviceexclusivemodenotallowed",
|
|
234
|
-
() => this.#t("deviceexclusivemodenotallowed")
|
|
235
|
-
), this.#e.addEventListener(
|
|
236
|
-
"deviceformatnotsupported",
|
|
237
|
-
() => this.#t("deviceformatnotsupported")
|
|
238
|
-
), this.#e.addEventListener(
|
|
239
|
-
"devicelocked",
|
|
240
|
-
() => this.#t("devicelocked")
|
|
241
|
-
), this.#e.addEventListener(
|
|
242
|
-
"devicenotfound",
|
|
243
|
-
() => this.#t("devicenotfound")
|
|
244
|
-
), this.#e.addEventListener(
|
|
245
|
-
"deviceunknownerror",
|
|
246
|
-
() => this.#t("deviceunknownerror")
|
|
247
|
-
), this.#e.addEventListener(
|
|
248
|
-
"mediaduration",
|
|
249
|
-
(e) => {
|
|
250
|
-
this.#i = Number(e.target);
|
|
251
|
-
}
|
|
252
|
-
), this.#e.addEventListener(
|
|
253
|
-
"mediaerror",
|
|
254
|
-
(e) => this.#r(e)
|
|
255
|
-
), this.#e.addEventListener("mediamaxconnectionsreached", () => {
|
|
256
|
-
this.#n().catch(console.error);
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
async reset({ keepPreload: e } = { keepPreload: !1 }) {
|
|
260
|
-
this.currentStreamingSessionId !== void 0 && (this.debugLog("reset"), e || await this.unloadPreloadedMediaProduct(), this.#e.stop(), this.playbackState !== "IDLE" && this.finishCurrentMediaProduct("skip"), this.detachPlaybackEngineEndedHandler(), this.currentStreamingSessionId = void 0, e || (this.preloadedStreamingSessionId = void 0), this.playbackState = "IDLE");
|
|
261
|
-
}
|
|
262
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
263
|
-
async seek(e) {
|
|
264
|
-
this.hasStarted() || await this.mediaStateChange("active"), this.seekStart(this.currentTime), this.currentTime = e, this.#e.seek(e), this.seekEnd(this.currentTime);
|
|
265
|
-
}
|
|
266
|
-
// Handles track "skip next" and progressions between shaka and native player
|
|
267
|
-
async skipToPreloadedMediaProduct() {
|
|
268
|
-
this.debugLog(
|
|
269
|
-
"skipToPreloadedMediaProduct",
|
|
270
|
-
this.preloadedStreamingSessionId
|
|
271
|
-
);
|
|
272
|
-
const e = this.currentStreamingSessionId === void 0;
|
|
273
|
-
if (this.preloadedStreamingSessionId && this.#a) {
|
|
274
|
-
const t = o.getMediaProductTransition(
|
|
275
|
-
this.preloadedStreamingSessionId
|
|
276
|
-
);
|
|
277
|
-
t && (this.#a.mediaProduct = t.mediaProduct), await this.load(this.#a, "implicit"), await this.updateOutputDevice(), e && (this.playbackState = "PLAYING"), this.playbackState === "IDLE" && (this.playbackState = "NOT_PLAYING");
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
console.warn("No preloaded item in native player.");
|
|
281
|
-
}
|
|
282
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
283
|
-
async unloadPreloadedMediaProduct() {
|
|
284
|
-
this.debugLog(
|
|
285
|
-
"unloadPreloadedMediaProduct",
|
|
286
|
-
this.preloadedStreamingSessionId
|
|
287
|
-
), this.hasNextItem() && (this.cleanUpStoredPreloadInfo(), "cancelPreload" in this.#e ? this.#e.cancelPreload() : console.warn("cancelPreload not available. Update native player."));
|
|
288
|
-
}
|
|
289
|
-
updateDeviceMode() {
|
|
290
|
-
this.updateOutputDevice()?.catch(console.error), a && s.dispatchEvent(
|
|
291
|
-
P(a.deviceMode)
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
updateOutputDevice() {
|
|
295
|
-
if (!a || (this.debugLog("updateOutputDevice", a.activeDevice), !a.activeDevice))
|
|
296
|
-
return Promise.resolve();
|
|
297
|
-
const { nativeDeviceId: e } = a.activeDevice;
|
|
298
|
-
if (this.outputDeviceType = a.activeDevice.type, e === "default")
|
|
299
|
-
this.#s !== "default" && (this.#e.selectSystemDevice(), s.dispatchEvent(S("default")), this.#s = "default");
|
|
300
|
-
else if (e) {
|
|
301
|
-
const t = a.getNativeDevice(e);
|
|
302
|
-
t && (this.#e.selectDevice(t, a.deviceMode), s.dispatchEvent(
|
|
303
|
-
S(a.activeDevice.id)
|
|
304
|
-
), s.dispatchEvent(
|
|
305
|
-
P(a.deviceMode)
|
|
306
|
-
), this.#s = e);
|
|
307
|
-
} else
|
|
308
|
-
throw new Error(`Device with sinkId ${e} not found.`);
|
|
309
|
-
return Promise.resolve();
|
|
310
|
-
}
|
|
311
|
-
get ready() {
|
|
312
|
-
return Promise.resolve();
|
|
313
|
-
}
|
|
314
|
-
get volume() {
|
|
315
|
-
return v("desiredVolumeLevel");
|
|
316
|
-
}
|
|
317
|
-
set volume(e) {
|
|
318
|
-
this.debugLog("Setting volume to", e), this.#e.setVolume(e * 100);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
export {
|
|
322
|
-
x as default
|
|
323
|
-
};
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { b as W, m as O, l as L, n as q } from "./index-vp_MoGvy.js";
|
|
2
|
-
import { l as M } from "./_commonjsHelpers-DaMA6jEr-DtILRGNx.js";
|
|
3
|
-
var P, S;
|
|
4
|
-
function N() {
|
|
5
|
-
return S || (S = 1, P = /* @__PURE__ */ function() {
|
|
6
|
-
function a(e, t, n, i, s) {
|
|
7
|
-
return e < t || n < t ? e > n ? n + 1 : e + 1 : i === s ? t : t + 1;
|
|
8
|
-
}
|
|
9
|
-
return function(e, t) {
|
|
10
|
-
if (e === t)
|
|
11
|
-
return 0;
|
|
12
|
-
if (e.length > t.length) {
|
|
13
|
-
var n = e;
|
|
14
|
-
e = t, t = n;
|
|
15
|
-
}
|
|
16
|
-
for (var i = e.length, s = t.length; i > 0 && e.charCodeAt(i - 1) === t.charCodeAt(s - 1); )
|
|
17
|
-
i--, s--;
|
|
18
|
-
for (var c = 0; c < i && e.charCodeAt(c) === t.charCodeAt(c); )
|
|
19
|
-
c++;
|
|
20
|
-
if (i -= c, s -= c, i === 0 || s < 3)
|
|
21
|
-
return s;
|
|
22
|
-
var o = 0, r, d, l, h, f, v, m, p, D, I, C, E, u = [];
|
|
23
|
-
for (r = 0; r < i; r++)
|
|
24
|
-
u.push(r + 1), u.push(e.charCodeAt(c + r));
|
|
25
|
-
for (var A = u.length - 1; o < s - 3; )
|
|
26
|
-
for (D = t.charCodeAt(c + (d = o)), I = t.charCodeAt(c + (l = o + 1)), C = t.charCodeAt(c + (h = o + 2)), E = t.charCodeAt(c + (f = o + 3)), v = o += 4, r = 0; r < A; r += 2)
|
|
27
|
-
m = u[r], p = u[r + 1], d = a(m, d, l, D, p), l = a(d, l, h, I, p), h = a(l, h, f, C, p), v = a(h, f, v, E, p), u[r] = v, f = h, h = l, l = d, d = m;
|
|
28
|
-
for (; o < s; )
|
|
29
|
-
for (D = t.charCodeAt(c + (d = o)), v = ++o, r = 0; r < A; r += 2)
|
|
30
|
-
m = u[r], u[r] = v = a(m, d, v, D, u[r + 1]), d = m;
|
|
31
|
-
return v;
|
|
32
|
-
};
|
|
33
|
-
}()), P;
|
|
34
|
-
}
|
|
35
|
-
var T = N();
|
|
36
|
-
const U = /* @__PURE__ */ M(T);
|
|
37
|
-
function B(a) {
|
|
38
|
-
return new CustomEvent("device-change", {
|
|
39
|
-
detail: {
|
|
40
|
-
devices: a
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
const y = O.parse(navigator.userAgent);
|
|
45
|
-
class w {
|
|
46
|
-
controllableVolume;
|
|
47
|
-
id;
|
|
48
|
-
name;
|
|
49
|
-
nativeDeviceId;
|
|
50
|
-
type;
|
|
51
|
-
webDeviceId;
|
|
52
|
-
constructor({
|
|
53
|
-
controllableVolume: e,
|
|
54
|
-
name: t,
|
|
55
|
-
nativeDeviceId: n,
|
|
56
|
-
type: i,
|
|
57
|
-
webDeviceId: s
|
|
58
|
-
}) {
|
|
59
|
-
this.name = t, this.id = n === "default" && s === "default" ? "default" : q(), this.nativeDeviceId = n, this.webDeviceId = s, this.type = i, this.controllableVolume = e !== !1;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function b(a) {
|
|
63
|
-
if (k(a))
|
|
64
|
-
return "windowsCommunication";
|
|
65
|
-
if ("id" in a && a.id === "BuiltInSpeakerDevice")
|
|
66
|
-
return "builtIn";
|
|
67
|
-
if ("type" in a && a.type === "airplay")
|
|
68
|
-
return "airplay";
|
|
69
|
-
if ("label" in a) {
|
|
70
|
-
const e = a.label.toLowerCase();
|
|
71
|
-
if (e.includes("bluetooth"))
|
|
72
|
-
return "bluetooth";
|
|
73
|
-
if (e.includes("displayport"))
|
|
74
|
-
return "displayPort";
|
|
75
|
-
if (e.includes("hdmi"))
|
|
76
|
-
return "hdmi";
|
|
77
|
-
if (e.includes("usb"))
|
|
78
|
-
return "usb";
|
|
79
|
-
if (e.includes("built-in"))
|
|
80
|
-
return "builtIn";
|
|
81
|
-
if (e.includes("airplay"))
|
|
82
|
-
return "airplay";
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function g(a, e) {
|
|
86
|
-
const t = e.toLowerCase();
|
|
87
|
-
let n = a;
|
|
88
|
-
return t.includes("mac") && (n = (a.split("(")[0] ?? "").trim()), n;
|
|
89
|
-
}
|
|
90
|
-
function k(a) {
|
|
91
|
-
let e;
|
|
92
|
-
return "label" in a && (e = a.label), "name" in a && (e = a.name), e?.startsWith("Communications") ?? !1;
|
|
93
|
-
}
|
|
94
|
-
function V(a, e) {
|
|
95
|
-
if (e = g(e, y.os.name || ""), [...a].length === 0 || e === "")
|
|
96
|
-
return;
|
|
97
|
-
const t = [...a].find((i) => i.name === e);
|
|
98
|
-
if (t)
|
|
99
|
-
return t;
|
|
100
|
-
const n = [...a].filter((i) => e.includes(i.name) || i.name.includes(e)).map((i) => ({
|
|
101
|
-
device: i,
|
|
102
|
-
distance: U(i.name, e)
|
|
103
|
-
})).sort((i, s) => i.distance - s.distance).reverse();
|
|
104
|
-
if (n.length > 0) {
|
|
105
|
-
const i = n.pop();
|
|
106
|
-
if (i && i.distance <= 16)
|
|
107
|
-
return i.device;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
class $ {
|
|
111
|
-
#i;
|
|
112
|
-
#a;
|
|
113
|
-
#n = "shared";
|
|
114
|
-
#e;
|
|
115
|
-
#t;
|
|
116
|
-
#s;
|
|
117
|
-
outputDevices;
|
|
118
|
-
constructor() {
|
|
119
|
-
this.#t = /* @__PURE__ */ new Set(), this.#s = /* @__PURE__ */ new Set(), this.#e = new EventTarget(), this.#a = new w({
|
|
120
|
-
name: "System Default",
|
|
121
|
-
nativeDeviceId: "default",
|
|
122
|
-
type: "systemDefault",
|
|
123
|
-
webDeviceId: "default"
|
|
124
|
-
}), this.#i = this.#a, this.outputDevices = /* @__PURE__ */ new Set([this.#a]), this.hydrateWebDevices().then().catch(console.error), navigator.mediaDevices.addEventListener("devicechange", () => {
|
|
125
|
-
this.hydrateWebDevices().then().catch(console.error);
|
|
126
|
-
}), this.#e.addEventListener("native-devices", (e) => {
|
|
127
|
-
this.#t = new Set(e.detail), this.queueUpdate().then().catch(console.error);
|
|
128
|
-
}), this.#e.addEventListener("web-devices", (e) => {
|
|
129
|
-
this.#s = new Set(e.detail), this.queueUpdate().then().catch(console.error);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
addNativeDevices(e) {
|
|
133
|
-
this.#e.dispatchEvent(
|
|
134
|
-
new CustomEvent("native-devices", {
|
|
135
|
-
detail: e
|
|
136
|
-
})
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
addWebDevices(e) {
|
|
140
|
-
e = e.filter((t) => t.deviceId !== "default"), this.#e.dispatchEvent(
|
|
141
|
-
new CustomEvent("web-devices", {
|
|
142
|
-
detail: e
|
|
143
|
-
})
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
emitDeviceChange() {
|
|
147
|
-
W.dispatchEvent(B([...this.outputDevices]));
|
|
148
|
-
}
|
|
149
|
-
getNativeDevice(e) {
|
|
150
|
-
return [...this.#t].find((t) => t.id === e);
|
|
151
|
-
}
|
|
152
|
-
async hydrateWebDevices() {
|
|
153
|
-
const e = (await navigator.mediaDevices.enumerateDevices()).filter((t) => t.kind === "audiooutput");
|
|
154
|
-
this.addWebDevices(e);
|
|
155
|
-
}
|
|
156
|
-
mergeDevices() {
|
|
157
|
-
[...this.outputDevices].filter((e) => e.id !== "default").forEach((e) => {
|
|
158
|
-
e.nativeDeviceId = void 0, e.webDeviceId = void 0;
|
|
159
|
-
}), this.#t.forEach((e) => {
|
|
160
|
-
const t = V(this.outputDevices, e.name);
|
|
161
|
-
t ? (t.nativeDeviceId = e.id, t.controllableVolume = e.controllableVolume, t.type = b(e) || t.type) : this.outputDevices.add(
|
|
162
|
-
new w({
|
|
163
|
-
controllableVolume: e.controllableVolume,
|
|
164
|
-
name: g(e.name, y.os.name || ""),
|
|
165
|
-
nativeDeviceId: e.id,
|
|
166
|
-
type: b(e)
|
|
167
|
-
})
|
|
168
|
-
);
|
|
169
|
-
}), this.#s.forEach((e) => {
|
|
170
|
-
const t = V(this.outputDevices, e.label);
|
|
171
|
-
t ? (t.webDeviceId = e.deviceId, t.type = b(e) || t.type) : this.outputDevices.add(
|
|
172
|
-
new w({
|
|
173
|
-
name: g(e.label, y.os.name || ""),
|
|
174
|
-
type: b(e),
|
|
175
|
-
webDeviceId: e.deviceId
|
|
176
|
-
})
|
|
177
|
-
);
|
|
178
|
-
}), [...this.outputDevices].filter(
|
|
179
|
-
(e) => e.webDeviceId === void 0 && e.nativeDeviceId === void 0 || e.type === "airplay" || e.type === "windowsCommunication"
|
|
180
|
-
).forEach((e) => this.outputDevices.delete(e));
|
|
181
|
-
}
|
|
182
|
-
async queueUpdate() {
|
|
183
|
-
const e = new Promise(
|
|
184
|
-
(i) => this.#e.addEventListener(
|
|
185
|
-
"native-devices",
|
|
186
|
-
(s) => i(s.detail),
|
|
187
|
-
{ once: !0 }
|
|
188
|
-
)
|
|
189
|
-
), t = new Promise(
|
|
190
|
-
(i) => this.#e.addEventListener(
|
|
191
|
-
"web-devices",
|
|
192
|
-
(s) => i(s.detail),
|
|
193
|
-
{ once: !0 }
|
|
194
|
-
)
|
|
195
|
-
), n = (i) => new Promise((s) => setTimeout(() => s(), i));
|
|
196
|
-
await Promise.any([e, t, n(1e3)]), this.mergeDevices(), this.emitDeviceChange();
|
|
197
|
-
}
|
|
198
|
-
set activeDevice(e) {
|
|
199
|
-
this.#i = e, this.#n = "shared", L.activePlayer?.updateOutputDevice()?.catch(console.error);
|
|
200
|
-
}
|
|
201
|
-
get activeDevice() {
|
|
202
|
-
return this.#i;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Set the current device mode for the output device.
|
|
206
|
-
*/
|
|
207
|
-
set deviceMode(e) {
|
|
208
|
-
const { activeDevice: t } = this, { activePlayer: n } = L;
|
|
209
|
-
t && n && n.name === "nativePlayer" && this.deviceMode !== e && (this.#n = e, n.updateDeviceMode());
|
|
210
|
-
}
|
|
211
|
-
get deviceMode() {
|
|
212
|
-
return this.#n;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
const F = new $();
|
|
216
|
-
export {
|
|
217
|
-
w as OutputDevice,
|
|
218
|
-
$ as OutputDevices,
|
|
219
|
-
b as findOutputType,
|
|
220
|
-
V as getOutputDeviceByName,
|
|
221
|
-
k as isWindowsCommunicationsDevice,
|
|
222
|
-
g as marshalLabel,
|
|
223
|
-
F as outputDevices
|
|
224
|
-
};
|