vidply 1.0.25 → 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/README.md +5 -0
- package/dist/dev/{vidply.HLSRenderer-PNP5OPES.js → vidply.HLSRenderer-ENLZE4QS.js} +19 -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 +292 -13
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/legacy/vidply.js +619 -24
- 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 +52 -1
- package/dist/vidply.esm.min.meta.json +56 -28
- package/dist/vidply.min.css +2 -2
- package/package.json +1 -1
- package/src/core/Player.js +124 -10
- 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-PNP5OPES.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-4PW35TCX.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);
|
|
@@ -5085,6 +5114,12 @@
|
|
|
5085
5114
|
}
|
|
5086
5115
|
return [];
|
|
5087
5116
|
}
|
|
5117
|
+
getCurrentQuality() {
|
|
5118
|
+
if (this.hls) {
|
|
5119
|
+
return this.hls.currentLevel;
|
|
5120
|
+
}
|
|
5121
|
+
return -1;
|
|
5122
|
+
}
|
|
5088
5123
|
destroy() {
|
|
5089
5124
|
if (this.hls) {
|
|
5090
5125
|
this.hls.destroy();
|
|
@@ -5095,6 +5130,287 @@
|
|
|
5095
5130
|
}
|
|
5096
5131
|
});
|
|
5097
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
|
+
|
|
5098
5414
|
// src/utils/EventEmitter.js
|
|
5099
5415
|
var EventEmitter = class {
|
|
5100
5416
|
constructor() {
|
|
@@ -8174,6 +8490,7 @@
|
|
|
8174
8490
|
this.element.appendChild(mediaElement);
|
|
8175
8491
|
this.element = mediaElement;
|
|
8176
8492
|
}
|
|
8493
|
+
this._originalElement = this.element;
|
|
8177
8494
|
this.options = __spreadValues({
|
|
8178
8495
|
// Display
|
|
8179
8496
|
width: null,
|
|
@@ -8447,7 +8764,7 @@
|
|
|
8447
8764
|
}
|
|
8448
8765
|
/**
|
|
8449
8766
|
* Detect language from HTML lang attribute
|
|
8450
|
-
* @returns {string|null} Language code if available in translations, null otherwise
|
|
8767
|
+
* @returns {string|null} Language code if available in translations or as built-in, null otherwise
|
|
8451
8768
|
*/
|
|
8452
8769
|
detectHtmlLanguage() {
|
|
8453
8770
|
const htmlLang = document.documentElement.lang || document.documentElement.getAttribute("lang");
|
|
@@ -8458,6 +8775,9 @@
|
|
|
8458
8775
|
if (i18n.translations[normalizedLang]) {
|
|
8459
8776
|
return normalizedLang;
|
|
8460
8777
|
}
|
|
8778
|
+
if (i18n.builtInLanguageLoaders && i18n.builtInLanguageLoaders[normalizedLang]) {
|
|
8779
|
+
return normalizedLang;
|
|
8780
|
+
}
|
|
8461
8781
|
this.log('Language "'.concat(htmlLang, '" not available, using English as fallback'));
|
|
8462
8782
|
return null;
|
|
8463
8783
|
}
|
|
@@ -8585,10 +8905,12 @@
|
|
|
8585
8905
|
}
|
|
8586
8906
|
async initializeRenderer() {
|
|
8587
8907
|
var _a;
|
|
8588
|
-
|
|
8908
|
+
let src = this._pendingSource || this.element.src || ((_a = this.element.querySelector("source")) == null ? void 0 : _a.src);
|
|
8589
8909
|
if (!src) {
|
|
8590
8910
|
throw new Error("No media source found");
|
|
8591
8911
|
}
|
|
8912
|
+
this.currentSource = src;
|
|
8913
|
+
this._pendingSource = null;
|
|
8592
8914
|
const sourceElements = this.sourceElements;
|
|
8593
8915
|
for (const sourceEl of sourceElements) {
|
|
8594
8916
|
const descSrc = sourceEl.getAttribute("data-desc-src");
|
|
@@ -8649,6 +8971,9 @@
|
|
|
8649
8971
|
} else if (src.includes(".m3u8")) {
|
|
8650
8972
|
const module = await Promise.resolve().then(() => (init_HLSRenderer(), HLSRenderer_exports));
|
|
8651
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;
|
|
8652
8977
|
}
|
|
8653
8978
|
this.log("Using ".concat((rendererClass == null ? void 0 : rendererClass.name) || "HTML5Renderer", " renderer"));
|
|
8654
8979
|
this.renderer = new rendererClass(this);
|
|
@@ -8760,6 +9085,11 @@
|
|
|
8760
9085
|
const resolvedPoster = this.resolvePosterPath(poster);
|
|
8761
9086
|
this.videoWrapper.style.setProperty("--vidply-poster-image", 'url("'.concat(resolvedPoster, '")'));
|
|
8762
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
|
+
}
|
|
8763
9093
|
}
|
|
8764
9094
|
hidePosterOverlay() {
|
|
8765
9095
|
if (!this.videoWrapper) {
|
|
@@ -8802,6 +9132,15 @@
|
|
|
8802
9132
|
* @param {string} [config.audioDescriptionSrc] - Audio description video URL
|
|
8803
9133
|
* @param {string} [config.signLanguageSrc] - Sign language video URL
|
|
8804
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
|
+
}
|
|
8805
9144
|
async load(config) {
|
|
8806
9145
|
var _a;
|
|
8807
9146
|
try {
|
|
@@ -8814,12 +9153,44 @@
|
|
|
8814
9153
|
const existingTracks = this.trackElements;
|
|
8815
9154
|
existingTracks.forEach((track) => track.remove());
|
|
8816
9155
|
this.invalidateTrackCache();
|
|
8817
|
-
|
|
8818
|
-
if (
|
|
8819
|
-
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
|
+
}
|
|
8820
9178
|
}
|
|
8821
9179
|
if (config.poster && this.element.tagName === "VIDEO") {
|
|
8822
|
-
|
|
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
|
+
}
|
|
8823
9194
|
}
|
|
8824
9195
|
if (config.tracks && config.tracks.length > 0) {
|
|
8825
9196
|
config.tracks.forEach((trackConfig) => {
|
|
@@ -8862,6 +9233,13 @@
|
|
|
8862
9233
|
this.renderer.media = this.element;
|
|
8863
9234
|
this.element.load();
|
|
8864
9235
|
}
|
|
9236
|
+
if (isExternalRenderer) {
|
|
9237
|
+
setTimeout(() => {
|
|
9238
|
+
this._switchingRenderer = false;
|
|
9239
|
+
}, 500);
|
|
9240
|
+
} else {
|
|
9241
|
+
this._switchingRenderer = false;
|
|
9242
|
+
}
|
|
8865
9243
|
window.scrollTo(scrollX, scrollY);
|
|
8866
9244
|
if (this.captionManager) {
|
|
8867
9245
|
this.captionManager.destroy();
|
|
@@ -8920,11 +9298,13 @@
|
|
|
8920
9298
|
const isYouTube = src.includes("youtube.com") || src.includes("youtu.be");
|
|
8921
9299
|
const isVimeo = src.includes("vimeo.com");
|
|
8922
9300
|
const isHLS = src.includes(".m3u8");
|
|
9301
|
+
const isSoundCloud = src.includes("soundcloud.com") || src.includes("api.soundcloud.com");
|
|
8923
9302
|
const currentRendererName = this.renderer.constructor.name;
|
|
8924
9303
|
if (isYouTube && currentRendererName !== "YouTubeRenderer") return true;
|
|
8925
9304
|
if (isVimeo && currentRendererName !== "VimeoRenderer") return true;
|
|
8926
9305
|
if (isHLS && currentRendererName !== "HLSRenderer") return true;
|
|
8927
|
-
if (
|
|
9306
|
+
if (isSoundCloud && currentRendererName !== "SoundCloudRenderer") return true;
|
|
9307
|
+
if (!isYouTube && !isVimeo && !isHLS && !isSoundCloud && currentRendererName !== "HTML5Renderer") return true;
|
|
8928
9308
|
return false;
|
|
8929
9309
|
}
|
|
8930
9310
|
// Playback controls
|
|
@@ -11139,6 +11519,10 @@
|
|
|
11139
11519
|
}
|
|
11140
11520
|
// Error handling
|
|
11141
11521
|
handleError(error) {
|
|
11522
|
+
if (this._switchingRenderer) {
|
|
11523
|
+
this.log("Suppressing error during renderer switch:", error, "debug");
|
|
11524
|
+
return;
|
|
11525
|
+
}
|
|
11142
11526
|
this.log("Error:", error, "error");
|
|
11143
11527
|
this.emit("error", error);
|
|
11144
11528
|
if (this.options.onError) {
|
|
@@ -11682,7 +12066,9 @@
|
|
|
11682
12066
|
autoPlayFirst: options.autoPlayFirst !== false,
|
|
11683
12067
|
// Default true - auto-play first track on load
|
|
11684
12068
|
loop: options.loop || false,
|
|
11685
|
-
showPanel: options.showPanel !== false
|
|
12069
|
+
showPanel: options.showPanel !== false,
|
|
12070
|
+
// Default true
|
|
12071
|
+
recreatePlayers: options.recreatePlayers || false
|
|
11686
12072
|
}, options);
|
|
11687
12073
|
this.container = null;
|
|
11688
12074
|
this.playlistPanel = null;
|
|
@@ -11690,6 +12076,8 @@
|
|
|
11690
12076
|
this.navigationFeedback = null;
|
|
11691
12077
|
this.isPanelVisible = this.options.showPanel !== false;
|
|
11692
12078
|
this.isChangingTrack = false;
|
|
12079
|
+
this.hostElement = options.hostElement || null;
|
|
12080
|
+
this.PlayerClass = options.PlayerClass || null;
|
|
11693
12081
|
this.handleTrackEnd = this.handleTrackEnd.bind(this);
|
|
11694
12082
|
this.handleTrackError = this.handleTrackError.bind(this);
|
|
11695
12083
|
this.player.playlistManager = this;
|
|
@@ -11699,6 +12087,159 @@
|
|
|
11699
12087
|
this.loadPlaylist(this.initialTracks);
|
|
11700
12088
|
}
|
|
11701
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
|
+
}
|
|
11702
12243
|
init() {
|
|
11703
12244
|
this.player.on("ended", this.handleTrackEnd);
|
|
11704
12245
|
this.player.on("error", this.handleTrackError);
|
|
@@ -11809,7 +12350,7 @@
|
|
|
11809
12350
|
* Load a track without playing
|
|
11810
12351
|
* @param {number} index - Track index
|
|
11811
12352
|
*/
|
|
11812
|
-
loadTrack(index) {
|
|
12353
|
+
async loadTrack(index) {
|
|
11813
12354
|
if (index < 0 || index >= this.tracks.length) {
|
|
11814
12355
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
11815
12356
|
return;
|
|
@@ -11817,6 +12358,25 @@
|
|
|
11817
12358
|
const track = this.tracks[index];
|
|
11818
12359
|
this.isChangingTrack = true;
|
|
11819
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
|
+
}
|
|
11820
12380
|
this.player.load({
|
|
11821
12381
|
src: track.src,
|
|
11822
12382
|
type: track.type,
|
|
@@ -11841,7 +12401,7 @@
|
|
|
11841
12401
|
* @param {number} index - Track index
|
|
11842
12402
|
* @param {boolean} userInitiated - Whether this was triggered by user action (default: false)
|
|
11843
12403
|
*/
|
|
11844
|
-
play(index, userInitiated = false) {
|
|
12404
|
+
async play(index, userInitiated = false) {
|
|
11845
12405
|
if (index < 0 || index >= this.tracks.length) {
|
|
11846
12406
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
11847
12407
|
return;
|
|
@@ -11849,6 +12409,25 @@
|
|
|
11849
12409
|
const track = this.tracks[index];
|
|
11850
12410
|
this.isChangingTrack = true;
|
|
11851
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
|
+
}
|
|
11852
12431
|
this.player.load({
|
|
11853
12432
|
src: track.src,
|
|
11854
12433
|
type: track.type,
|
|
@@ -11910,10 +12489,26 @@
|
|
|
11910
12489
|
this.next();
|
|
11911
12490
|
}
|
|
11912
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
|
+
}
|
|
11913
12501
|
/**
|
|
11914
12502
|
* Handle track error
|
|
11915
12503
|
*/
|
|
11916
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
|
+
}
|
|
11917
12512
|
console.error("VidPly Playlist: Track error", e);
|
|
11918
12513
|
if (this.options.autoAdvance) {
|
|
11919
12514
|
setTimeout(() => {
|