@tidal-music/player-web-components 0.1.1 → 0.2.0
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/basePlayer-C5QIyqfj-Dxhlf4BZ.js +528 -0
- package/dist/{browserPlayer-oNOpDVm6-UW0N6pFH.js → browserPlayer-HE2uqs17-DJrIq6Jp.js} +44 -55
- package/dist/{index-tM9JvbA8.js → index-vp_MoGvy.js} +1204 -1054
- package/dist/index.d.ts +3 -0
- package/dist/index.js +9 -8
- package/dist/{nativePlayer-U375Dfm5-hUK7oXzY.js → nativePlayer-B3eHKegV-DdXsvi0F.js} +65 -104
- package/dist/output-devices-Jno8Kp5B-CAnEAv_Z.js +224 -0
- package/dist/shakaPlayer-CCJQsypf-DHT2kwDp.js +24411 -0
- package/package.json +16 -18
- package/dist/basePlayer-a-avZASH-Ux-6s9Ex.js +0 -579
- package/dist/output-devices-NXuo75MQ-_vYYuqUm.js +0 -236
- package/dist/shakaPlayer-izGFLVQr--XUsjgT2.js +0 -24740
- package/dist/worker-qh_9Fyf6-Li0uY2-a.js +0 -89
- /package/dist/{_commonjsHelpers-f3sTPFkQ-YKQV-mq1.js → _commonjsHelpers-DaMA6jEr-DtILRGNx.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CredentialsProvider } from '@tidal-music/common';
|
|
2
2
|
import { events } from '@tidal-music/player';
|
|
3
3
|
import { setCredentialsProvider } from '@tidal-music/player';
|
|
4
|
+
import { setEventSender } from '@tidal-music/player';
|
|
4
5
|
|
|
5
6
|
export { CredentialsProvider }
|
|
6
7
|
|
|
@@ -8,6 +9,8 @@ export { events }
|
|
|
8
9
|
|
|
9
10
|
export { setCredentialsProvider }
|
|
10
11
|
|
|
12
|
+
export { setEventSender }
|
|
13
|
+
|
|
11
14
|
export declare const TidalCurrentTime = "tidal-current-time";
|
|
12
15
|
|
|
13
16
|
export declare const TidalDurationTime = "tidal-duration-time";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as s, p as r, r as i, s as t, t as d, b as o, H as l, Q as n } from "./index-vp_MoGvy.js";
|
|
2
2
|
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
s as TidalCurrentTime,
|
|
4
|
+
r as TidalDurationTime,
|
|
5
|
+
i as TidalPlayButton,
|
|
6
|
+
t as TidalProgressBar,
|
|
7
|
+
d as TidalVideoView,
|
|
8
|
+
o as events,
|
|
9
|
+
l as setCredentialsProvider,
|
|
10
|
+
n as setEventSender
|
|
10
11
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
const
|
|
4
|
-
function
|
|
5
|
-
return new CustomEvent(
|
|
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
6
|
}
|
|
7
|
-
const
|
|
7
|
+
const w = {
|
|
8
8
|
file_checksum_mismatch: "NPO02",
|
|
9
9
|
no_such_file: "NPO01",
|
|
10
10
|
unreadable_file: "NPO03"
|
|
@@ -16,8 +16,8 @@ const D = {
|
|
|
16
16
|
devicenotfound: "NPD05",
|
|
17
17
|
deviceunknownerror: "NPD00"
|
|
18
18
|
};
|
|
19
|
-
let
|
|
20
|
-
class
|
|
19
|
+
let a;
|
|
20
|
+
class x extends I {
|
|
21
21
|
#s = "default";
|
|
22
22
|
/**
|
|
23
23
|
* A Boolean which is true if the media contained in the element has finished playing.
|
|
@@ -30,63 +30,61 @@ class A extends f {
|
|
|
30
30
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended
|
|
31
31
|
*/
|
|
32
32
|
#i;
|
|
33
|
-
#r = !0;
|
|
34
33
|
#e;
|
|
35
34
|
#a;
|
|
36
35
|
name = "nativePlayer";
|
|
37
36
|
playbackEngineHandlerAttached = !1;
|
|
38
37
|
constructor() {
|
|
39
|
-
super(),
|
|
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
|
|
40
39
|
// @ts-ignore
|
|
41
40
|
window.NativePlayerComponent.Player(), this.playbackState = "IDLE", this.registerEventListeners(), this.#e.setVolume(100);
|
|
42
41
|
}
|
|
43
|
-
// eslint-disable-next-line class-methods-use-this
|
|
44
42
|
#t(e) {
|
|
45
43
|
s.dispatchError(
|
|
46
44
|
new u("EUnexpected", N[e])
|
|
47
45
|
);
|
|
48
46
|
}
|
|
49
|
-
#
|
|
47
|
+
#r(e) {
|
|
50
48
|
this.debugLog("handleMediaError", e.target);
|
|
51
|
-
const t = e.target,
|
|
49
|
+
const t = e.target, i = w[t.errorCode];
|
|
52
50
|
this.currentStreamingSessionId && k({
|
|
53
|
-
errorCode:
|
|
51
|
+
errorCode: i,
|
|
54
52
|
errorMessage: JSON.stringify(e.target),
|
|
55
53
|
streamingSessionId: this.currentStreamingSessionId
|
|
56
|
-
}), s.dispatchError(new u("EUnexpected",
|
|
54
|
+
}), s.dispatchError(new u("EUnexpected", i));
|
|
57
55
|
}
|
|
58
|
-
#
|
|
56
|
+
#d(e) {
|
|
59
57
|
switch (this.debugLog("handleNativePlayerStateChange", e), e) {
|
|
60
|
-
case "paused":
|
|
61
|
-
case "ready":
|
|
62
|
-
this.playbackState = "NOT_PLAYING";
|
|
63
|
-
break;
|
|
64
58
|
case "active":
|
|
65
59
|
this.playbackState = "PLAYING";
|
|
66
60
|
break;
|
|
67
|
-
case "seeking":
|
|
68
61
|
case "idle":
|
|
62
|
+
case "seeking":
|
|
69
63
|
this.playbackState = "STALLED";
|
|
70
64
|
break;
|
|
71
|
-
case "
|
|
72
|
-
|
|
65
|
+
case "paused":
|
|
66
|
+
case "ready":
|
|
67
|
+
this.playbackState = "NOT_PLAYING";
|
|
73
68
|
break;
|
|
74
69
|
case "stopped":
|
|
75
70
|
this.playbackState = "NOT_PLAYING";
|
|
76
71
|
break;
|
|
72
|
+
case "uninitialized":
|
|
73
|
+
this.playbackState = "IDLE";
|
|
74
|
+
break;
|
|
77
75
|
default:
|
|
78
76
|
this.debugLog("No handling for state", e);
|
|
79
77
|
break;
|
|
80
78
|
}
|
|
81
79
|
}
|
|
82
|
-
async #
|
|
80
|
+
async #n() {
|
|
83
81
|
this.debugLog("handleNetworkError");
|
|
84
82
|
const e = p.timestamp(
|
|
85
83
|
"streaming_metrics:playback_statistics:actualStartTimestamp"
|
|
86
84
|
);
|
|
87
85
|
if ((e !== void 0 ? Math.abs(p.now() - e) : 0) >= 36e5) {
|
|
88
|
-
const t = structuredClone(this.currentMediaProduct),
|
|
89
|
-
this.finishCurrentMediaProduct("error"), t && (await this.hardReload(t,
|
|
86
|
+
const t = structuredClone(this.currentMediaProduct), i = this.currentTime;
|
|
87
|
+
this.finishCurrentMediaProduct("error"), t && (await this.hardReload(t, i), await this.play());
|
|
90
88
|
return;
|
|
91
89
|
}
|
|
92
90
|
await Promise.race([
|
|
@@ -100,7 +98,7 @@ class A extends f {
|
|
|
100
98
|
* Clean up native player before leaving for another player.
|
|
101
99
|
*/
|
|
102
100
|
abandon() {
|
|
103
|
-
|
|
101
|
+
a && a.deviceMode === "exclusive" && this.#e.selectSystemDevice();
|
|
104
102
|
}
|
|
105
103
|
getPosition() {
|
|
106
104
|
return this.currentTime;
|
|
@@ -123,8 +121,8 @@ class A extends f {
|
|
|
123
121
|
), this.playbackState = "NOT_PLAYING";
|
|
124
122
|
return;
|
|
125
123
|
}
|
|
126
|
-
const { mediaProduct: t, playbackContext:
|
|
127
|
-
...
|
|
124
|
+
const { mediaProduct: t, playbackContext: i } = e, r = {
|
|
125
|
+
...i,
|
|
128
126
|
actualDuration: this.#i
|
|
129
127
|
};
|
|
130
128
|
this.preloadedStreamingSessionId && o.saveMediaProductTransition(
|
|
@@ -134,42 +132,42 @@ class A extends f {
|
|
|
134
132
|
playbackContext: r
|
|
135
133
|
}
|
|
136
134
|
), await this.mediaStateChange("active"), s.dispatchEvent(
|
|
137
|
-
|
|
135
|
+
b(t, r)
|
|
138
136
|
), this.currentStreamingSessionId = this.preloadedStreamingSessionId, this.mediaProductStarted(this.currentStreamingSessionId);
|
|
139
137
|
}
|
|
140
138
|
async load(e, t) {
|
|
141
|
-
this.debugLog("load", e), this.currentTime = e.assetPosition, this.startAssetPosition = e.assetPosition, await this.reset()
|
|
142
|
-
const { assetPosition:
|
|
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;
|
|
143
141
|
this.currentStreamingSessionId = d.streamingSessionId, t === "explicit" && (this.playbackState = "NOT_PLAYING");
|
|
144
|
-
const
|
|
142
|
+
const L = this.nativeEvent("mediaduration");
|
|
145
143
|
if (n)
|
|
146
144
|
this.#e.load(l, n, c);
|
|
147
145
|
else
|
|
148
146
|
throw new Error("Stream format is undefined.");
|
|
149
|
-
if (await
|
|
147
|
+
if (await L, this.currentStreamingSessionId !== d.streamingSessionId)
|
|
150
148
|
return;
|
|
151
|
-
this.debugLog("load() duration is", this.#i),
|
|
152
|
-
await this.mediaStateChange("active"), await this.seek(
|
|
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;
|
|
153
151
|
})().catch(console.error) : this.currentTime = 0;
|
|
154
|
-
const
|
|
155
|
-
assetPosition:
|
|
152
|
+
const m = y({
|
|
153
|
+
assetPosition: i,
|
|
156
154
|
duration: this.#i,
|
|
157
155
|
playbackInfo: h,
|
|
158
156
|
streamInfo: d
|
|
159
157
|
});
|
|
160
158
|
o.saveMediaProductTransition(
|
|
161
159
|
d.streamingSessionId,
|
|
162
|
-
{ mediaProduct: r, playbackContext:
|
|
160
|
+
{ mediaProduct: r, playbackContext: m }
|
|
163
161
|
), this.debugLog("load() mediaProductTransition"), s.dispatchEvent(
|
|
164
|
-
|
|
162
|
+
b(r, m)
|
|
165
163
|
), this.debugLog("load() pb NOT_PLAYING"), this.debugLog("load() done");
|
|
166
164
|
}
|
|
167
165
|
mediaStateChange(e) {
|
|
168
166
|
return new Promise((t) => {
|
|
169
167
|
this.#e.addEventListener(
|
|
170
168
|
"mediastate",
|
|
171
|
-
(
|
|
172
|
-
|
|
169
|
+
(i) => {
|
|
170
|
+
i.target === e && t(i.target);
|
|
173
171
|
}
|
|
174
172
|
);
|
|
175
173
|
});
|
|
@@ -178,20 +176,19 @@ class A extends f {
|
|
|
178
176
|
return new Promise((t) => {
|
|
179
177
|
this.#e.addEventListener(
|
|
180
178
|
e,
|
|
181
|
-
(
|
|
179
|
+
(i) => t(i)
|
|
182
180
|
);
|
|
183
181
|
});
|
|
184
182
|
}
|
|
185
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
186
183
|
async next(e) {
|
|
187
184
|
this.debugLog("next", e), this.hasNextItem() && await this.unloadPreloadedMediaProduct();
|
|
188
|
-
const { mediaProduct: t, playbackInfo:
|
|
189
|
-
this.preloadedStreamingSessionId = n, this.debugLog("preloading", c, "for", n), d ? this.#e.preload(c, d, h) : console.error("Stream format undefined for preload."), this.debugLog("preloading done");
|
|
190
|
-
const l =
|
|
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({
|
|
191
188
|
assetPosition: 0,
|
|
192
189
|
duration: 0,
|
|
193
190
|
// TODO: Cannot get duration here, try to solve in some other way...
|
|
194
|
-
playbackInfo:
|
|
191
|
+
playbackInfo: i,
|
|
195
192
|
streamInfo: r
|
|
196
193
|
});
|
|
197
194
|
o.saveMediaProductTransition(n, {
|
|
@@ -223,15 +220,15 @@ class A extends f {
|
|
|
223
220
|
}), this.#e.addEventListener(
|
|
224
221
|
"mediastate",
|
|
225
222
|
(e) => {
|
|
226
|
-
e.target === "completed" ? this.finishCurrentMediaProduct("completed") : this.#
|
|
223
|
+
e.target === "completed" ? this.finishCurrentMediaProduct("completed") : this.#d(e.target);
|
|
227
224
|
}
|
|
228
225
|
), this.#e.addEventListener(
|
|
229
226
|
"devices",
|
|
230
227
|
(e) => {
|
|
231
|
-
|
|
228
|
+
a ? a.addNativeDevices(e.target) : console.error("Output devices not loaded.");
|
|
232
229
|
}
|
|
233
230
|
), this.#e.addEventListener("devicedisconnected", () => {
|
|
234
|
-
s.dispatchEvent(
|
|
231
|
+
s.dispatchEvent(E()), this.#t("devicedisconnected");
|
|
235
232
|
}), this.#e.addEventListener(
|
|
236
233
|
"deviceexclusivemodenotallowed",
|
|
237
234
|
() => this.#t("deviceexclusivemodenotallowed")
|
|
@@ -254,17 +251,17 @@ class A extends f {
|
|
|
254
251
|
}
|
|
255
252
|
), this.#e.addEventListener(
|
|
256
253
|
"mediaerror",
|
|
257
|
-
(e) => this.#
|
|
254
|
+
(e) => this.#r(e)
|
|
258
255
|
), this.#e.addEventListener("mediamaxconnectionsreached", () => {
|
|
259
|
-
this.#
|
|
256
|
+
this.#n().catch(console.error);
|
|
260
257
|
});
|
|
261
258
|
}
|
|
262
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
263
259
|
async reset({ keepPreload: e } = { keepPreload: !1 }) {
|
|
264
|
-
this
|
|
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");
|
|
265
261
|
}
|
|
262
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
266
263
|
async seek(e) {
|
|
267
|
-
this.hasStarted() || await this.mediaStateChange("active"), this.seekStart(), this.currentTime = e, this.#e.seek(e), this.seekEnd();
|
|
264
|
+
this.hasStarted() || await this.mediaStateChange("active"), this.seekStart(this.currentTime), this.currentTime = e, this.#e.seek(e), this.seekEnd(this.currentTime);
|
|
268
265
|
}
|
|
269
266
|
// Handles track "skip next" and progressions between shaka and native player
|
|
270
267
|
async skipToPreloadedMediaProduct() {
|
|
@@ -290,73 +287,37 @@ class A extends f {
|
|
|
290
287
|
), this.hasNextItem() && (this.cleanUpStoredPreloadInfo(), "cancelPreload" in this.#e ? this.#e.cancelPreload() : console.warn("cancelPreload not available. Update native player."));
|
|
291
288
|
}
|
|
292
289
|
updateDeviceMode() {
|
|
293
|
-
this.updateOutputDevice()?.catch(console.error),
|
|
294
|
-
P(
|
|
290
|
+
this.updateOutputDevice()?.catch(console.error), a && s.dispatchEvent(
|
|
291
|
+
P(a.deviceMode)
|
|
295
292
|
);
|
|
296
293
|
}
|
|
297
294
|
updateOutputDevice() {
|
|
298
|
-
if (!
|
|
295
|
+
if (!a || (this.debugLog("updateOutputDevice", a.activeDevice), !a.activeDevice))
|
|
299
296
|
return Promise.resolve();
|
|
300
|
-
const { nativeDeviceId: e } =
|
|
301
|
-
if (this.outputDeviceType =
|
|
297
|
+
const { nativeDeviceId: e } = a.activeDevice;
|
|
298
|
+
if (this.outputDeviceType = a.activeDevice.type, e === "default")
|
|
302
299
|
this.#s !== "default" && (this.#e.selectSystemDevice(), s.dispatchEvent(S("default")), this.#s = "default");
|
|
303
300
|
else if (e) {
|
|
304
|
-
const t =
|
|
305
|
-
t && (this.#e.selectDevice(t,
|
|
306
|
-
S(
|
|
301
|
+
const t = a.getNativeDevice(e);
|
|
302
|
+
t && (this.#e.selectDevice(t, a.deviceMode), s.dispatchEvent(
|
|
303
|
+
S(a.activeDevice.id)
|
|
307
304
|
), s.dispatchEvent(
|
|
308
|
-
P(
|
|
305
|
+
P(a.deviceMode)
|
|
309
306
|
), this.#s = e);
|
|
310
307
|
} else
|
|
311
|
-
|
|
308
|
+
throw new Error(`Device with sinkId ${e} not found.`);
|
|
312
309
|
return Promise.resolve();
|
|
313
310
|
}
|
|
314
|
-
/**
|
|
315
|
-
* WIMPWC-7901
|
|
316
|
-
* This is a temporary fix as there is currently no way to enable
|
|
317
|
-
* the MQA decoder in Native Player after disabling it.
|
|
318
|
-
*
|
|
319
|
-
* Switching devices forces the Native Player to use the new device settings.
|
|
320
|
-
* By default `device.passThrough` is `undefined`, that's why we check explicitly for `false`.
|
|
321
|
-
*
|
|
322
|
-
* TODO: Refactor when `this._player.enableMQADecoder();` works....
|
|
323
|
-
*/
|
|
324
|
-
updatePassThrough() {
|
|
325
|
-
if (!i)
|
|
326
|
-
return;
|
|
327
|
-
const { activeDevice: e } = i;
|
|
328
|
-
if (i.passThrough === !0) {
|
|
329
|
-
this.#e.disableMQADecoder(), s.dispatchEvent(b(!0));
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
if (i.passThrough === !1)
|
|
333
|
-
if (this.#e.selectSystemDevice(), e.nativeDeviceId) {
|
|
334
|
-
const t = i.getNativeDevice(
|
|
335
|
-
e.nativeDeviceId
|
|
336
|
-
);
|
|
337
|
-
t && this.#e.selectDevice(
|
|
338
|
-
t,
|
|
339
|
-
i.deviceMode
|
|
340
|
-
);
|
|
341
|
-
} else
|
|
342
|
-
console.error(
|
|
343
|
-
"Passthrough could not be properly disabled since the nativeDeviceId is missing for",
|
|
344
|
-
e
|
|
345
|
-
);
|
|
346
|
-
this.#e.enableMQADecoder(), s.dispatchEvent(b(!1));
|
|
347
|
-
}
|
|
348
|
-
// eslint-disable-next-line class-methods-use-this
|
|
349
311
|
get ready() {
|
|
350
312
|
return Promise.resolve();
|
|
351
313
|
}
|
|
352
|
-
// eslint-disable-next-line class-methods-use-this
|
|
353
314
|
get volume() {
|
|
354
|
-
return
|
|
315
|
+
return v("desiredVolumeLevel");
|
|
355
316
|
}
|
|
356
317
|
set volume(e) {
|
|
357
318
|
this.debugLog("Setting volume to", e), this.#e.setVolume(e * 100);
|
|
358
319
|
}
|
|
359
320
|
}
|
|
360
321
|
export {
|
|
361
|
-
|
|
322
|
+
x as default
|
|
362
323
|
};
|
|
@@ -0,0 +1,224 @@
|
|
|
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
|
+
};
|