vidply 1.0.26 → 1.0.27
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/dev/{vidply.HLSRenderer-X46P47LY.js → vidply.HLSRenderer-ENLZE4QS.js} +13 -8
- package/dist/dev/vidply.HLSRenderer-ENLZE4QS.js.map +7 -0
- package/dist/dev/{vidply.HTML5Renderer-LXQ3I45Q.js → vidply.HTML5Renderer-6SBDI6S2.js} +2 -2
- package/dist/dev/vidply.SoundCloudRenderer-CD7VJKNS.js +280 -0
- package/dist/dev/vidply.SoundCloudRenderer-CD7VJKNS.js.map +7 -0
- package/dist/dev/{vidply.VimeoRenderer-DCETT5IZ.js → vidply.VimeoRenderer-VPH4RNES.js} +17 -4
- package/dist/dev/vidply.VimeoRenderer-VPH4RNES.js.map +7 -0
- package/dist/dev/{vidply.YouTubeRenderer-QLMMD757.js → vidply.YouTubeRenderer-6MGKEFTZ.js} +14 -6
- package/dist/dev/vidply.YouTubeRenderer-6MGKEFTZ.js.map +7 -0
- package/dist/dev/{vidply.chunk-UEIJOJH6.js → vidply.chunk-BCOFCT6U.js} +4 -1
- package/dist/dev/vidply.chunk-BCOFCT6U.js.map +7 -0
- package/dist/dev/vidply.esm.js +288 -12
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/legacy/vidply.js +609 -23
- package/dist/legacy/vidply.js.map +3 -3
- package/dist/legacy/vidply.min.js +1 -1
- package/dist/legacy/vidply.min.meta.json +26 -13
- package/dist/prod/vidply.HLSRenderer-CBXZ4RF2.min.js +6 -0
- package/dist/prod/{vidply.HTML5Renderer-XJCSUETP.min.js → vidply.HTML5Renderer-MY7XDV7R.min.js} +1 -1
- package/dist/prod/vidply.SoundCloudRenderer-MOR2CUFH.min.js +6 -0
- package/dist/prod/vidply.VimeoRenderer-3HBMM2WR.min.js +6 -0
- package/dist/prod/vidply.YouTubeRenderer-MFC2GMAC.min.js +6 -0
- package/dist/prod/vidply.chunk-OXXPY2XB.min.js +6 -0
- package/dist/prod/vidply.esm.min.js +6 -6
- package/dist/vidply.css +51 -0
- package/dist/vidply.esm.min.meta.json +56 -28
- package/dist/vidply.min.css +1 -1
- package/package.json +1 -1
- package/src/core/Player.js +117 -8
- package/src/features/PlaylistManager.js +312 -4
- package/src/renderers/HLSRenderer.js +17 -9
- package/src/renderers/HTML5Renderer.js +5 -0
- package/src/renderers/SoundCloudRenderer.js +355 -0
- package/src/renderers/VimeoRenderer.js +20 -4
- package/src/renderers/YouTubeRenderer.js +12 -6
- package/src/styles/vidply.css +51 -0
- package/dist/dev/vidply.HLSRenderer-X46P47LY.js.map +0 -7
- package/dist/dev/vidply.VimeoRenderer-DCETT5IZ.js.map +0 -7
- package/dist/dev/vidply.YouTubeRenderer-QLMMD757.js.map +0 -7
- package/dist/dev/vidply.chunk-UEIJOJH6.js.map +0 -7
- package/dist/prod/vidply.HLSRenderer-LDXSMWTI.min.js +0 -6
- package/dist/prod/vidply.VimeoRenderer-P3PU27S7.min.js +0 -6
- package/dist/prod/vidply.YouTubeRenderer-DGKKWB5M.min.js +0 -6
- package/dist/prod/vidply.chunk-BQBGEJF7.min.js +0 -6
- /package/dist/dev/{vidply.HTML5Renderer-LXQ3I45Q.js.map → vidply.HTML5Renderer-6SBDI6S2.js.map} +0 -0
package/dist/legacy/vidply.js
CHANGED
|
@@ -1647,6 +1647,9 @@
|
|
|
1647
1647
|
this.attachEvents();
|
|
1648
1648
|
this.media.preload = this.player.options.preload;
|
|
1649
1649
|
this.media.load();
|
|
1650
|
+
if (this.player.container) {
|
|
1651
|
+
this.player.container.classList.remove("vidply-external-controls");
|
|
1652
|
+
}
|
|
1650
1653
|
}
|
|
1651
1654
|
attachEvents() {
|
|
1652
1655
|
this.media.addEventListener("loadedmetadata", () => {
|
|
@@ -4417,7 +4420,8 @@
|
|
|
4417
4420
|
this.iframe = null;
|
|
4418
4421
|
}
|
|
4419
4422
|
async init() {
|
|
4420
|
-
|
|
4423
|
+
const src = this.player.currentSource || this.player.element.src;
|
|
4424
|
+
this.videoId = this.extractVideoId(src);
|
|
4421
4425
|
if (!this.videoId) {
|
|
4422
4426
|
throw new Error("Invalid YouTube URL");
|
|
4423
4427
|
}
|
|
@@ -4466,7 +4470,8 @@
|
|
|
4466
4470
|
this.iframe = document.createElement("div");
|
|
4467
4471
|
this.iframe.id = "youtube-player-".concat(Math.random().toString(36).substr(2, 9));
|
|
4468
4472
|
this.iframe.style.width = "100%";
|
|
4469
|
-
this.iframe.style.
|
|
4473
|
+
this.iframe.style.aspectRatio = "16 / 9";
|
|
4474
|
+
this.iframe.style.maxHeight = "100%";
|
|
4470
4475
|
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
4471
4476
|
}
|
|
4472
4477
|
async initializePlayer() {
|
|
@@ -4476,9 +4481,12 @@
|
|
|
4476
4481
|
width: "100%",
|
|
4477
4482
|
height: "100%",
|
|
4478
4483
|
playerVars: {
|
|
4479
|
-
controls:
|
|
4480
|
-
|
|
4481
|
-
|
|
4484
|
+
controls: 1,
|
|
4485
|
+
// Use YouTube native controls
|
|
4486
|
+
disablekb: 0,
|
|
4487
|
+
// Allow keyboard controls
|
|
4488
|
+
fs: 1,
|
|
4489
|
+
// Allow fullscreen
|
|
4482
4490
|
modestbranding: 1,
|
|
4483
4491
|
rel: 0,
|
|
4484
4492
|
showinfo: 0,
|
|
@@ -4491,6 +4499,9 @@
|
|
|
4491
4499
|
onReady: (event) => {
|
|
4492
4500
|
this.isReady = true;
|
|
4493
4501
|
this.attachEvents();
|
|
4502
|
+
if (this.player.container) {
|
|
4503
|
+
this.player.container.classList.add("vidply-external-controls");
|
|
4504
|
+
}
|
|
4494
4505
|
resolve();
|
|
4495
4506
|
},
|
|
4496
4507
|
onStateChange: (event) => this.handleStateChange(event),
|
|
@@ -4644,7 +4655,8 @@
|
|
|
4644
4655
|
this.iframe = null;
|
|
4645
4656
|
}
|
|
4646
4657
|
async init() {
|
|
4647
|
-
|
|
4658
|
+
const src = this.player.currentSource || this.player.element.src;
|
|
4659
|
+
this.videoId = this.extractVideoId(src);
|
|
4648
4660
|
if (!this.videoId) {
|
|
4649
4661
|
throw new Error("Invalid Vimeo URL");
|
|
4650
4662
|
}
|
|
@@ -4683,7 +4695,8 @@
|
|
|
4683
4695
|
this.iframe = document.createElement("div");
|
|
4684
4696
|
this.iframe.id = "vimeo-player-".concat(Math.random().toString(36).substr(2, 9));
|
|
4685
4697
|
this.iframe.style.width = "100%";
|
|
4686
|
-
this.iframe.style.
|
|
4698
|
+
this.iframe.style.aspectRatio = "16 / 9";
|
|
4699
|
+
this.iframe.style.maxHeight = "100%";
|
|
4687
4700
|
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
4688
4701
|
}
|
|
4689
4702
|
async initializePlayer() {
|
|
@@ -4691,7 +4704,8 @@
|
|
|
4691
4704
|
id: this.videoId,
|
|
4692
4705
|
width: "100%",
|
|
4693
4706
|
height: "100%",
|
|
4694
|
-
controls:
|
|
4707
|
+
controls: true,
|
|
4708
|
+
// Use Vimeo native controls
|
|
4695
4709
|
autoplay: this.player.options.autoplay,
|
|
4696
4710
|
muted: this.player.options.muted,
|
|
4697
4711
|
loop: this.player.options.loop,
|
|
@@ -4703,6 +4717,16 @@
|
|
|
4703
4717
|
this.vimeo = new window.Vimeo.Player(this.iframe.id, options);
|
|
4704
4718
|
await this.vimeo.ready();
|
|
4705
4719
|
this.isReady = true;
|
|
4720
|
+
const vimeoIframe = this.iframe.querySelector("iframe");
|
|
4721
|
+
if (vimeoIframe) {
|
|
4722
|
+
vimeoIframe.style.width = "100%";
|
|
4723
|
+
vimeoIframe.style.height = "100%";
|
|
4724
|
+
vimeoIframe.setAttribute("width", "100%");
|
|
4725
|
+
vimeoIframe.setAttribute("height", "100%");
|
|
4726
|
+
}
|
|
4727
|
+
if (this.player.container) {
|
|
4728
|
+
this.player.container.classList.add("vidply-external-controls");
|
|
4729
|
+
}
|
|
4706
4730
|
this.attachEvents();
|
|
4707
4731
|
try {
|
|
4708
4732
|
const duration = await this.vimeo.getDuration();
|
|
@@ -4915,12 +4939,14 @@
|
|
|
4915
4939
|
fragLoadingMaxRetryTimeout: 64e3
|
|
4916
4940
|
});
|
|
4917
4941
|
this.hls.attachMedia(this.media);
|
|
4918
|
-
let src;
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4942
|
+
let src = this.player.currentSource;
|
|
4943
|
+
if (!src) {
|
|
4944
|
+
const sourceElement = this.player.element.querySelector("source");
|
|
4945
|
+
if (sourceElement) {
|
|
4946
|
+
src = sourceElement.getAttribute("src");
|
|
4947
|
+
} else {
|
|
4948
|
+
src = this.player.element.getAttribute("src") || this.player.element.src;
|
|
4949
|
+
}
|
|
4924
4950
|
}
|
|
4925
4951
|
this.player.log("Loading HLS source: ".concat(src), "log");
|
|
4926
4952
|
if (!src) {
|
|
@@ -4943,6 +4969,9 @@
|
|
|
4943
4969
|
this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {
|
|
4944
4970
|
this.player.log("HLS manifest loaded, found " + data.levels.length + " quality levels");
|
|
4945
4971
|
this.player.emit("hlsmanifestparsed", data);
|
|
4972
|
+
if (this.player.container) {
|
|
4973
|
+
this.player.container.classList.remove("vidply-external-controls");
|
|
4974
|
+
}
|
|
4946
4975
|
});
|
|
4947
4976
|
this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {
|
|
4948
4977
|
this.player.log("HLS level switched to " + data.level);
|
|
@@ -5101,6 +5130,287 @@
|
|
|
5101
5130
|
}
|
|
5102
5131
|
});
|
|
5103
5132
|
|
|
5133
|
+
// src/renderers/SoundCloudRenderer.js
|
|
5134
|
+
var SoundCloudRenderer_exports = {};
|
|
5135
|
+
__export(SoundCloudRenderer_exports, {
|
|
5136
|
+
SoundCloudRenderer: () => SoundCloudRenderer,
|
|
5137
|
+
default: () => SoundCloudRenderer_default
|
|
5138
|
+
});
|
|
5139
|
+
var SoundCloudRenderer, SoundCloudRenderer_default;
|
|
5140
|
+
var init_SoundCloudRenderer = __esm({
|
|
5141
|
+
"src/renderers/SoundCloudRenderer.js"() {
|
|
5142
|
+
SoundCloudRenderer = class {
|
|
5143
|
+
constructor(player) {
|
|
5144
|
+
this.player = player;
|
|
5145
|
+
this.widget = null;
|
|
5146
|
+
this.trackUrl = null;
|
|
5147
|
+
this.isReady = false;
|
|
5148
|
+
this.iframe = null;
|
|
5149
|
+
this.iframeId = null;
|
|
5150
|
+
}
|
|
5151
|
+
async init() {
|
|
5152
|
+
var _a;
|
|
5153
|
+
this.trackUrl = this.player.currentSource || this.player.element.src || ((_a = this.player.element.querySelector("source")) == null ? void 0 : _a.src);
|
|
5154
|
+
if (!this.trackUrl || !this.isValidSoundCloudUrl(this.trackUrl)) {
|
|
5155
|
+
throw new Error("Invalid SoundCloud URL");
|
|
5156
|
+
}
|
|
5157
|
+
await this.loadSoundCloudAPI();
|
|
5158
|
+
this.createIframe();
|
|
5159
|
+
await this.initializeWidget();
|
|
5160
|
+
}
|
|
5161
|
+
/**
|
|
5162
|
+
* Validate SoundCloud URL
|
|
5163
|
+
* @param {string} url
|
|
5164
|
+
* @returns {boolean}
|
|
5165
|
+
*/
|
|
5166
|
+
isValidSoundCloudUrl(url) {
|
|
5167
|
+
return url.includes("soundcloud.com") || url.includes("api.soundcloud.com");
|
|
5168
|
+
}
|
|
5169
|
+
/**
|
|
5170
|
+
* Check if URL is a playlist/set
|
|
5171
|
+
*/
|
|
5172
|
+
isPlaylist() {
|
|
5173
|
+
return this.trackUrl && this.trackUrl.includes("/sets/");
|
|
5174
|
+
}
|
|
5175
|
+
/**
|
|
5176
|
+
* Extract track/playlist info from URL for embed
|
|
5177
|
+
* SoundCloud URLs can be:
|
|
5178
|
+
* - https://soundcloud.com/artist/track
|
|
5179
|
+
* - https://soundcloud.com/artist/sets/playlist
|
|
5180
|
+
* - https://api.soundcloud.com/tracks/123456
|
|
5181
|
+
*/
|
|
5182
|
+
getEmbedUrl() {
|
|
5183
|
+
const encodedUrl = encodeURIComponent(this.trackUrl);
|
|
5184
|
+
const params = new URLSearchParams({
|
|
5185
|
+
url: this.trackUrl,
|
|
5186
|
+
auto_play: this.player.options.autoplay ? "true" : "false",
|
|
5187
|
+
hide_related: "true",
|
|
5188
|
+
show_comments: "false",
|
|
5189
|
+
show_user: "true",
|
|
5190
|
+
show_reposts: "false",
|
|
5191
|
+
show_teaser: "false",
|
|
5192
|
+
visual: "false",
|
|
5193
|
+
// Use classic player for better control
|
|
5194
|
+
color: "%23007bff"
|
|
5195
|
+
});
|
|
5196
|
+
return "https://w.soundcloud.com/player/?".concat(params.toString());
|
|
5197
|
+
}
|
|
5198
|
+
async loadSoundCloudAPI() {
|
|
5199
|
+
if (window.SC && window.SC.Widget) {
|
|
5200
|
+
return Promise.resolve();
|
|
5201
|
+
}
|
|
5202
|
+
return new Promise((resolve, reject) => {
|
|
5203
|
+
const script = document.createElement("script");
|
|
5204
|
+
script.src = "https://w.soundcloud.com/player/api.js";
|
|
5205
|
+
script.onload = () => {
|
|
5206
|
+
setTimeout(() => {
|
|
5207
|
+
if (window.SC && window.SC.Widget) {
|
|
5208
|
+
resolve();
|
|
5209
|
+
} else {
|
|
5210
|
+
reject(new Error("SoundCloud Widget API not available"));
|
|
5211
|
+
}
|
|
5212
|
+
}, 100);
|
|
5213
|
+
};
|
|
5214
|
+
script.onerror = () => reject(new Error("Failed to load SoundCloud Widget API"));
|
|
5215
|
+
document.head.appendChild(script);
|
|
5216
|
+
});
|
|
5217
|
+
}
|
|
5218
|
+
createIframe() {
|
|
5219
|
+
this.player.element.style.display = "none";
|
|
5220
|
+
this.player.element.removeAttribute("poster");
|
|
5221
|
+
if (this.player.videoWrapper) {
|
|
5222
|
+
this.player.videoWrapper.classList.remove("vidply-forced-poster");
|
|
5223
|
+
this.player.videoWrapper.style.removeProperty("--vidply-poster-image");
|
|
5224
|
+
}
|
|
5225
|
+
this.iframeId = "soundcloud-player-".concat(Math.random().toString(36).substr(2, 9));
|
|
5226
|
+
this.iframe = document.createElement("iframe");
|
|
5227
|
+
this.iframe.id = this.iframeId;
|
|
5228
|
+
this.iframe.scrolling = "no";
|
|
5229
|
+
this.iframe.frameBorder = "no";
|
|
5230
|
+
this.iframe.allow = "autoplay";
|
|
5231
|
+
this.iframe.src = this.getEmbedUrl();
|
|
5232
|
+
this.iframe.style.width = "100%";
|
|
5233
|
+
this.iframe.style.display = "block";
|
|
5234
|
+
if (this.isPlaylist()) {
|
|
5235
|
+
this.iframe.style.aspectRatio = "16 / 9";
|
|
5236
|
+
this.iframe.classList.add("vidply-soundcloud-iframe", "vidply-soundcloud-playlist");
|
|
5237
|
+
} else {
|
|
5238
|
+
this.iframe.style.aspectRatio = "16 / 3";
|
|
5239
|
+
this.iframe.classList.add("vidply-soundcloud-iframe");
|
|
5240
|
+
}
|
|
5241
|
+
this.iframe.style.maxHeight = "100%";
|
|
5242
|
+
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
5243
|
+
}
|
|
5244
|
+
async initializeWidget() {
|
|
5245
|
+
return new Promise((resolve, reject) => {
|
|
5246
|
+
this.iframe.addEventListener("load", () => {
|
|
5247
|
+
try {
|
|
5248
|
+
this.widget = window.SC.Widget(this.iframe);
|
|
5249
|
+
this.widget.bind(window.SC.Widget.Events.READY, () => {
|
|
5250
|
+
this.isReady = true;
|
|
5251
|
+
this.attachEvents();
|
|
5252
|
+
if (this.player.container) {
|
|
5253
|
+
this.player.container.classList.add("vidply-external-controls");
|
|
5254
|
+
}
|
|
5255
|
+
this.widget.getCurrentSound((sound) => {
|
|
5256
|
+
if (sound) {
|
|
5257
|
+
this.player.state.duration = sound.duration / 1e3;
|
|
5258
|
+
this.player.emit("loadedmetadata");
|
|
5259
|
+
}
|
|
5260
|
+
});
|
|
5261
|
+
resolve();
|
|
5262
|
+
});
|
|
5263
|
+
this.widget.bind(window.SC.Widget.Events.ERROR, (error) => {
|
|
5264
|
+
this.player.handleError(new Error("SoundCloud error: ".concat(error.message || "Unknown error")));
|
|
5265
|
+
});
|
|
5266
|
+
} catch (error) {
|
|
5267
|
+
reject(error);
|
|
5268
|
+
}
|
|
5269
|
+
});
|
|
5270
|
+
setTimeout(() => {
|
|
5271
|
+
if (!this.isReady) {
|
|
5272
|
+
reject(new Error("SoundCloud widget initialization timeout"));
|
|
5273
|
+
}
|
|
5274
|
+
}, 1e4);
|
|
5275
|
+
});
|
|
5276
|
+
}
|
|
5277
|
+
attachEvents() {
|
|
5278
|
+
if (!this.widget) return;
|
|
5279
|
+
const Events = window.SC.Widget.Events;
|
|
5280
|
+
this.widget.bind(Events.PLAY, () => {
|
|
5281
|
+
this.player.state.playing = true;
|
|
5282
|
+
this.player.state.paused = false;
|
|
5283
|
+
this.player.state.ended = false;
|
|
5284
|
+
this.player.emit("play");
|
|
5285
|
+
if (this.player.options.onPlay) {
|
|
5286
|
+
this.player.options.onPlay.call(this.player);
|
|
5287
|
+
}
|
|
5288
|
+
});
|
|
5289
|
+
this.widget.bind(Events.PAUSE, () => {
|
|
5290
|
+
this.player.state.playing = false;
|
|
5291
|
+
this.player.state.paused = true;
|
|
5292
|
+
this.player.emit("pause");
|
|
5293
|
+
if (this.player.options.onPause) {
|
|
5294
|
+
this.player.options.onPause.call(this.player);
|
|
5295
|
+
}
|
|
5296
|
+
});
|
|
5297
|
+
this.widget.bind(Events.FINISH, () => {
|
|
5298
|
+
this.player.state.playing = false;
|
|
5299
|
+
this.player.state.paused = true;
|
|
5300
|
+
this.player.state.ended = true;
|
|
5301
|
+
this.player.emit("ended");
|
|
5302
|
+
if (this.player.options.onEnded) {
|
|
5303
|
+
this.player.options.onEnded.call(this.player);
|
|
5304
|
+
}
|
|
5305
|
+
if (this.player.options.loop) {
|
|
5306
|
+
this.seek(0);
|
|
5307
|
+
this.play();
|
|
5308
|
+
}
|
|
5309
|
+
});
|
|
5310
|
+
this.widget.bind(Events.PLAY_PROGRESS, (data) => {
|
|
5311
|
+
const currentTime = data.currentPosition / 1e3;
|
|
5312
|
+
this.player.state.currentTime = currentTime;
|
|
5313
|
+
this.player.emit("timeupdate", currentTime);
|
|
5314
|
+
if (this.player.options.onTimeUpdate) {
|
|
5315
|
+
this.player.options.onTimeUpdate.call(this.player, currentTime);
|
|
5316
|
+
}
|
|
5317
|
+
});
|
|
5318
|
+
this.widget.bind(Events.SEEK, (data) => {
|
|
5319
|
+
this.player.state.currentTime = data.currentPosition / 1e3;
|
|
5320
|
+
this.player.emit("seeked");
|
|
5321
|
+
});
|
|
5322
|
+
this.widget.bind(Events.LOAD_PROGRESS, (data) => {
|
|
5323
|
+
if (this.player.state.duration) {
|
|
5324
|
+
const buffered = data.loadedProgress * this.player.state.duration;
|
|
5325
|
+
this.player.emit("progress", buffered);
|
|
5326
|
+
}
|
|
5327
|
+
});
|
|
5328
|
+
}
|
|
5329
|
+
play() {
|
|
5330
|
+
if (this.isReady && this.widget) {
|
|
5331
|
+
const scrollX = window.scrollX;
|
|
5332
|
+
const scrollY = window.scrollY;
|
|
5333
|
+
this.widget.play();
|
|
5334
|
+
window.scrollTo(scrollX, scrollY);
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
5337
|
+
pause() {
|
|
5338
|
+
if (this.isReady && this.widget) {
|
|
5339
|
+
this.widget.pause();
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
seek(time) {
|
|
5343
|
+
if (this.isReady && this.widget) {
|
|
5344
|
+
this.widget.seekTo(time * 1e3);
|
|
5345
|
+
this.player.state.currentTime = time;
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
setVolume(volume) {
|
|
5349
|
+
if (this.isReady && this.widget) {
|
|
5350
|
+
this.widget.setVolume(volume * 100);
|
|
5351
|
+
this.player.state.volume = volume;
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5354
|
+
setMuted(muted) {
|
|
5355
|
+
if (this.isReady && this.widget) {
|
|
5356
|
+
if (muted) {
|
|
5357
|
+
this.widget.getVolume((vol) => {
|
|
5358
|
+
this._previousVolume = vol;
|
|
5359
|
+
this.widget.setVolume(0);
|
|
5360
|
+
});
|
|
5361
|
+
} else {
|
|
5362
|
+
this.widget.setVolume(this._previousVolume || 100);
|
|
5363
|
+
}
|
|
5364
|
+
this.player.state.muted = muted;
|
|
5365
|
+
}
|
|
5366
|
+
}
|
|
5367
|
+
setPlaybackSpeed(speed) {
|
|
5368
|
+
this.player.log("SoundCloud does not support playback speed control", "warn");
|
|
5369
|
+
}
|
|
5370
|
+
/**
|
|
5371
|
+
* Get current track info
|
|
5372
|
+
* @returns {Promise<Object>}
|
|
5373
|
+
*/
|
|
5374
|
+
getCurrentSound() {
|
|
5375
|
+
return new Promise((resolve) => {
|
|
5376
|
+
if (this.isReady && this.widget) {
|
|
5377
|
+
this.widget.getCurrentSound((sound) => {
|
|
5378
|
+
resolve(sound);
|
|
5379
|
+
});
|
|
5380
|
+
} else {
|
|
5381
|
+
resolve(null);
|
|
5382
|
+
}
|
|
5383
|
+
});
|
|
5384
|
+
}
|
|
5385
|
+
destroy() {
|
|
5386
|
+
if (this.widget) {
|
|
5387
|
+
const Events = window.SC.Widget.Events;
|
|
5388
|
+
try {
|
|
5389
|
+
this.widget.unbind(Events.READY);
|
|
5390
|
+
this.widget.unbind(Events.PLAY);
|
|
5391
|
+
this.widget.unbind(Events.PAUSE);
|
|
5392
|
+
this.widget.unbind(Events.FINISH);
|
|
5393
|
+
this.widget.unbind(Events.PLAY_PROGRESS);
|
|
5394
|
+
this.widget.unbind(Events.SEEK);
|
|
5395
|
+
this.widget.unbind(Events.LOAD_PROGRESS);
|
|
5396
|
+
this.widget.unbind(Events.ERROR);
|
|
5397
|
+
} catch (e) {
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5400
|
+
if (this.iframe && this.iframe.parentNode) {
|
|
5401
|
+
this.iframe.parentNode.removeChild(this.iframe);
|
|
5402
|
+
}
|
|
5403
|
+
if (this.player.element) {
|
|
5404
|
+
this.player.element.style.display = "";
|
|
5405
|
+
}
|
|
5406
|
+
this.widget = null;
|
|
5407
|
+
this.isReady = false;
|
|
5408
|
+
}
|
|
5409
|
+
};
|
|
5410
|
+
SoundCloudRenderer_default = SoundCloudRenderer;
|
|
5411
|
+
}
|
|
5412
|
+
});
|
|
5413
|
+
|
|
5104
5414
|
// src/utils/EventEmitter.js
|
|
5105
5415
|
var EventEmitter = class {
|
|
5106
5416
|
constructor() {
|
|
@@ -8180,6 +8490,7 @@
|
|
|
8180
8490
|
this.element.appendChild(mediaElement);
|
|
8181
8491
|
this.element = mediaElement;
|
|
8182
8492
|
}
|
|
8493
|
+
this._originalElement = this.element;
|
|
8183
8494
|
this.options = __spreadValues({
|
|
8184
8495
|
// Display
|
|
8185
8496
|
width: null,
|
|
@@ -8594,10 +8905,12 @@
|
|
|
8594
8905
|
}
|
|
8595
8906
|
async initializeRenderer() {
|
|
8596
8907
|
var _a;
|
|
8597
|
-
|
|
8908
|
+
let src = this._pendingSource || this.element.src || ((_a = this.element.querySelector("source")) == null ? void 0 : _a.src);
|
|
8598
8909
|
if (!src) {
|
|
8599
8910
|
throw new Error("No media source found");
|
|
8600
8911
|
}
|
|
8912
|
+
this.currentSource = src;
|
|
8913
|
+
this._pendingSource = null;
|
|
8601
8914
|
const sourceElements = this.sourceElements;
|
|
8602
8915
|
for (const sourceEl of sourceElements) {
|
|
8603
8916
|
const descSrc = sourceEl.getAttribute("data-desc-src");
|
|
@@ -8658,6 +8971,9 @@
|
|
|
8658
8971
|
} else if (src.includes(".m3u8")) {
|
|
8659
8972
|
const module = await Promise.resolve().then(() => (init_HLSRenderer(), HLSRenderer_exports));
|
|
8660
8973
|
rendererClass = module.HLSRenderer || module.default;
|
|
8974
|
+
} else if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
|
|
8975
|
+
const module = await Promise.resolve().then(() => (init_SoundCloudRenderer(), SoundCloudRenderer_exports));
|
|
8976
|
+
rendererClass = module.SoundCloudRenderer || module.default;
|
|
8661
8977
|
}
|
|
8662
8978
|
this.log("Using ".concat((rendererClass == null ? void 0 : rendererClass.name) || "HTML5Renderer", " renderer"));
|
|
8663
8979
|
this.renderer = new rendererClass(this);
|
|
@@ -8769,6 +9085,11 @@
|
|
|
8769
9085
|
const resolvedPoster = this.resolvePosterPath(poster);
|
|
8770
9086
|
this.videoWrapper.style.setProperty("--vidply-poster-image", 'url("'.concat(resolvedPoster, '")'));
|
|
8771
9087
|
this.videoWrapper.classList.add("vidply-forced-poster");
|
|
9088
|
+
if (this._isAudioContent && this.container) {
|
|
9089
|
+
this.container.classList.add("vidply-audio-content");
|
|
9090
|
+
} else if (this.container) {
|
|
9091
|
+
this.container.classList.remove("vidply-audio-content");
|
|
9092
|
+
}
|
|
8772
9093
|
}
|
|
8773
9094
|
hidePosterOverlay() {
|
|
8774
9095
|
if (!this.videoWrapper) {
|
|
@@ -8811,6 +9132,15 @@
|
|
|
8811
9132
|
* @param {string} [config.audioDescriptionSrc] - Audio description video URL
|
|
8812
9133
|
* @param {string} [config.signLanguageSrc] - Sign language video URL
|
|
8813
9134
|
*/
|
|
9135
|
+
/**
|
|
9136
|
+
* Check if a source URL requires an external renderer (YouTube, Vimeo, SoundCloud, HLS)
|
|
9137
|
+
* @param {string} src - Source URL
|
|
9138
|
+
* @returns {boolean}
|
|
9139
|
+
*/
|
|
9140
|
+
isExternalRendererUrl(src) {
|
|
9141
|
+
if (!src) return false;
|
|
9142
|
+
return src.includes("youtube.com") || src.includes("youtu.be") || src.includes("vimeo.com") || src.includes("soundcloud.com") || src.includes("api.soundcloud.com") || src.includes(".m3u8");
|
|
9143
|
+
}
|
|
8814
9144
|
async load(config) {
|
|
8815
9145
|
var _a;
|
|
8816
9146
|
try {
|
|
@@ -8823,12 +9153,44 @@
|
|
|
8823
9153
|
const existingTracks = this.trackElements;
|
|
8824
9154
|
existingTracks.forEach((track) => track.remove());
|
|
8825
9155
|
this.invalidateTrackCache();
|
|
8826
|
-
|
|
8827
|
-
if (
|
|
8828
|
-
this.
|
|
9156
|
+
const isExternalRenderer = this.isExternalRendererUrl(config.src);
|
|
9157
|
+
if (isExternalRenderer) {
|
|
9158
|
+
this._switchingRenderer = true;
|
|
9159
|
+
}
|
|
9160
|
+
if (!isExternalRenderer) {
|
|
9161
|
+
this.element.src = config.src;
|
|
9162
|
+
if (config.type) {
|
|
9163
|
+
this.element.type = config.type;
|
|
9164
|
+
}
|
|
9165
|
+
} else {
|
|
9166
|
+
this.element.removeAttribute("src");
|
|
9167
|
+
const sources = this.element.querySelectorAll("source");
|
|
9168
|
+
sources.forEach((s) => s.removeAttribute("src"));
|
|
9169
|
+
}
|
|
9170
|
+
this._pendingSource = config.src;
|
|
9171
|
+
this._isAudioContent = config.type && config.type.startsWith("audio/");
|
|
9172
|
+
if (this.container) {
|
|
9173
|
+
if (this._isAudioContent) {
|
|
9174
|
+
this.container.classList.add("vidply-audio-content");
|
|
9175
|
+
} else {
|
|
9176
|
+
this.container.classList.remove("vidply-audio-content");
|
|
9177
|
+
}
|
|
8829
9178
|
}
|
|
8830
9179
|
if (config.poster && this.element.tagName === "VIDEO") {
|
|
8831
|
-
|
|
9180
|
+
if (this._isAudioContent) {
|
|
9181
|
+
this.element.removeAttribute("poster");
|
|
9182
|
+
if (this.videoWrapper) {
|
|
9183
|
+
const resolvedPoster = this.resolvePosterPath(config.poster);
|
|
9184
|
+
this.videoWrapper.style.setProperty("--vidply-poster-image", 'url("'.concat(resolvedPoster, '")'));
|
|
9185
|
+
this.videoWrapper.classList.add("vidply-forced-poster");
|
|
9186
|
+
}
|
|
9187
|
+
} else {
|
|
9188
|
+
this.element.poster = this.resolvePosterPath(config.poster);
|
|
9189
|
+
if (this.videoWrapper) {
|
|
9190
|
+
this.videoWrapper.classList.remove("vidply-forced-poster");
|
|
9191
|
+
this.videoWrapper.style.removeProperty("--vidply-poster-image");
|
|
9192
|
+
}
|
|
9193
|
+
}
|
|
8832
9194
|
}
|
|
8833
9195
|
if (config.tracks && config.tracks.length > 0) {
|
|
8834
9196
|
config.tracks.forEach((trackConfig) => {
|
|
@@ -8871,6 +9233,13 @@
|
|
|
8871
9233
|
this.renderer.media = this.element;
|
|
8872
9234
|
this.element.load();
|
|
8873
9235
|
}
|
|
9236
|
+
if (isExternalRenderer) {
|
|
9237
|
+
setTimeout(() => {
|
|
9238
|
+
this._switchingRenderer = false;
|
|
9239
|
+
}, 500);
|
|
9240
|
+
} else {
|
|
9241
|
+
this._switchingRenderer = false;
|
|
9242
|
+
}
|
|
8874
9243
|
window.scrollTo(scrollX, scrollY);
|
|
8875
9244
|
if (this.captionManager) {
|
|
8876
9245
|
this.captionManager.destroy();
|
|
@@ -8929,11 +9298,13 @@
|
|
|
8929
9298
|
const isYouTube = src.includes("youtube.com") || src.includes("youtu.be");
|
|
8930
9299
|
const isVimeo = src.includes("vimeo.com");
|
|
8931
9300
|
const isHLS = src.includes(".m3u8");
|
|
9301
|
+
const isSoundCloud = src.includes("soundcloud.com") || src.includes("api.soundcloud.com");
|
|
8932
9302
|
const currentRendererName = this.renderer.constructor.name;
|
|
8933
9303
|
if (isYouTube && currentRendererName !== "YouTubeRenderer") return true;
|
|
8934
9304
|
if (isVimeo && currentRendererName !== "VimeoRenderer") return true;
|
|
8935
9305
|
if (isHLS && currentRendererName !== "HLSRenderer") return true;
|
|
8936
|
-
if (
|
|
9306
|
+
if (isSoundCloud && currentRendererName !== "SoundCloudRenderer") return true;
|
|
9307
|
+
if (!isYouTube && !isVimeo && !isHLS && !isSoundCloud && currentRendererName !== "HTML5Renderer") return true;
|
|
8937
9308
|
return false;
|
|
8938
9309
|
}
|
|
8939
9310
|
// Playback controls
|
|
@@ -11148,6 +11519,10 @@
|
|
|
11148
11519
|
}
|
|
11149
11520
|
// Error handling
|
|
11150
11521
|
handleError(error) {
|
|
11522
|
+
if (this._switchingRenderer) {
|
|
11523
|
+
this.log("Suppressing error during renderer switch:", error, "debug");
|
|
11524
|
+
return;
|
|
11525
|
+
}
|
|
11151
11526
|
this.log("Error:", error, "error");
|
|
11152
11527
|
this.emit("error", error);
|
|
11153
11528
|
if (this.options.onError) {
|
|
@@ -11691,7 +12066,9 @@
|
|
|
11691
12066
|
autoPlayFirst: options.autoPlayFirst !== false,
|
|
11692
12067
|
// Default true - auto-play first track on load
|
|
11693
12068
|
loop: options.loop || false,
|
|
11694
|
-
showPanel: options.showPanel !== false
|
|
12069
|
+
showPanel: options.showPanel !== false,
|
|
12070
|
+
// Default true
|
|
12071
|
+
recreatePlayers: options.recreatePlayers || false
|
|
11695
12072
|
}, options);
|
|
11696
12073
|
this.container = null;
|
|
11697
12074
|
this.playlistPanel = null;
|
|
@@ -11699,6 +12076,8 @@
|
|
|
11699
12076
|
this.navigationFeedback = null;
|
|
11700
12077
|
this.isPanelVisible = this.options.showPanel !== false;
|
|
11701
12078
|
this.isChangingTrack = false;
|
|
12079
|
+
this.hostElement = options.hostElement || null;
|
|
12080
|
+
this.PlayerClass = options.PlayerClass || null;
|
|
11702
12081
|
this.handleTrackEnd = this.handleTrackEnd.bind(this);
|
|
11703
12082
|
this.handleTrackError = this.handleTrackError.bind(this);
|
|
11704
12083
|
this.player.playlistManager = this;
|
|
@@ -11708,6 +12087,159 @@
|
|
|
11708
12087
|
this.loadPlaylist(this.initialTracks);
|
|
11709
12088
|
}
|
|
11710
12089
|
}
|
|
12090
|
+
/**
|
|
12091
|
+
* Determine the media type for a track
|
|
12092
|
+
* @param {Object} track - Track object
|
|
12093
|
+
* @returns {string} - 'audio', 'video', 'youtube', 'vimeo', 'soundcloud', 'hls'
|
|
12094
|
+
*/
|
|
12095
|
+
getTrackMediaType(track) {
|
|
12096
|
+
const src = track.src || "";
|
|
12097
|
+
if (src.includes("youtube.com") || src.includes("youtu.be")) {
|
|
12098
|
+
return "youtube";
|
|
12099
|
+
}
|
|
12100
|
+
if (src.includes("vimeo.com")) {
|
|
12101
|
+
return "vimeo";
|
|
12102
|
+
}
|
|
12103
|
+
if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
|
|
12104
|
+
return "soundcloud";
|
|
12105
|
+
}
|
|
12106
|
+
if (src.includes(".m3u8")) {
|
|
12107
|
+
return "hls";
|
|
12108
|
+
}
|
|
12109
|
+
if (track.type && track.type.startsWith("audio/")) {
|
|
12110
|
+
return "audio";
|
|
12111
|
+
}
|
|
12112
|
+
return "video";
|
|
12113
|
+
}
|
|
12114
|
+
/**
|
|
12115
|
+
* Recreate the player with the appropriate element type for the track
|
|
12116
|
+
* @param {Object} track - Track to load
|
|
12117
|
+
* @param {boolean} autoPlay - Whether to auto-play after creation
|
|
12118
|
+
*/
|
|
12119
|
+
async recreatePlayerForTrack(track, autoPlay = false) {
|
|
12120
|
+
if (!this.hostElement || !this.PlayerClass) {
|
|
12121
|
+
console.warn("VidPly Playlist: Cannot recreate player - missing hostElement or PlayerClass");
|
|
12122
|
+
return false;
|
|
12123
|
+
}
|
|
12124
|
+
const mediaType = this.getTrackMediaType(track);
|
|
12125
|
+
const elementType = mediaType === "audio" ? "audio" : "video";
|
|
12126
|
+
const wasVisible = this.isPanelVisible;
|
|
12127
|
+
const savedTracks = [...this.tracks];
|
|
12128
|
+
const savedIndex = this.currentIndex;
|
|
12129
|
+
if (this.trackArtworkElement && this.trackArtworkElement.parentNode) {
|
|
12130
|
+
this.trackArtworkElement.parentNode.removeChild(this.trackArtworkElement);
|
|
12131
|
+
}
|
|
12132
|
+
if (this.trackInfoElement && this.trackInfoElement.parentNode) {
|
|
12133
|
+
this.trackInfoElement.parentNode.removeChild(this.trackInfoElement);
|
|
12134
|
+
}
|
|
12135
|
+
if (this.navigationFeedback && this.navigationFeedback.parentNode) {
|
|
12136
|
+
this.navigationFeedback.parentNode.removeChild(this.navigationFeedback);
|
|
12137
|
+
}
|
|
12138
|
+
if (this.playlistPanel && this.playlistPanel.parentNode) {
|
|
12139
|
+
this.playlistPanel.parentNode.removeChild(this.playlistPanel);
|
|
12140
|
+
}
|
|
12141
|
+
if (this.player) {
|
|
12142
|
+
this.player.off("ended", this.handleTrackEnd);
|
|
12143
|
+
this.player.off("error", this.handleTrackError);
|
|
12144
|
+
this.player.destroy();
|
|
12145
|
+
}
|
|
12146
|
+
this.hostElement.innerHTML = "";
|
|
12147
|
+
const mediaElement = document.createElement(elementType);
|
|
12148
|
+
mediaElement.setAttribute("preload", "metadata");
|
|
12149
|
+
if (elementType === "video" && track.poster && (mediaType === "video" || mediaType === "hls")) {
|
|
12150
|
+
mediaElement.setAttribute("poster", track.poster);
|
|
12151
|
+
}
|
|
12152
|
+
const isExternalRenderer = ["youtube", "vimeo", "soundcloud", "hls"].includes(mediaType);
|
|
12153
|
+
if (!isExternalRenderer) {
|
|
12154
|
+
const source = document.createElement("source");
|
|
12155
|
+
source.src = track.src;
|
|
12156
|
+
if (track.type) {
|
|
12157
|
+
source.type = track.type;
|
|
12158
|
+
}
|
|
12159
|
+
mediaElement.appendChild(source);
|
|
12160
|
+
if (track.tracks && track.tracks.length > 0) {
|
|
12161
|
+
track.tracks.forEach((trackConfig) => {
|
|
12162
|
+
const trackEl = document.createElement("track");
|
|
12163
|
+
trackEl.src = trackConfig.src;
|
|
12164
|
+
trackEl.kind = trackConfig.kind || "captions";
|
|
12165
|
+
trackEl.srclang = trackConfig.srclang || "en";
|
|
12166
|
+
trackEl.label = trackConfig.label || trackConfig.srclang;
|
|
12167
|
+
if (trackConfig.default) {
|
|
12168
|
+
trackEl.default = true;
|
|
12169
|
+
}
|
|
12170
|
+
mediaElement.appendChild(trackEl);
|
|
12171
|
+
});
|
|
12172
|
+
}
|
|
12173
|
+
}
|
|
12174
|
+
this.hostElement.appendChild(mediaElement);
|
|
12175
|
+
const playerOptions = {
|
|
12176
|
+
mediaType: elementType,
|
|
12177
|
+
poster: track.poster,
|
|
12178
|
+
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
12179
|
+
audioDescriptionDuration: track.audioDescriptionDuration || null,
|
|
12180
|
+
signLanguageSrc: track.signLanguageSrc || null
|
|
12181
|
+
};
|
|
12182
|
+
this.player = new this.PlayerClass(mediaElement, playerOptions);
|
|
12183
|
+
this.player.playlistManager = this;
|
|
12184
|
+
await new Promise((resolve) => {
|
|
12185
|
+
this.player.on("ready", resolve);
|
|
12186
|
+
});
|
|
12187
|
+
this.player.on("ended", this.handleTrackEnd);
|
|
12188
|
+
this.player.on("error", this.handleTrackError);
|
|
12189
|
+
if (this.player.container) {
|
|
12190
|
+
if (this.trackArtworkElement) {
|
|
12191
|
+
const videoWrapper = this.player.container.querySelector(".vidply-video-wrapper");
|
|
12192
|
+
if (videoWrapper) {
|
|
12193
|
+
this.player.container.insertBefore(this.trackArtworkElement, videoWrapper);
|
|
12194
|
+
} else {
|
|
12195
|
+
this.player.container.appendChild(this.trackArtworkElement);
|
|
12196
|
+
}
|
|
12197
|
+
}
|
|
12198
|
+
if (this.trackInfoElement) {
|
|
12199
|
+
this.player.container.appendChild(this.trackInfoElement);
|
|
12200
|
+
}
|
|
12201
|
+
if (this.navigationFeedback) {
|
|
12202
|
+
this.player.container.appendChild(this.navigationFeedback);
|
|
12203
|
+
}
|
|
12204
|
+
if (this.playlistPanel) {
|
|
12205
|
+
this.player.container.appendChild(this.playlistPanel);
|
|
12206
|
+
}
|
|
12207
|
+
}
|
|
12208
|
+
this.container = this.player.container;
|
|
12209
|
+
this.updatePlayerControls();
|
|
12210
|
+
this.tracks = savedTracks;
|
|
12211
|
+
this.currentIndex = savedIndex;
|
|
12212
|
+
this.updatePlaylistUI();
|
|
12213
|
+
this.isPanelVisible = wasVisible;
|
|
12214
|
+
if (this.playlistPanel) {
|
|
12215
|
+
this.playlistPanel.style.display = wasVisible ? "" : "none";
|
|
12216
|
+
}
|
|
12217
|
+
if (isExternalRenderer) {
|
|
12218
|
+
this.player.load({
|
|
12219
|
+
src: track.src,
|
|
12220
|
+
type: track.type,
|
|
12221
|
+
poster: track.poster,
|
|
12222
|
+
tracks: track.tracks || [],
|
|
12223
|
+
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
12224
|
+
signLanguageSrc: track.signLanguageSrc || null
|
|
12225
|
+
});
|
|
12226
|
+
} else {
|
|
12227
|
+
this.player.load({
|
|
12228
|
+
src: track.src,
|
|
12229
|
+
type: track.type,
|
|
12230
|
+
poster: track.poster,
|
|
12231
|
+
tracks: track.tracks || [],
|
|
12232
|
+
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
12233
|
+
signLanguageSrc: track.signLanguageSrc || null
|
|
12234
|
+
});
|
|
12235
|
+
}
|
|
12236
|
+
if (autoPlay) {
|
|
12237
|
+
setTimeout(() => {
|
|
12238
|
+
this.player.play();
|
|
12239
|
+
}, 100);
|
|
12240
|
+
}
|
|
12241
|
+
return true;
|
|
12242
|
+
}
|
|
11711
12243
|
init() {
|
|
11712
12244
|
this.player.on("ended", this.handleTrackEnd);
|
|
11713
12245
|
this.player.on("error", this.handleTrackError);
|
|
@@ -11818,7 +12350,7 @@
|
|
|
11818
12350
|
* Load a track without playing
|
|
11819
12351
|
* @param {number} index - Track index
|
|
11820
12352
|
*/
|
|
11821
|
-
loadTrack(index) {
|
|
12353
|
+
async loadTrack(index) {
|
|
11822
12354
|
if (index < 0 || index >= this.tracks.length) {
|
|
11823
12355
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
11824
12356
|
return;
|
|
@@ -11826,6 +12358,25 @@
|
|
|
11826
12358
|
const track = this.tracks[index];
|
|
11827
12359
|
this.isChangingTrack = true;
|
|
11828
12360
|
this.currentIndex = index;
|
|
12361
|
+
if (this.options.recreatePlayers && this.hostElement && this.PlayerClass) {
|
|
12362
|
+
const currentMediaType = this.player ? this.player.element.tagName === "AUDIO" ? "audio" : "video" : null;
|
|
12363
|
+
const newMediaType = this.getTrackMediaType(track);
|
|
12364
|
+
const newElementType = newMediaType === "audio" || newMediaType === "soundcloud" ? "audio" : "video";
|
|
12365
|
+
if (currentMediaType !== newElementType) {
|
|
12366
|
+
await this.recreatePlayerForTrack(track, false);
|
|
12367
|
+
this.updateTrackInfo(track);
|
|
12368
|
+
this.updatePlaylistUI();
|
|
12369
|
+
this.player.emit("playlisttrackchange", {
|
|
12370
|
+
index,
|
|
12371
|
+
item: track,
|
|
12372
|
+
total: this.tracks.length
|
|
12373
|
+
});
|
|
12374
|
+
setTimeout(() => {
|
|
12375
|
+
this.isChangingTrack = false;
|
|
12376
|
+
}, 150);
|
|
12377
|
+
return;
|
|
12378
|
+
}
|
|
12379
|
+
}
|
|
11829
12380
|
this.player.load({
|
|
11830
12381
|
src: track.src,
|
|
11831
12382
|
type: track.type,
|
|
@@ -11850,7 +12401,7 @@
|
|
|
11850
12401
|
* @param {number} index - Track index
|
|
11851
12402
|
* @param {boolean} userInitiated - Whether this was triggered by user action (default: false)
|
|
11852
12403
|
*/
|
|
11853
|
-
play(index, userInitiated = false) {
|
|
12404
|
+
async play(index, userInitiated = false) {
|
|
11854
12405
|
if (index < 0 || index >= this.tracks.length) {
|
|
11855
12406
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
11856
12407
|
return;
|
|
@@ -11858,6 +12409,25 @@
|
|
|
11858
12409
|
const track = this.tracks[index];
|
|
11859
12410
|
this.isChangingTrack = true;
|
|
11860
12411
|
this.currentIndex = index;
|
|
12412
|
+
if (this.options.recreatePlayers && this.hostElement && this.PlayerClass) {
|
|
12413
|
+
const currentMediaType = this.player ? this.player.element.tagName === "AUDIO" ? "audio" : "video" : null;
|
|
12414
|
+
const newMediaType = this.getTrackMediaType(track);
|
|
12415
|
+
const newElementType = newMediaType === "audio" || newMediaType === "soundcloud" ? "audio" : "video";
|
|
12416
|
+
if (currentMediaType !== newElementType) {
|
|
12417
|
+
await this.recreatePlayerForTrack(track, true);
|
|
12418
|
+
this.updateTrackInfo(track);
|
|
12419
|
+
this.updatePlaylistUI();
|
|
12420
|
+
this.player.emit("playlisttrackchange", {
|
|
12421
|
+
index,
|
|
12422
|
+
item: track,
|
|
12423
|
+
total: this.tracks.length
|
|
12424
|
+
});
|
|
12425
|
+
setTimeout(() => {
|
|
12426
|
+
this.isChangingTrack = false;
|
|
12427
|
+
}, 150);
|
|
12428
|
+
return;
|
|
12429
|
+
}
|
|
12430
|
+
}
|
|
11861
12431
|
this.player.load({
|
|
11862
12432
|
src: track.src,
|
|
11863
12433
|
type: track.type,
|
|
@@ -11919,10 +12489,26 @@
|
|
|
11919
12489
|
this.next();
|
|
11920
12490
|
}
|
|
11921
12491
|
}
|
|
12492
|
+
/**
|
|
12493
|
+
* Check if a source URL requires an external renderer
|
|
12494
|
+
* @param {string} src - Source URL
|
|
12495
|
+
* @returns {boolean}
|
|
12496
|
+
*/
|
|
12497
|
+
isExternalRendererUrl(src) {
|
|
12498
|
+
if (!src) return false;
|
|
12499
|
+
return src.includes("youtube.com") || src.includes("youtu.be") || src.includes("vimeo.com") || src.includes("soundcloud.com") || src.includes("api.soundcloud.com") || src.includes(".m3u8");
|
|
12500
|
+
}
|
|
11922
12501
|
/**
|
|
11923
12502
|
* Handle track error
|
|
11924
12503
|
*/
|
|
11925
12504
|
handleTrackError(e) {
|
|
12505
|
+
const currentTrack = this.getCurrentTrack();
|
|
12506
|
+
if (currentTrack && currentTrack.src && this.isExternalRendererUrl(currentTrack.src)) {
|
|
12507
|
+
return;
|
|
12508
|
+
}
|
|
12509
|
+
if (this.isChangingTrack) {
|
|
12510
|
+
return;
|
|
12511
|
+
}
|
|
11926
12512
|
console.error("VidPly Playlist: Track error", e);
|
|
11927
12513
|
if (this.options.autoAdvance) {
|
|
11928
12514
|
setTimeout(() => {
|