@scarlett-player/embed 1.5.1 → 1.6.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/embed.audio.js +300 -0
- package/dist/embed.audio.js.map +1 -1
- package/dist/embed.audio.umd.cjs +1 -1
- package/dist/embed.audio.umd.cjs.map +1 -1
- package/dist/embed.js +484 -52
- package/dist/embed.js.map +1 -1
- package/dist/embed.umd.cjs +1 -1
- package/dist/embed.umd.cjs.map +1 -1
- package/dist/embed.video.js +116 -0
- package/dist/embed.video.js.map +1 -1
- package/dist/embed.video.umd.cjs +1 -1
- package/dist/embed.video.umd.cjs.map +1 -1
- package/dist/hls2.js +12 -0
- package/dist/hls2.js.map +1 -0
- package/package.json +10 -10
package/dist/embed.audio.js
CHANGED
|
@@ -4220,6 +4220,272 @@ function createAudioUIPlugin(config) {
|
|
|
4220
4220
|
};
|
|
4221
4221
|
return plugin;
|
|
4222
4222
|
}
|
|
4223
|
+
var PLAYLIST_ICONS = {
|
|
4224
|
+
previous: '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 6h2v12H6V6zm3.5 6L18 6v12l-8.5-6z"/></svg>',
|
|
4225
|
+
next: '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z"/></svg>',
|
|
4226
|
+
list: '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M3 6h11v2H3V6zm0 5h11v2H3v-2zm0 5h7v2H3v-2zm13-1.5V8l6 3.5-6 3.5z"/></svg>'
|
|
4227
|
+
};
|
|
4228
|
+
var PlaylistSkipButton = class {
|
|
4229
|
+
constructor(plugin, direction) {
|
|
4230
|
+
this.plugin = plugin;
|
|
4231
|
+
this.direction = direction;
|
|
4232
|
+
this.clickHandler = () => {
|
|
4233
|
+
if (this.direction === "next") {
|
|
4234
|
+
this.plugin.next();
|
|
4235
|
+
} else {
|
|
4236
|
+
this.plugin.previous();
|
|
4237
|
+
}
|
|
4238
|
+
};
|
|
4239
|
+
const label = direction === "next" ? "Next item" : "Previous item";
|
|
4240
|
+
this.el = document.createElement("button");
|
|
4241
|
+
this.el.type = "button";
|
|
4242
|
+
this.el.className = `sp-control sp-playlist-skip sp-playlist-skip--${direction}`;
|
|
4243
|
+
this.el.setAttribute("aria-label", label);
|
|
4244
|
+
this.el.setAttribute("title", label);
|
|
4245
|
+
this.el.innerHTML = PLAYLIST_ICONS[direction];
|
|
4246
|
+
this.el.addEventListener("click", this.clickHandler);
|
|
4247
|
+
}
|
|
4248
|
+
render() {
|
|
4249
|
+
return this.el;
|
|
4250
|
+
}
|
|
4251
|
+
update() {
|
|
4252
|
+
const state = this.plugin.getState();
|
|
4253
|
+
if (state.tracks.length <= 1) {
|
|
4254
|
+
this.el.style.display = "none";
|
|
4255
|
+
return;
|
|
4256
|
+
}
|
|
4257
|
+
this.el.style.display = "";
|
|
4258
|
+
const enabled = this.direction === "next" ? state.hasNext : state.hasPrevious;
|
|
4259
|
+
this.el.disabled = !enabled;
|
|
4260
|
+
}
|
|
4261
|
+
destroy() {
|
|
4262
|
+
this.el.removeEventListener("click", this.clickHandler);
|
|
4263
|
+
this.el.remove();
|
|
4264
|
+
}
|
|
4265
|
+
};
|
|
4266
|
+
var PlaylistPanel = class {
|
|
4267
|
+
constructor(plugin, options) {
|
|
4268
|
+
this.plugin = plugin;
|
|
4269
|
+
this.options = options;
|
|
4270
|
+
this.open = false;
|
|
4271
|
+
this.renderedIds = "";
|
|
4272
|
+
this.toggleHandler = (event) => {
|
|
4273
|
+
event.stopPropagation();
|
|
4274
|
+
this.setOpen(!this.open);
|
|
4275
|
+
};
|
|
4276
|
+
this.documentClickHandler = () => {
|
|
4277
|
+
if (this.open) this.setOpen(false);
|
|
4278
|
+
};
|
|
4279
|
+
this.keydownHandler = (event) => {
|
|
4280
|
+
if (event.key === "Escape" && this.open) {
|
|
4281
|
+
this.setOpen(false);
|
|
4282
|
+
this.button.focus();
|
|
4283
|
+
}
|
|
4284
|
+
};
|
|
4285
|
+
this.el = document.createElement("div");
|
|
4286
|
+
this.el.className = "sp-playlist";
|
|
4287
|
+
this.button = document.createElement("button");
|
|
4288
|
+
this.button.type = "button";
|
|
4289
|
+
this.button.className = "sp-control sp-playlist__button";
|
|
4290
|
+
this.button.setAttribute("aria-label", "Playlist");
|
|
4291
|
+
this.button.setAttribute("title", "Playlist");
|
|
4292
|
+
this.button.setAttribute("aria-haspopup", "true");
|
|
4293
|
+
this.button.setAttribute("aria-expanded", "false");
|
|
4294
|
+
this.button.innerHTML = PLAYLIST_ICONS.list;
|
|
4295
|
+
this.panel = document.createElement("div");
|
|
4296
|
+
this.panel.className = "sp-playlist__panel";
|
|
4297
|
+
this.panel.setAttribute("role", "menu");
|
|
4298
|
+
this.panel.hidden = true;
|
|
4299
|
+
this.el.appendChild(this.button);
|
|
4300
|
+
this.el.appendChild(this.panel);
|
|
4301
|
+
this.button.addEventListener("click", this.toggleHandler);
|
|
4302
|
+
document.addEventListener("click", this.documentClickHandler);
|
|
4303
|
+
document.addEventListener("keydown", this.keydownHandler);
|
|
4304
|
+
}
|
|
4305
|
+
render() {
|
|
4306
|
+
return this.el;
|
|
4307
|
+
}
|
|
4308
|
+
update() {
|
|
4309
|
+
const state = this.plugin.getState();
|
|
4310
|
+
if (state.tracks.length <= 1) {
|
|
4311
|
+
this.el.style.display = "none";
|
|
4312
|
+
return;
|
|
4313
|
+
}
|
|
4314
|
+
this.el.style.display = "";
|
|
4315
|
+
const signature = state.tracks.map((track) => track.id).join("|");
|
|
4316
|
+
if (signature !== this.renderedIds) {
|
|
4317
|
+
this.renderedIds = signature;
|
|
4318
|
+
this.renderPanel(state.tracks, state.currentIndex);
|
|
4319
|
+
return;
|
|
4320
|
+
}
|
|
4321
|
+
this.markActive(state.currentIndex);
|
|
4322
|
+
}
|
|
4323
|
+
destroy() {
|
|
4324
|
+
this.button.removeEventListener("click", this.toggleHandler);
|
|
4325
|
+
document.removeEventListener("click", this.documentClickHandler);
|
|
4326
|
+
document.removeEventListener("keydown", this.keydownHandler);
|
|
4327
|
+
this.el.remove();
|
|
4328
|
+
}
|
|
4329
|
+
setOpen(open) {
|
|
4330
|
+
this.open = open;
|
|
4331
|
+
this.panel.hidden = !open;
|
|
4332
|
+
this.button.setAttribute("aria-expanded", String(open));
|
|
4333
|
+
this.el.classList.toggle("sp-playlist--open", open);
|
|
4334
|
+
}
|
|
4335
|
+
markActive(currentIndex) {
|
|
4336
|
+
const items = this.panel.querySelectorAll(".sp-playlist__item");
|
|
4337
|
+
items.forEach((item, index) => {
|
|
4338
|
+
item.classList.toggle("sp-playlist__item--active", index === currentIndex);
|
|
4339
|
+
item.setAttribute("aria-current", index === currentIndex ? "true" : "false");
|
|
4340
|
+
});
|
|
4341
|
+
}
|
|
4342
|
+
renderPanel(tracks, currentIndex) {
|
|
4343
|
+
this.panel.textContent = "";
|
|
4344
|
+
tracks.forEach((track, index) => {
|
|
4345
|
+
const item = document.createElement("button");
|
|
4346
|
+
item.type = "button";
|
|
4347
|
+
item.className = "sp-playlist__item";
|
|
4348
|
+
item.setAttribute("role", "menuitem");
|
|
4349
|
+
item.setAttribute("aria-current", index === currentIndex ? "true" : "false");
|
|
4350
|
+
if (index === currentIndex) {
|
|
4351
|
+
item.classList.add("sp-playlist__item--active");
|
|
4352
|
+
}
|
|
4353
|
+
const position = document.createElement("span");
|
|
4354
|
+
position.className = "sp-playlist__position";
|
|
4355
|
+
position.textContent = String(index + 1);
|
|
4356
|
+
const text = document.createElement("span");
|
|
4357
|
+
text.className = "sp-playlist__text";
|
|
4358
|
+
const title = document.createElement("span");
|
|
4359
|
+
title.className = "sp-playlist__title";
|
|
4360
|
+
title.textContent = track.title ?? `Item ${index + 1}`;
|
|
4361
|
+
text.appendChild(title);
|
|
4362
|
+
if (track.artist) {
|
|
4363
|
+
const artist = document.createElement("span");
|
|
4364
|
+
artist.className = "sp-playlist__artist";
|
|
4365
|
+
artist.textContent = track.artist;
|
|
4366
|
+
text.appendChild(artist);
|
|
4367
|
+
}
|
|
4368
|
+
item.appendChild(position);
|
|
4369
|
+
item.appendChild(text);
|
|
4370
|
+
item.addEventListener("click", (event) => {
|
|
4371
|
+
event.stopPropagation();
|
|
4372
|
+
this.options.onSelect(index);
|
|
4373
|
+
this.setOpen(false);
|
|
4374
|
+
});
|
|
4375
|
+
this.panel.appendChild(item);
|
|
4376
|
+
});
|
|
4377
|
+
}
|
|
4378
|
+
};
|
|
4379
|
+
var STYLE_ID = "sp-playlist-styles";
|
|
4380
|
+
var styles = `
|
|
4381
|
+
.sp-playlist-skip[disabled] {
|
|
4382
|
+
opacity: 0.4;
|
|
4383
|
+
cursor: default;
|
|
4384
|
+
}
|
|
4385
|
+
|
|
4386
|
+
.sp-playlist {
|
|
4387
|
+
position: relative;
|
|
4388
|
+
display: inline-flex;
|
|
4389
|
+
}
|
|
4390
|
+
|
|
4391
|
+
.sp-playlist__button svg,
|
|
4392
|
+
.sp-playlist-skip svg {
|
|
4393
|
+
width: 20px;
|
|
4394
|
+
height: 20px;
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4397
|
+
.sp-playlist__panel {
|
|
4398
|
+
position: absolute;
|
|
4399
|
+
bottom: calc(100% + 8px);
|
|
4400
|
+
right: 0;
|
|
4401
|
+
z-index: 20;
|
|
4402
|
+
display: flex;
|
|
4403
|
+
flex-direction: column;
|
|
4404
|
+
min-width: 240px;
|
|
4405
|
+
max-width: 320px;
|
|
4406
|
+
max-height: 300px;
|
|
4407
|
+
overflow-y: auto;
|
|
4408
|
+
padding: 4px;
|
|
4409
|
+
border-radius: 8px;
|
|
4410
|
+
background: rgba(20, 20, 20, 0.96);
|
|
4411
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4414
|
+
.sp-playlist__panel[hidden] {
|
|
4415
|
+
display: none;
|
|
4416
|
+
}
|
|
4417
|
+
|
|
4418
|
+
.sp-playlist__item {
|
|
4419
|
+
display: flex;
|
|
4420
|
+
gap: 10px;
|
|
4421
|
+
align-items: flex-start;
|
|
4422
|
+
width: 100%;
|
|
4423
|
+
padding: 8px 10px;
|
|
4424
|
+
border: 0;
|
|
4425
|
+
border-radius: 6px;
|
|
4426
|
+
background: transparent;
|
|
4427
|
+
color: #fff;
|
|
4428
|
+
font: inherit;
|
|
4429
|
+
text-align: left;
|
|
4430
|
+
cursor: pointer;
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4433
|
+
.sp-playlist__item:hover,
|
|
4434
|
+
.sp-playlist__item:focus-visible {
|
|
4435
|
+
background: rgba(255, 255, 255, 0.12);
|
|
4436
|
+
}
|
|
4437
|
+
|
|
4438
|
+
.sp-playlist__item--active {
|
|
4439
|
+
background: rgba(255, 255, 255, 0.08);
|
|
4440
|
+
}
|
|
4441
|
+
|
|
4442
|
+
.sp-playlist__item--active .sp-playlist__title {
|
|
4443
|
+
font-weight: 600;
|
|
4444
|
+
}
|
|
4445
|
+
|
|
4446
|
+
.sp-playlist__position {
|
|
4447
|
+
flex: 0 0 auto;
|
|
4448
|
+
min-width: 18px;
|
|
4449
|
+
color: rgba(255, 255, 255, 0.7);
|
|
4450
|
+
font-variant-numeric: tabular-nums;
|
|
4451
|
+
font-size: 12px;
|
|
4452
|
+
line-height: 18px;
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
.sp-playlist__text {
|
|
4456
|
+
display: flex;
|
|
4457
|
+
flex-direction: column;
|
|
4458
|
+
min-width: 0;
|
|
4459
|
+
}
|
|
4460
|
+
|
|
4461
|
+
.sp-playlist__title {
|
|
4462
|
+
font-size: 13px;
|
|
4463
|
+
line-height: 18px;
|
|
4464
|
+
}
|
|
4465
|
+
|
|
4466
|
+
.sp-playlist__artist {
|
|
4467
|
+
color: rgba(255, 255, 255, 0.6);
|
|
4468
|
+
font-size: 11px;
|
|
4469
|
+
line-height: 16px;
|
|
4470
|
+
}
|
|
4471
|
+
|
|
4472
|
+
@media (max-width: 480px) {
|
|
4473
|
+
.sp-playlist__panel {
|
|
4474
|
+
min-width: 200px;
|
|
4475
|
+
max-width: 76vw;
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
`;
|
|
4479
|
+
function injectStyles() {
|
|
4480
|
+
if (typeof document === "undefined" || document.getElementById(STYLE_ID)) {
|
|
4481
|
+
return null;
|
|
4482
|
+
}
|
|
4483
|
+
const el = document.createElement("style");
|
|
4484
|
+
el.id = STYLE_ID;
|
|
4485
|
+
el.textContent = styles;
|
|
4486
|
+
document.head.appendChild(el);
|
|
4487
|
+
return el;
|
|
4488
|
+
}
|
|
4223
4489
|
var DEFAULT_CONFIG$1 = {
|
|
4224
4490
|
autoAdvance: true,
|
|
4225
4491
|
preloadNext: true,
|
|
@@ -4409,8 +4675,42 @@ function createPlaylistPlugin(config) {
|
|
|
4409
4675
|
api?.emit("playlist:ended", void 0);
|
|
4410
4676
|
}
|
|
4411
4677
|
});
|
|
4678
|
+
injectStyles();
|
|
4679
|
+
void import("./hls2.js").then(({ registerControl }) => {
|
|
4680
|
+
const self = plugin;
|
|
4681
|
+
registerControl(
|
|
4682
|
+
"playlist-previous",
|
|
4683
|
+
() => new PlaylistSkipButton(self, "previous")
|
|
4684
|
+
);
|
|
4685
|
+
registerControl("playlist-next", () => new PlaylistSkipButton(self, "next"));
|
|
4686
|
+
registerControl(
|
|
4687
|
+
"playlist",
|
|
4688
|
+
() => new PlaylistPanel(self, {
|
|
4689
|
+
onSelect: (index) => self.play(index)
|
|
4690
|
+
})
|
|
4691
|
+
);
|
|
4692
|
+
}).catch(() => {
|
|
4693
|
+
api?.logger.debug("@scarlett-player/ui not present, playlist controls not registered");
|
|
4694
|
+
});
|
|
4695
|
+
const onKeyDown = (event) => {
|
|
4696
|
+
if (!api || !api.container.contains(document.activeElement)) return;
|
|
4697
|
+
const activeEl = document.activeElement;
|
|
4698
|
+
if (activeEl instanceof HTMLInputElement || activeEl instanceof HTMLTextAreaElement || activeEl instanceof HTMLSelectElement || activeEl?.isContentEditable) {
|
|
4699
|
+
return;
|
|
4700
|
+
}
|
|
4701
|
+
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
|
4702
|
+
if (event.key === "n" || event.key === "N") {
|
|
4703
|
+
event.preventDefault();
|
|
4704
|
+
plugin.next();
|
|
4705
|
+
} else if (event.key === "p" || event.key === "P") {
|
|
4706
|
+
event.preventDefault();
|
|
4707
|
+
plugin.previous();
|
|
4708
|
+
}
|
|
4709
|
+
};
|
|
4710
|
+
document.addEventListener("keydown", onKeyDown);
|
|
4412
4711
|
api.onDestroy(() => {
|
|
4413
4712
|
unsubEnded();
|
|
4713
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
4414
4714
|
if (advanceTimeout) {
|
|
4415
4715
|
clearTimeout(advanceTimeout);
|
|
4416
4716
|
advanceTimeout = null;
|