vidply 1.0.31 → 1.0.33
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 +708 -708
- package/dist/dev/{vidply.HLSRenderer-ENLZE4QS.js → vidply.HLSRenderer-LIFBU6UD.js} +61 -10
- package/dist/dev/vidply.HLSRenderer-LIFBU6UD.js.map +7 -0
- package/dist/dev/{vidply.HTML5Renderer-6SBDI6S2.js → vidply.HTML5Renderer-YWMVYWFS.js} +2 -2
- package/dist/dev/{vidply.TranscriptManager-T677KF4N.js → vidply.TranscriptManager-R7NJRU7E.js} +2 -2
- package/dist/dev/{vidply.chunk-GS2JX5RQ.js → vidply.chunk-PMRKJBGH.js} +5 -2
- package/dist/dev/vidply.chunk-PMRKJBGH.js.map +7 -0
- package/dist/dev/{vidply.chunk-W2LSBD6Y.js → vidply.chunk-UVO24MXU.js} +33 -3
- package/dist/dev/vidply.chunk-UVO24MXU.js.map +7 -0
- package/dist/dev/{vidply.de-SNL6AJ4D.js → vidply.de-CEGBLV67.js} +4 -1
- package/dist/dev/vidply.de-CEGBLV67.js.map +7 -0
- package/dist/dev/vidply.esm.js +374 -64
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/legacy/vidply.js +483 -71
- package/dist/legacy/vidply.js.map +3 -3
- package/dist/legacy/vidply.min.js +1 -1
- package/dist/legacy/vidply.min.meta.json +15 -15
- package/dist/prod/vidply.HLSRenderer-ESR6NAMI.min.js +6 -0
- package/dist/prod/{vidply.HTML5Renderer-KKW3OLHM.min.js → vidply.HTML5Renderer-6ROXQSQY.min.js} +1 -1
- package/dist/prod/{vidply.TranscriptManager-WFZSW6NR.min.js → vidply.TranscriptManager-B65LKXGG.min.js} +1 -1
- package/dist/prod/vidply.chunk-7HVHEUHH.min.js +6 -0
- package/dist/prod/vidply.chunk-IQKD4GUB.min.js +6 -0
- package/dist/prod/vidply.de-IHKC573T.min.js +6 -0
- package/dist/prod/vidply.esm.min.js +9 -9
- package/dist/vidply.esm.min.meta.json +33 -33
- package/package.json +1 -1
- package/src/controls/ControlBar.js +120 -71
- package/src/core/Player.js +5087 -4868
- package/src/features/PlaylistManager.js +1669 -1511
- package/src/i18n/languages/de.js +3 -0
- package/src/i18n/languages/en.js +3 -0
- package/src/renderers/HLSRenderer.js +77 -8
- package/src/renderers/HTML5Renderer.js +43 -5
- package/dist/dev/vidply.HLSRenderer-ENLZE4QS.js.map +0 -7
- package/dist/dev/vidply.HLSRenderer-UMPUDSYL.js +0 -266
- package/dist/dev/vidply.HLSRenderer-UMPUDSYL.js.map +0 -7
- package/dist/dev/vidply.HTML5Renderer-FXBZQL6Y.js +0 -12
- package/dist/dev/vidply.HTML5Renderer-FXBZQL6Y.js.map +0 -7
- package/dist/dev/vidply.chunk-BCOFCT6U.js +0 -246
- package/dist/dev/vidply.chunk-BCOFCT6U.js.map +0 -7
- package/dist/dev/vidply.chunk-GS2JX5RQ.js.map +0 -7
- package/dist/dev/vidply.chunk-W2LSBD6Y.js.map +0 -7
- package/dist/dev/vidply.de-SNL6AJ4D.js.map +0 -7
- package/dist/prod/vidply.HLSRenderer-3CG7BZKA.min.js +0 -6
- package/dist/prod/vidply.HLSRenderer-CBXZ4RF2.min.js +0 -6
- package/dist/prod/vidply.HTML5Renderer-MY7XDV7R.min.js +0 -6
- package/dist/prod/vidply.chunk-34RH2THY.min.js +0 -6
- package/dist/prod/vidply.chunk-LGTJRPUL.min.js +0 -6
- package/dist/prod/vidply.chunk-OXXPY2XB.min.js +0 -6
- package/dist/prod/vidply.de-FR3XX54P.min.js +0 -6
- /package/dist/dev/{vidply.HTML5Renderer-6SBDI6S2.js.map → vidply.HTML5Renderer-YWMVYWFS.js.map} +0 -0
- /package/dist/dev/{vidply.TranscriptManager-T677KF4N.js.map → vidply.TranscriptManager-R7NJRU7E.js.map} +0 -0
package/dist/legacy/vidply.js
CHANGED
|
@@ -296,6 +296,9 @@
|
|
|
296
296
|
signLanguageVideo: "Sign Language Video",
|
|
297
297
|
closeSignLanguage: "Close sign language video",
|
|
298
298
|
signLanguageSettings: "Sign language settings",
|
|
299
|
+
startPlaybackFirst: "Please start playback first.",
|
|
300
|
+
startPlaybackForAudioDescription: "Please start playback first to use audio description.",
|
|
301
|
+
startPlaybackForSignLanguage: "Please start playback first to use sign language video.",
|
|
299
302
|
noChapters: "No chapters available",
|
|
300
303
|
noCaptions: "No captions available",
|
|
301
304
|
auto: "Auto",
|
|
@@ -484,6 +487,9 @@
|
|
|
484
487
|
signLanguageVideo: "Gebärdensprache-Video",
|
|
485
488
|
closeSignLanguage: "Gebärdensprache-Video schließen",
|
|
486
489
|
signLanguageSettings: "Gebärdensprache-Einstellungen",
|
|
490
|
+
startPlaybackFirst: "Bitte starten Sie die Wiedergabe zuerst.",
|
|
491
|
+
startPlaybackForAudioDescription: "Bitte starten Sie die Wiedergabe zuerst, um die Audiodeskription zu nutzen.",
|
|
492
|
+
startPlaybackForSignLanguage: "Bitte starten Sie die Wiedergabe zuerst, um das Gebärdensprache-Video zu nutzen.",
|
|
487
493
|
noChapters: "Keine Kapitel verfügbar",
|
|
488
494
|
noCaptions: "Keine Untertitel verfügbar",
|
|
489
495
|
auto: "Automatisch",
|
|
@@ -1726,13 +1732,18 @@
|
|
|
1726
1732
|
constructor(player) {
|
|
1727
1733
|
this.player = player;
|
|
1728
1734
|
this.media = player.element;
|
|
1735
|
+
this._didDeferredLoad = false;
|
|
1729
1736
|
}
|
|
1730
1737
|
async init() {
|
|
1731
1738
|
this.media.controls = false;
|
|
1732
1739
|
this.media.removeAttribute("controls");
|
|
1733
1740
|
this.attachEvents();
|
|
1734
|
-
|
|
1735
|
-
|
|
1741
|
+
if (this.player.options.deferLoad) {
|
|
1742
|
+
this.media.preload = this.player.options.preload || "none";
|
|
1743
|
+
} else {
|
|
1744
|
+
this.media.preload = this.player.options.preload;
|
|
1745
|
+
this.media.load();
|
|
1746
|
+
}
|
|
1736
1747
|
if (this.player.container) {
|
|
1737
1748
|
this.player.container.classList.remove("vidply-external-controls");
|
|
1738
1749
|
}
|
|
@@ -1839,6 +1850,15 @@
|
|
|
1839
1850
|
play() {
|
|
1840
1851
|
const scrollX = window.scrollX;
|
|
1841
1852
|
const scrollY = window.scrollY;
|
|
1853
|
+
if (this.player.options.deferLoad && !this._didDeferredLoad) {
|
|
1854
|
+
try {
|
|
1855
|
+
if (this.media.readyState === 0) {
|
|
1856
|
+
this.media.load();
|
|
1857
|
+
}
|
|
1858
|
+
} catch (e) {
|
|
1859
|
+
}
|
|
1860
|
+
this._didDeferredLoad = true;
|
|
1861
|
+
}
|
|
1842
1862
|
const promise = this.media.play();
|
|
1843
1863
|
window.scrollTo(scrollX, scrollY);
|
|
1844
1864
|
if (promise !== void 0) {
|
|
@@ -1858,6 +1878,22 @@
|
|
|
1858
1878
|
});
|
|
1859
1879
|
}
|
|
1860
1880
|
}
|
|
1881
|
+
/**
|
|
1882
|
+
* Ensure the media element has been loaded at least once (metadata/initial state)
|
|
1883
|
+
* without starting playback. Useful for playlists to behave like single videos.
|
|
1884
|
+
*/
|
|
1885
|
+
ensureLoaded() {
|
|
1886
|
+
if (!this.player.options.deferLoad || this._didDeferredLoad) {
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
try {
|
|
1890
|
+
if (this.media.readyState === 0) {
|
|
1891
|
+
this.media.load();
|
|
1892
|
+
}
|
|
1893
|
+
} catch (e) {
|
|
1894
|
+
}
|
|
1895
|
+
this._didDeferredLoad = true;
|
|
1896
|
+
}
|
|
1861
1897
|
pause() {
|
|
1862
1898
|
this.media.pause();
|
|
1863
1899
|
}
|
|
@@ -4967,6 +5003,8 @@
|
|
|
4967
5003
|
this.player = player;
|
|
4968
5004
|
this.media = player.element;
|
|
4969
5005
|
this.hls = null;
|
|
5006
|
+
this._hlsSourceLoaded = false;
|
|
5007
|
+
this._pendingSrc = null;
|
|
4970
5008
|
}
|
|
4971
5009
|
async init() {
|
|
4972
5010
|
if (this.canPlayNatively()) {
|
|
@@ -5007,6 +5045,8 @@
|
|
|
5007
5045
|
}
|
|
5008
5046
|
this.hls = new window.Hls({
|
|
5009
5047
|
debug: this.player.options.debug,
|
|
5048
|
+
// When deferLoad is enabled, do not start loading until the first play().
|
|
5049
|
+
autoStartLoad: !this.player.options.deferLoad,
|
|
5010
5050
|
enableWorker: true,
|
|
5011
5051
|
lowLatencyMode: false,
|
|
5012
5052
|
backBufferLength: 90,
|
|
@@ -5042,7 +5082,12 @@
|
|
|
5042
5082
|
if (!src) {
|
|
5043
5083
|
throw new Error("No HLS source found");
|
|
5044
5084
|
}
|
|
5045
|
-
this.
|
|
5085
|
+
if (this.player.options.deferLoad) {
|
|
5086
|
+
this._pendingSrc = src;
|
|
5087
|
+
} else {
|
|
5088
|
+
this.hls.loadSource(src);
|
|
5089
|
+
this._hlsSourceLoaded = true;
|
|
5090
|
+
}
|
|
5046
5091
|
this.attachHlsEvents();
|
|
5047
5092
|
this.attachMediaEvents();
|
|
5048
5093
|
}
|
|
@@ -5161,9 +5206,45 @@
|
|
|
5161
5206
|
this.player.log("Non-fatal HLS error: " + data.details, "warn");
|
|
5162
5207
|
}
|
|
5163
5208
|
}
|
|
5209
|
+
/**
|
|
5210
|
+
* Ensure the HLS manifest/initial loading is started without starting playback.
|
|
5211
|
+
* This makes playlist selection behave more like single-video initialization.
|
|
5212
|
+
*/
|
|
5213
|
+
ensureLoaded() {
|
|
5214
|
+
if (!this.player.options.deferLoad) {
|
|
5215
|
+
return;
|
|
5216
|
+
}
|
|
5217
|
+
if (!this.hls) {
|
|
5218
|
+
return;
|
|
5219
|
+
}
|
|
5220
|
+
if (this._hlsSourceLoaded) {
|
|
5221
|
+
return;
|
|
5222
|
+
}
|
|
5223
|
+
const src = this._pendingSrc || this.player._pendingSource || this.player.currentSource;
|
|
5224
|
+
if (!src) {
|
|
5225
|
+
return;
|
|
5226
|
+
}
|
|
5227
|
+
try {
|
|
5228
|
+
this.hls.loadSource(src);
|
|
5229
|
+
this._hlsSourceLoaded = true;
|
|
5230
|
+
this.hls.startLoad();
|
|
5231
|
+
} catch (e) {
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
5164
5234
|
play() {
|
|
5165
5235
|
const scrollX = window.scrollX;
|
|
5166
5236
|
const scrollY = window.scrollY;
|
|
5237
|
+
if (this.player.options.deferLoad && this.hls && !this._hlsSourceLoaded) {
|
|
5238
|
+
const src = this._pendingSrc || this.player.currentSource;
|
|
5239
|
+
if (src) {
|
|
5240
|
+
try {
|
|
5241
|
+
this.hls.loadSource(src);
|
|
5242
|
+
this.hls.startLoad();
|
|
5243
|
+
this._hlsSourceLoaded = true;
|
|
5244
|
+
} catch (e) {
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5167
5248
|
const promise = this.media.play();
|
|
5168
5249
|
window.scrollTo(scrollX, scrollY);
|
|
5169
5250
|
if (promise !== void 0) {
|
|
@@ -5194,13 +5275,19 @@
|
|
|
5194
5275
|
}
|
|
5195
5276
|
getQualities() {
|
|
5196
5277
|
if (this.hls && this.hls.levels) {
|
|
5197
|
-
return this.hls.levels.map((level, index) =>
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5278
|
+
return this.hls.levels.map((level, index) => {
|
|
5279
|
+
const height = Number(level.height) || 0;
|
|
5280
|
+
const bitrate = Number(level.bitrate) || 0;
|
|
5281
|
+
const kb = bitrate > 0 ? Math.round(bitrate / 1e3) : 0;
|
|
5282
|
+
const name = height > 0 ? "".concat(height, "p") : kb > 0 ? "".concat(kb, " kb") : "Auto";
|
|
5283
|
+
return {
|
|
5284
|
+
index,
|
|
5285
|
+
height: level.height,
|
|
5286
|
+
width: level.width,
|
|
5287
|
+
bitrate: level.bitrate,
|
|
5288
|
+
name
|
|
5289
|
+
};
|
|
5290
|
+
});
|
|
5204
5291
|
}
|
|
5205
5292
|
return [];
|
|
5206
5293
|
}
|
|
@@ -5677,6 +5764,8 @@
|
|
|
5677
5764
|
init() {
|
|
5678
5765
|
this.createElement();
|
|
5679
5766
|
this.createControls();
|
|
5767
|
+
this.updateDuration();
|
|
5768
|
+
this.updateProgress();
|
|
5680
5769
|
this.attachEvents();
|
|
5681
5770
|
this.setupAutoHide();
|
|
5682
5771
|
this.setupOverflowDetection();
|
|
@@ -6091,6 +6180,7 @@
|
|
|
6091
6180
|
});
|
|
6092
6181
|
}
|
|
6093
6182
|
createControls() {
|
|
6183
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
6094
6184
|
const progressTimeWrapper = DOMUtils.createElement("div", {
|
|
6095
6185
|
className: "".concat(this.player.options.classPrefix, "-progress-time-wrapper")
|
|
6096
6186
|
});
|
|
@@ -6156,7 +6246,11 @@
|
|
|
6156
6246
|
btn.dataset.overflowPriorityMobile = "3";
|
|
6157
6247
|
this.rightButtons.appendChild(btn);
|
|
6158
6248
|
}
|
|
6159
|
-
|
|
6249
|
+
const src = this.player.currentSource || ((_b = (_a = this.player.element) == null ? void 0 : _a.getAttribute) == null ? void 0 : _b.call(_a, "src")) || ((_c = this.player.element) == null ? void 0 : _c.currentSrc) || ((_d = this.player.element) == null ? void 0 : _d.src) || ((_h = (_g = (_f = (_e = this.player.element) == null ? void 0 : _e.querySelector) == null ? void 0 : _f.call(_e, "source")) == null ? void 0 : _g.getAttribute) == null ? void 0 : _h.call(_g, "src")) || ((_k = (_j = (_i = this.player.element) == null ? void 0 : _i.querySelector) == null ? void 0 : _j.call(_i, "source")) == null ? void 0 : _k.src) || "";
|
|
6250
|
+
const isHlsSource = typeof src === "string" && src.includes(".m3u8");
|
|
6251
|
+
const isVideoElement = ((_m = (_l = this.player.element) == null ? void 0 : _l.tagName) == null ? void 0 : _m.toLowerCase()) === "video";
|
|
6252
|
+
const hideSpeedForThisPlayer = !!this.player.options.hideSpeedForHls && isHlsSource || !!this.player.options.hideSpeedForHlsVideo && isHlsSource && isVideoElement;
|
|
6253
|
+
if (this.player.options.speedButton && !hideSpeedForThisPlayer) {
|
|
6160
6254
|
const btn = this.createSpeedButton();
|
|
6161
6255
|
btn.dataset.overflowPriority = "1";
|
|
6162
6256
|
btn.dataset.overflowPriorityMobile = "3";
|
|
@@ -6238,20 +6332,32 @@
|
|
|
6238
6332
|
}
|
|
6239
6333
|
// Helper methods to check for available features
|
|
6240
6334
|
hasChapterTracks() {
|
|
6335
|
+
var _a, _b;
|
|
6241
6336
|
const textTracks = this.player.element.textTracks;
|
|
6242
6337
|
for (let i = 0; i < textTracks.length; i++) {
|
|
6243
|
-
if (textTracks[i].kind === "chapters")
|
|
6244
|
-
|
|
6245
|
-
|
|
6338
|
+
if (textTracks[i].kind === "chapters") return true;
|
|
6339
|
+
}
|
|
6340
|
+
const trackEls = Array.from(this.player.element.querySelectorAll('track[kind="chapters"]'));
|
|
6341
|
+
if (trackEls.length > 0) return true;
|
|
6342
|
+
const current = (_b = (_a = this.player.playlistManager) == null ? void 0 : _a.getCurrentTrack) == null ? void 0 : _b.call(_a);
|
|
6343
|
+
if ((current == null ? void 0 : current.tracks) && Array.isArray(current.tracks)) {
|
|
6344
|
+
return current.tracks.some((t) => (t == null ? void 0 : t.kind) === "chapters");
|
|
6246
6345
|
}
|
|
6247
6346
|
return false;
|
|
6248
6347
|
}
|
|
6249
6348
|
hasCaptionTracks() {
|
|
6349
|
+
var _a, _b;
|
|
6250
6350
|
const textTracks = this.player.element.textTracks;
|
|
6251
6351
|
for (let i = 0; i < textTracks.length; i++) {
|
|
6252
|
-
if (textTracks[i].kind === "captions" || textTracks[i].kind === "subtitles")
|
|
6253
|
-
|
|
6254
|
-
|
|
6352
|
+
if (textTracks[i].kind === "captions" || textTracks[i].kind === "subtitles") return true;
|
|
6353
|
+
}
|
|
6354
|
+
const trackEls = Array.from(this.player.element.querySelectorAll("track"));
|
|
6355
|
+
if (trackEls.some((el) => el.getAttribute("kind") === "captions" || el.getAttribute("kind") === "subtitles")) {
|
|
6356
|
+
return true;
|
|
6357
|
+
}
|
|
6358
|
+
const current = (_b = (_a = this.player.playlistManager) == null ? void 0 : _a.getCurrentTrack) == null ? void 0 : _b.call(_a);
|
|
6359
|
+
if ((current == null ? void 0 : current.tracks) && Array.isArray(current.tracks)) {
|
|
6360
|
+
return current.tracks.some((t) => (t == null ? void 0 : t.kind) === "captions" || (t == null ? void 0 : t.kind) === "subtitles");
|
|
6255
6361
|
}
|
|
6256
6362
|
return false;
|
|
6257
6363
|
}
|
|
@@ -6326,55 +6432,65 @@
|
|
|
6326
6432
|
this.currentPreviewTime = null;
|
|
6327
6433
|
this.previewThumbnailTimeout = null;
|
|
6328
6434
|
this.previewSupported = false;
|
|
6435
|
+
this.previewVideoReady = false;
|
|
6436
|
+
this.previewVideoInitialized = false;
|
|
6329
6437
|
const isVideo = this.player.element && this.player.element.tagName === "VIDEO";
|
|
6330
6438
|
if (!isVideo) {
|
|
6331
6439
|
return;
|
|
6332
6440
|
}
|
|
6441
|
+
}
|
|
6442
|
+
/**
|
|
6443
|
+
* Lazily create the hidden preview video (only after playback started once)
|
|
6444
|
+
*/
|
|
6445
|
+
ensurePreviewVideoInitialized() {
|
|
6446
|
+
var _a, _b;
|
|
6447
|
+
if (this.previewVideoInitialized) return;
|
|
6448
|
+
if (!((_b = (_a = this.player) == null ? void 0 : _a.state) == null ? void 0 : _b.hasStartedPlayback)) return;
|
|
6333
6449
|
const renderer = this.player.renderer;
|
|
6334
6450
|
const hasVideoMedia = renderer && renderer.media && renderer.media.tagName === "VIDEO";
|
|
6335
6451
|
const isHTML5Renderer = hasVideoMedia && renderer.media === this.player.element && !renderer.hls && typeof renderer.seek === "function";
|
|
6336
6452
|
this.previewSupported = isHTML5Renderer && hasVideoMedia;
|
|
6337
|
-
if (this.previewSupported)
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
this.previewVideo.style.top = "-9999px";
|
|
6347
|
-
const mainVideo = renderer.media || this.player.element;
|
|
6348
|
-
let videoSrc = null;
|
|
6349
|
-
if (mainVideo.src) {
|
|
6350
|
-
videoSrc = mainVideo.src;
|
|
6351
|
-
} else {
|
|
6352
|
-
const source = mainVideo.querySelector("source");
|
|
6353
|
-
if (source) {
|
|
6354
|
-
videoSrc = source.src;
|
|
6355
|
-
}
|
|
6356
|
-
}
|
|
6357
|
-
if (!videoSrc) {
|
|
6358
|
-
this.player.log("No video source found for preview", "warn");
|
|
6359
|
-
this.previewSupported = false;
|
|
6360
|
-
return;
|
|
6361
|
-
}
|
|
6362
|
-
if (mainVideo.crossOrigin) {
|
|
6363
|
-
this.previewVideo.crossOrigin = mainVideo.crossOrigin;
|
|
6364
|
-
}
|
|
6365
|
-
this.previewVideo.addEventListener("error", (e) => {
|
|
6366
|
-
this.player.log("Preview video failed to load:", e, "warn");
|
|
6367
|
-
this.previewSupported = false;
|
|
6368
|
-
});
|
|
6369
|
-
this.previewVideo.addEventListener("loadedmetadata", () => {
|
|
6370
|
-
this.previewVideoReady = true;
|
|
6371
|
-
}, { once: true });
|
|
6372
|
-
if (this.player.container) {
|
|
6373
|
-
this.player.container.appendChild(this.previewVideo);
|
|
6453
|
+
if (!this.previewSupported) return;
|
|
6454
|
+
const mainVideo = renderer.media || this.player.element;
|
|
6455
|
+
let videoSrc = null;
|
|
6456
|
+
if (mainVideo.src) {
|
|
6457
|
+
videoSrc = mainVideo.src;
|
|
6458
|
+
} else {
|
|
6459
|
+
const source = mainVideo.querySelector("source");
|
|
6460
|
+
if (source) {
|
|
6461
|
+
videoSrc = source.src;
|
|
6374
6462
|
}
|
|
6375
|
-
this.previewVideo.src = videoSrc;
|
|
6376
|
-
this.previewVideoReady = false;
|
|
6377
6463
|
}
|
|
6464
|
+
if (!videoSrc) {
|
|
6465
|
+
this.player.log("No video source found for preview", "warn");
|
|
6466
|
+
this.previewSupported = false;
|
|
6467
|
+
return;
|
|
6468
|
+
}
|
|
6469
|
+
this.previewVideo = document.createElement("video");
|
|
6470
|
+
this.previewVideo.muted = true;
|
|
6471
|
+
this.previewVideo.preload = "auto";
|
|
6472
|
+
this.previewVideo.playsInline = true;
|
|
6473
|
+
this.previewVideo.style.position = "absolute";
|
|
6474
|
+
this.previewVideo.style.visibility = "hidden";
|
|
6475
|
+
this.previewVideo.style.width = "1px";
|
|
6476
|
+
this.previewVideo.style.height = "1px";
|
|
6477
|
+
this.previewVideo.style.top = "-9999px";
|
|
6478
|
+
if (mainVideo.crossOrigin) {
|
|
6479
|
+
this.previewVideo.crossOrigin = mainVideo.crossOrigin;
|
|
6480
|
+
}
|
|
6481
|
+
this.previewVideo.addEventListener("error", (e) => {
|
|
6482
|
+
this.player.log("Preview video failed to load:", e, "warn");
|
|
6483
|
+
this.previewSupported = false;
|
|
6484
|
+
});
|
|
6485
|
+
this.previewVideo.addEventListener("loadedmetadata", () => {
|
|
6486
|
+
this.previewVideoReady = true;
|
|
6487
|
+
}, { once: true });
|
|
6488
|
+
if (this.player.container) {
|
|
6489
|
+
this.player.container.appendChild(this.previewVideo);
|
|
6490
|
+
}
|
|
6491
|
+
this.previewVideo.src = videoSrc;
|
|
6492
|
+
this.previewVideoReady = false;
|
|
6493
|
+
this.previewVideoInitialized = true;
|
|
6378
6494
|
}
|
|
6379
6495
|
/**
|
|
6380
6496
|
* Generate preview thumbnail for a specific time
|
|
@@ -6500,6 +6616,7 @@
|
|
|
6500
6616
|
this.isDraggingProgress = false;
|
|
6501
6617
|
});
|
|
6502
6618
|
progress.addEventListener("mousemove", (e) => {
|
|
6619
|
+
var _a, _b;
|
|
6503
6620
|
if (!this.isDraggingProgress) {
|
|
6504
6621
|
const { time } = updateProgress(e.clientX);
|
|
6505
6622
|
const rect = progress.getBoundingClientRect();
|
|
@@ -6507,8 +6624,17 @@
|
|
|
6507
6624
|
this.controls.progressTooltipTime.textContent = TimeUtils.formatTime(time);
|
|
6508
6625
|
this.controls.progressTooltip.style.left = "".concat(left, "px");
|
|
6509
6626
|
this.controls.progressTooltip.style.display = "block";
|
|
6627
|
+
if (!((_b = (_a = this.player) == null ? void 0 : _a.state) == null ? void 0 : _b.hasStartedPlayback)) {
|
|
6628
|
+
if (this.controls.progressPreview) {
|
|
6629
|
+
this.controls.progressPreview.style.display = "none";
|
|
6630
|
+
}
|
|
6631
|
+
return;
|
|
6632
|
+
}
|
|
6633
|
+
this.ensurePreviewVideoInitialized();
|
|
6510
6634
|
if (this.previewSupported) {
|
|
6511
6635
|
this.updatePreviewThumbnail(time);
|
|
6636
|
+
} else if (this.controls.progressPreview) {
|
|
6637
|
+
this.controls.progressPreview.style.display = "none";
|
|
6512
6638
|
}
|
|
6513
6639
|
}
|
|
6514
6640
|
});
|
|
@@ -10377,6 +10503,17 @@
|
|
|
10377
10503
|
volume: 0.8,
|
|
10378
10504
|
playbackSpeed: 1,
|
|
10379
10505
|
preload: "metadata",
|
|
10506
|
+
// Optional initial duration (seconds) so UI can show duration
|
|
10507
|
+
// before media metadata is loaded (useful with deferLoad/preload=none).
|
|
10508
|
+
initialDuration: 0,
|
|
10509
|
+
// When enabled, VidPly will not start network loading during init().
|
|
10510
|
+
// - HTML5: does not call element.load() until the first user-initiated play()
|
|
10511
|
+
// - HLS (hls.js): does not load manifest/segments until the first play()
|
|
10512
|
+
// This is useful for pages with many players to avoid high initial bandwidth.
|
|
10513
|
+
deferLoad: false,
|
|
10514
|
+
// When enabled, clicking Audio Description / Sign Language before playback will show
|
|
10515
|
+
// a notice instead of implicitly starting playback/loading.
|
|
10516
|
+
requirePlaybackForAccessibilityToggles: false,
|
|
10380
10517
|
startTime: 0,
|
|
10381
10518
|
playsInline: true,
|
|
10382
10519
|
// Enable inline playback on iOS (prevents native fullscreen)
|
|
@@ -10393,6 +10530,11 @@
|
|
|
10393
10530
|
qualityButton: true,
|
|
10394
10531
|
captionStyleButton: true,
|
|
10395
10532
|
speedButton: true,
|
|
10533
|
+
// When enabled, the playback speed UI is suppressed for ALL HLS streams (audio + video).
|
|
10534
|
+
hideSpeedForHls: false,
|
|
10535
|
+
// When enabled, the playback speed UI is suppressed for HLS *video* streams only.
|
|
10536
|
+
// This is useful for live streams where speed controls don't make sense.
|
|
10537
|
+
hideSpeedForHlsVideo: false,
|
|
10396
10538
|
captionsButton: true,
|
|
10397
10539
|
transcriptButton: true,
|
|
10398
10540
|
fullscreenButton: true,
|
|
@@ -10469,6 +10611,8 @@
|
|
|
10469
10611
|
}, options);
|
|
10470
10612
|
this.options.metadataAlerts = this.options.metadataAlerts || {};
|
|
10471
10613
|
this.options.metadataHashtags = this.options.metadataHashtags || {};
|
|
10614
|
+
this.noticeElement = null;
|
|
10615
|
+
this.noticeTimeout = null;
|
|
10472
10616
|
this.storage = new StorageManager("vidply");
|
|
10473
10617
|
const savedPrefs = this.storage.getPlayerPreferences();
|
|
10474
10618
|
if (savedPrefs) {
|
|
@@ -10483,10 +10627,11 @@
|
|
|
10483
10627
|
ended: false,
|
|
10484
10628
|
buffering: false,
|
|
10485
10629
|
seeking: false,
|
|
10630
|
+
hasStartedPlayback: false,
|
|
10486
10631
|
muted: this.options.muted,
|
|
10487
10632
|
volume: this.options.volume,
|
|
10488
10633
|
currentTime: 0,
|
|
10489
|
-
duration: 0,
|
|
10634
|
+
duration: Number(this.options.initialDuration) > 0 ? Number(this.options.initialDuration) : 0,
|
|
10490
10635
|
playbackSpeed: this.options.playbackSpeed,
|
|
10491
10636
|
fullscreen: false,
|
|
10492
10637
|
pip: false,
|
|
@@ -10575,6 +10720,52 @@
|
|
|
10575
10720
|
});
|
|
10576
10721
|
this.init();
|
|
10577
10722
|
}
|
|
10723
|
+
/**
|
|
10724
|
+
* Show a small in-player notice (non-blocking), also announced to screen readers.
|
|
10725
|
+
*/
|
|
10726
|
+
showNotice(message, { timeout = 2500, priority = "polite" } = {}) {
|
|
10727
|
+
var _a;
|
|
10728
|
+
try {
|
|
10729
|
+
if (!message) return;
|
|
10730
|
+
if (!this.container) return;
|
|
10731
|
+
if ((_a = this.keyboardManager) == null ? void 0 : _a.announce) {
|
|
10732
|
+
this.keyboardManager.announce(message, priority);
|
|
10733
|
+
}
|
|
10734
|
+
if (!this.noticeElement) {
|
|
10735
|
+
const el = document.createElement("div");
|
|
10736
|
+
el.className = "".concat(this.options.classPrefix, "-notice");
|
|
10737
|
+
el.setAttribute("role", "status");
|
|
10738
|
+
el.setAttribute("aria-live", priority);
|
|
10739
|
+
el.setAttribute("aria-atomic", "true");
|
|
10740
|
+
el.style.position = "absolute";
|
|
10741
|
+
el.style.left = "0.75rem";
|
|
10742
|
+
el.style.right = "0.75rem";
|
|
10743
|
+
el.style.top = "0.75rem";
|
|
10744
|
+
el.style.zIndex = "9999";
|
|
10745
|
+
el.style.padding = "0.5rem 0.75rem";
|
|
10746
|
+
el.style.borderRadius = "0.5rem";
|
|
10747
|
+
el.style.background = "rgba(0, 0, 0, 0.75)";
|
|
10748
|
+
el.style.color = "#fff";
|
|
10749
|
+
el.style.fontSize = "0.875rem";
|
|
10750
|
+
el.style.lineHeight = "1.3";
|
|
10751
|
+
el.style.pointerEvents = "none";
|
|
10752
|
+
this.noticeElement = el;
|
|
10753
|
+
this.container.appendChild(el);
|
|
10754
|
+
}
|
|
10755
|
+
this.noticeElement.textContent = message;
|
|
10756
|
+
this.noticeElement.style.display = "block";
|
|
10757
|
+
if (this.noticeTimeout) {
|
|
10758
|
+
clearTimeout(this.noticeTimeout);
|
|
10759
|
+
this.noticeTimeout = null;
|
|
10760
|
+
}
|
|
10761
|
+
this.noticeTimeout = setTimeout(() => {
|
|
10762
|
+
if (this.noticeElement) {
|
|
10763
|
+
this.noticeElement.style.display = "none";
|
|
10764
|
+
}
|
|
10765
|
+
}, timeout);
|
|
10766
|
+
} catch (e) {
|
|
10767
|
+
}
|
|
10768
|
+
}
|
|
10578
10769
|
async init() {
|
|
10579
10770
|
var _a;
|
|
10580
10771
|
try {
|
|
@@ -10751,8 +10942,23 @@
|
|
|
10751
10942
|
if (this.options.height) {
|
|
10752
10943
|
this.container.style.height = typeof this.options.height === "number" ? "".concat(this.options.height, "px") : this.options.height;
|
|
10753
10944
|
}
|
|
10945
|
+
if (this.element.tagName === "VIDEO" && !this.options.height) {
|
|
10946
|
+
const wAttr = parseInt(this.element.getAttribute("width") || "", 10);
|
|
10947
|
+
const hAttr = parseInt(this.element.getAttribute("height") || "", 10);
|
|
10948
|
+
if (Number.isFinite(wAttr) && Number.isFinite(hAttr) && wAttr > 0 && hAttr > 0) {
|
|
10949
|
+
if (!this.container.style.aspectRatio) {
|
|
10950
|
+
this.container.style.aspectRatio = "".concat(wAttr, " / ").concat(hAttr);
|
|
10951
|
+
}
|
|
10952
|
+
if (this.videoWrapper && !this.videoWrapper.style.aspectRatio) {
|
|
10953
|
+
this.videoWrapper.style.aspectRatio = "".concat(wAttr, " / ").concat(hAttr);
|
|
10954
|
+
this.videoWrapper.style.height = "auto";
|
|
10955
|
+
}
|
|
10956
|
+
}
|
|
10957
|
+
}
|
|
10754
10958
|
if (this.options.poster && this.element.tagName === "VIDEO") {
|
|
10755
|
-
|
|
10959
|
+
const resolvedPoster = this.resolvePosterPath(this.options.poster);
|
|
10960
|
+
this.element.poster = resolvedPoster;
|
|
10961
|
+
this.applyPosterAspectRatio(resolvedPoster);
|
|
10756
10962
|
}
|
|
10757
10963
|
if (this.element.tagName === "VIDEO") {
|
|
10758
10964
|
this.createPlayButtonOverlay();
|
|
@@ -10766,6 +10972,7 @@
|
|
|
10766
10972
|
}
|
|
10767
10973
|
});
|
|
10768
10974
|
this.on("play", () => {
|
|
10975
|
+
this.state.hasStartedPlayback = true;
|
|
10769
10976
|
this.hidePosterOverlay();
|
|
10770
10977
|
});
|
|
10771
10978
|
this.on("timeupdate", () => {
|
|
@@ -10779,6 +10986,34 @@
|
|
|
10779
10986
|
}
|
|
10780
10987
|
}, { once: true });
|
|
10781
10988
|
}
|
|
10989
|
+
/**
|
|
10990
|
+
* Apply aspect ratio to the video wrapper based on the poster's intrinsic size.
|
|
10991
|
+
* This helps render correct poster sizing before media metadata is available.
|
|
10992
|
+
*/
|
|
10993
|
+
applyPosterAspectRatio(posterUrl) {
|
|
10994
|
+
try {
|
|
10995
|
+
if (!posterUrl) return;
|
|
10996
|
+
if (this.element.tagName !== "VIDEO") return;
|
|
10997
|
+
if (!this.videoWrapper) return;
|
|
10998
|
+
if (this.options.width || this.options.height) return;
|
|
10999
|
+
if (this._posterAspectAppliedFor === posterUrl) return;
|
|
11000
|
+
this._posterAspectAppliedFor = posterUrl;
|
|
11001
|
+
const img = new Image();
|
|
11002
|
+
img.decoding = "async";
|
|
11003
|
+
img.onload = () => {
|
|
11004
|
+
const w = img.naturalWidth;
|
|
11005
|
+
const h = img.naturalHeight;
|
|
11006
|
+
if (!w || !h) return;
|
|
11007
|
+
this.videoWrapper.style.aspectRatio = "".concat(w, " / ").concat(h);
|
|
11008
|
+
this.videoWrapper.style.height = "auto";
|
|
11009
|
+
if (this.container && !this.container.style.aspectRatio) {
|
|
11010
|
+
this.container.style.aspectRatio = "".concat(w, " / ").concat(h);
|
|
11011
|
+
}
|
|
11012
|
+
};
|
|
11013
|
+
img.src = posterUrl;
|
|
11014
|
+
} catch (e) {
|
|
11015
|
+
}
|
|
11016
|
+
}
|
|
10782
11017
|
createPlayButtonOverlay() {
|
|
10783
11018
|
this.playButtonOverlay = createPlayOverlay();
|
|
10784
11019
|
this.playButtonOverlay.addEventListener("click", () => {
|
|
@@ -11177,7 +11412,25 @@
|
|
|
11177
11412
|
await this.initializeRenderer();
|
|
11178
11413
|
} else {
|
|
11179
11414
|
this.renderer.media = this.element;
|
|
11180
|
-
this.
|
|
11415
|
+
if (this.options.deferLoad) {
|
|
11416
|
+
try {
|
|
11417
|
+
this.element.preload = this.options.preload || "metadata";
|
|
11418
|
+
} catch (e) {
|
|
11419
|
+
}
|
|
11420
|
+
if (this.renderer) {
|
|
11421
|
+
if (typeof this.renderer._didDeferredLoad === "boolean") {
|
|
11422
|
+
this.renderer._didDeferredLoad = false;
|
|
11423
|
+
}
|
|
11424
|
+
if (typeof this.renderer._hlsSourceLoaded === "boolean") {
|
|
11425
|
+
this.renderer._hlsSourceLoaded = false;
|
|
11426
|
+
}
|
|
11427
|
+
if ("_pendingSrc" in this.renderer) {
|
|
11428
|
+
this.renderer._pendingSrc = this._pendingSource || this.currentSource || null;
|
|
11429
|
+
}
|
|
11430
|
+
}
|
|
11431
|
+
} else {
|
|
11432
|
+
this.element.load();
|
|
11433
|
+
}
|
|
11181
11434
|
}
|
|
11182
11435
|
if (isExternalRenderer) {
|
|
11183
11436
|
setTimeout(() => {
|
|
@@ -11222,6 +11475,20 @@
|
|
|
11222
11475
|
this.handleError(error);
|
|
11223
11476
|
}
|
|
11224
11477
|
}
|
|
11478
|
+
/**
|
|
11479
|
+
* Ensure the current renderer has started its initial load (metadata/manifest)
|
|
11480
|
+
* without starting playback. This is useful for playlists to behave like
|
|
11481
|
+
* single videos on selection, while still keeping autoplay off.
|
|
11482
|
+
*/
|
|
11483
|
+
ensureLoaded() {
|
|
11484
|
+
try {
|
|
11485
|
+
if (!this.renderer) return;
|
|
11486
|
+
if (typeof this.renderer.ensureLoaded === "function") {
|
|
11487
|
+
this.renderer.ensureLoaded();
|
|
11488
|
+
}
|
|
11489
|
+
} catch (e) {
|
|
11490
|
+
}
|
|
11491
|
+
}
|
|
11225
11492
|
/**
|
|
11226
11493
|
* Check if we need to change renderer type
|
|
11227
11494
|
* @param {string} src - New source URL
|
|
@@ -11257,6 +11524,11 @@
|
|
|
11257
11524
|
play() {
|
|
11258
11525
|
if (this.renderer) {
|
|
11259
11526
|
this.renderer.play();
|
|
11527
|
+
return;
|
|
11528
|
+
}
|
|
11529
|
+
if (this.playlistManager && Array.isArray(this.playlistManager.tracks) && this.playlistManager.tracks.length > 0) {
|
|
11530
|
+
const index = this.playlistManager.currentIndex >= 0 ? this.playlistManager.currentIndex : 0;
|
|
11531
|
+
this.playlistManager.play(index, true);
|
|
11260
11532
|
}
|
|
11261
11533
|
}
|
|
11262
11534
|
pause() {
|
|
@@ -12586,6 +12858,18 @@
|
|
|
12586
12858
|
this.emit("audiodescriptiondisabled");
|
|
12587
12859
|
}
|
|
12588
12860
|
async toggleAudioDescription() {
|
|
12861
|
+
var _a, _b, _c;
|
|
12862
|
+
if (this.options.requirePlaybackForAccessibilityToggles && !this.renderer && ((_b = (_a = this.playlistManager) == null ? void 0 : _a.tracks) == null ? void 0 : _b.length)) {
|
|
12863
|
+
this.showNotice(i18n.t("player.startPlaybackForAudioDescription"));
|
|
12864
|
+
return;
|
|
12865
|
+
}
|
|
12866
|
+
if (!this.renderer && this.playlistManager && ((_c = this.playlistManager.tracks) == null ? void 0 : _c.length)) {
|
|
12867
|
+
this.audioDescriptionManager.desiredState = !this.audioDescriptionManager.desiredState;
|
|
12868
|
+
this.state.audioDescriptionEnabled = this.audioDescriptionManager.desiredState;
|
|
12869
|
+
this.emit(this.audioDescriptionManager.desiredState ? "audiodescriptionenabled" : "audiodescriptiondisabled");
|
|
12870
|
+
this.play();
|
|
12871
|
+
return;
|
|
12872
|
+
}
|
|
12589
12873
|
return this.audioDescriptionManager.toggle();
|
|
12590
12874
|
}
|
|
12591
12875
|
// Sign Language (delegated to SignLanguageManager)
|
|
@@ -12849,6 +13133,19 @@
|
|
|
12849
13133
|
return this.signLanguageManager.disable();
|
|
12850
13134
|
}
|
|
12851
13135
|
toggleSignLanguage() {
|
|
13136
|
+
var _a, _b, _c;
|
|
13137
|
+
if (this.options.requirePlaybackForAccessibilityToggles && !this.renderer && ((_b = (_a = this.playlistManager) == null ? void 0 : _a.tracks) == null ? void 0 : _b.length)) {
|
|
13138
|
+
this.showNotice(i18n.t("player.startPlaybackForSignLanguage"));
|
|
13139
|
+
return;
|
|
13140
|
+
}
|
|
13141
|
+
if (!this.renderer && this.playlistManager && ((_c = this.playlistManager.tracks) == null ? void 0 : _c.length)) {
|
|
13142
|
+
const wasEnabled = this.signLanguageManager.enabled;
|
|
13143
|
+
const result = this.signLanguageManager.toggle();
|
|
13144
|
+
if (!wasEnabled && this.signLanguageManager.enabled) {
|
|
13145
|
+
this.play();
|
|
13146
|
+
}
|
|
13147
|
+
return result;
|
|
13148
|
+
}
|
|
12852
13149
|
return this.signLanguageManager.toggle();
|
|
12853
13150
|
}
|
|
12854
13151
|
setupSignLanguageInteraction() {
|
|
@@ -13960,6 +14257,7 @@
|
|
|
13960
14257
|
* @param {boolean} autoPlay - Whether to auto-play after creation
|
|
13961
14258
|
*/
|
|
13962
14259
|
async recreatePlayerForTrack(track, autoPlay = false) {
|
|
14260
|
+
var _a;
|
|
13963
14261
|
if (!this.hostElement || !this.PlayerClass) {
|
|
13964
14262
|
console.warn("VidPly Playlist: Cannot recreate player - missing hostElement or PlayerClass");
|
|
13965
14263
|
return false;
|
|
@@ -13981,6 +14279,7 @@
|
|
|
13981
14279
|
if (this.playlistPanel && this.playlistPanel.parentNode) {
|
|
13982
14280
|
this.playlistPanel.parentNode.removeChild(this.playlistPanel);
|
|
13983
14281
|
}
|
|
14282
|
+
const preservedPlayerOptions = ((_a = this.player) == null ? void 0 : _a.options) ? __spreadValues({}, this.player.options) : {};
|
|
13984
14283
|
if (this.player) {
|
|
13985
14284
|
this.player.off("ended", this.handleTrackEnd);
|
|
13986
14285
|
this.player.off("error", this.handleTrackError);
|
|
@@ -13988,7 +14287,8 @@
|
|
|
13988
14287
|
}
|
|
13989
14288
|
this.hostElement.innerHTML = "";
|
|
13990
14289
|
const mediaElement = document.createElement(elementType);
|
|
13991
|
-
|
|
14290
|
+
const preloadValue = preservedPlayerOptions.preload || "metadata";
|
|
14291
|
+
mediaElement.setAttribute("preload", preloadValue);
|
|
13992
14292
|
if (elementType === "video" && track.poster && (mediaType === "video" || mediaType === "hls")) {
|
|
13993
14293
|
mediaElement.setAttribute("poster", track.poster);
|
|
13994
14294
|
}
|
|
@@ -14022,6 +14322,7 @@
|
|
|
14022
14322
|
audioDescriptionDuration: track.audioDescriptionDuration || null,
|
|
14023
14323
|
signLanguageSrc: track.signLanguageSrc || null
|
|
14024
14324
|
};
|
|
14325
|
+
Object.assign(playerOptions, preservedPlayerOptions);
|
|
14025
14326
|
this.player = new this.PlayerClass(mediaElement, playerOptions);
|
|
14026
14327
|
this.player.playlistManager = this;
|
|
14027
14328
|
await new Promise((resolve) => {
|
|
@@ -14184,31 +14485,35 @@
|
|
|
14184
14485
|
if (this.options.autoPlayFirst) {
|
|
14185
14486
|
this.play(0);
|
|
14186
14487
|
} else {
|
|
14187
|
-
this.loadTrack(0)
|
|
14488
|
+
void this.loadTrack(0).catch(() => {
|
|
14489
|
+
});
|
|
14188
14490
|
}
|
|
14189
14491
|
}
|
|
14190
14492
|
this.updatePlaylistVisibilityInFullscreen();
|
|
14191
14493
|
}
|
|
14192
14494
|
/**
|
|
14193
14495
|
* Load a track without playing
|
|
14496
|
+
* This is the playlist equivalent of a "single video initialized but not started yet":
|
|
14497
|
+
* it updates UI selection and loads the media into the player so metadata/manifests
|
|
14498
|
+
* and feature managers can be ready, but it does not start playback.
|
|
14194
14499
|
* @param {number} index - Track index
|
|
14195
14500
|
*/
|
|
14196
14501
|
async loadTrack(index) {
|
|
14502
|
+
var _a, _b;
|
|
14197
14503
|
if (index < 0 || index >= this.tracks.length) {
|
|
14198
14504
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
14199
14505
|
return;
|
|
14200
14506
|
}
|
|
14201
14507
|
const track = this.tracks[index];
|
|
14508
|
+
this.selectTrack(index);
|
|
14202
14509
|
this.isChangingTrack = true;
|
|
14203
|
-
this.currentIndex = index;
|
|
14204
14510
|
if (this.options.recreatePlayers && this.hostElement && this.PlayerClass) {
|
|
14205
14511
|
const currentMediaType = this.player ? this.player.element.tagName === "AUDIO" ? "audio" : "video" : null;
|
|
14206
14512
|
const newMediaType = this.getTrackMediaType(track);
|
|
14207
14513
|
const newElementType = newMediaType === "audio" || newMediaType === "soundcloud" ? "audio" : "video";
|
|
14208
14514
|
if (currentMediaType !== newElementType) {
|
|
14209
14515
|
await this.recreatePlayerForTrack(track, false);
|
|
14210
|
-
this.
|
|
14211
|
-
this.updatePlaylistUI();
|
|
14516
|
+
this.selectTrack(index);
|
|
14212
14517
|
this.player.emit("playlisttrackchange", {
|
|
14213
14518
|
index,
|
|
14214
14519
|
item: track,
|
|
@@ -14220,16 +14525,22 @@
|
|
|
14220
14525
|
return;
|
|
14221
14526
|
}
|
|
14222
14527
|
}
|
|
14223
|
-
this.player.load({
|
|
14528
|
+
const loadPromise = this.player.load({
|
|
14224
14529
|
src: track.src,
|
|
14225
14530
|
type: track.type,
|
|
14226
14531
|
poster: track.poster,
|
|
14227
14532
|
tracks: track.tracks || [],
|
|
14228
14533
|
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
14229
|
-
signLanguageSrc: track.signLanguageSrc || null
|
|
14230
|
-
|
|
14231
|
-
|
|
14232
|
-
this.
|
|
14534
|
+
signLanguageSrc: track.signLanguageSrc || null,
|
|
14535
|
+
signLanguageSources: track.signLanguageSources || {}
|
|
14536
|
+
});
|
|
14537
|
+
if (((_b = (_a = this.player) == null ? void 0 : _a.options) == null ? void 0 : _b.deferLoad) && typeof this.player.ensureLoaded === "function") {
|
|
14538
|
+
Promise.resolve(loadPromise).then(() => {
|
|
14539
|
+
var _a2, _b2;
|
|
14540
|
+
return (_b2 = (_a2 = this.player) == null ? void 0 : _a2.ensureLoaded) == null ? void 0 : _b2.call(_a2);
|
|
14541
|
+
}).catch(() => {
|
|
14542
|
+
});
|
|
14543
|
+
}
|
|
14233
14544
|
this.player.emit("playlisttrackchange", {
|
|
14234
14545
|
index,
|
|
14235
14546
|
item: track,
|
|
@@ -14239,12 +14550,105 @@
|
|
|
14239
14550
|
this.isChangingTrack = false;
|
|
14240
14551
|
}, 150);
|
|
14241
14552
|
}
|
|
14553
|
+
/**
|
|
14554
|
+
* Select a track (UI/selection only; does NOT set the media src / does NOT initialize renderer)
|
|
14555
|
+
*
|
|
14556
|
+
* In "B always" playlist mode, you typically want `loadTrack()` on selection so the
|
|
14557
|
+
* selected item behaves like a single video (metadata/manifest loaded, features ready)
|
|
14558
|
+
* without auto-playing.
|
|
14559
|
+
* @param {number} index - Track index
|
|
14560
|
+
*/
|
|
14561
|
+
selectTrack(index) {
|
|
14562
|
+
var _a, _b, _c, _d;
|
|
14563
|
+
if (index < 0 || index >= this.tracks.length) {
|
|
14564
|
+
console.warn("VidPly Playlist: Invalid track index", index);
|
|
14565
|
+
return;
|
|
14566
|
+
}
|
|
14567
|
+
const track = this.tracks[index];
|
|
14568
|
+
this.currentIndex = index;
|
|
14569
|
+
try {
|
|
14570
|
+
if (((_b = (_a = this.player) == null ? void 0 : _a.element) == null ? void 0 : _b.tagName) === "VIDEO") {
|
|
14571
|
+
if (track.poster) {
|
|
14572
|
+
const posterUrl = typeof this.player.resolvePosterPath === "function" ? this.player.resolvePosterPath(track.poster) : track.poster;
|
|
14573
|
+
this.player.element.poster = posterUrl;
|
|
14574
|
+
(_d = (_c = this.player).applyPosterAspectRatio) == null ? void 0 : _d.call(_c, posterUrl);
|
|
14575
|
+
} else {
|
|
14576
|
+
this.player.element.removeAttribute("poster");
|
|
14577
|
+
}
|
|
14578
|
+
}
|
|
14579
|
+
this.player.audioDescriptionSrc = track.audioDescriptionSrc || null;
|
|
14580
|
+
this.player.signLanguageSrc = track.signLanguageSrc || null;
|
|
14581
|
+
this.player.signLanguageSources = track.signLanguageSources || {};
|
|
14582
|
+
if (track.duration && Number(track.duration) > 0) {
|
|
14583
|
+
this.player.state.duration = Number(track.duration);
|
|
14584
|
+
}
|
|
14585
|
+
if (this.player.audioDescriptionManager) {
|
|
14586
|
+
this.player.audioDescriptionManager.src = track.audioDescriptionSrc || null;
|
|
14587
|
+
this.player.audioDescriptionManager.originalSource = track.src || this.player.originalSrc || null;
|
|
14588
|
+
}
|
|
14589
|
+
if (this.player.signLanguageManager) {
|
|
14590
|
+
this.player.signLanguageManager.src = track.signLanguageSrc || null;
|
|
14591
|
+
this.player.signLanguageManager.sources = track.signLanguageSources || {};
|
|
14592
|
+
this.player.signLanguageManager.currentLanguage = null;
|
|
14593
|
+
}
|
|
14594
|
+
if (track.src && !this.player.originalSrc) {
|
|
14595
|
+
this.player.originalSrc = track.src;
|
|
14596
|
+
}
|
|
14597
|
+
const existing = Array.from(this.player.element.querySelectorAll("track"));
|
|
14598
|
+
existing.forEach((t) => t.remove());
|
|
14599
|
+
if (Array.isArray(track.tracks)) {
|
|
14600
|
+
track.tracks.forEach((tc) => {
|
|
14601
|
+
if (!(tc == null ? void 0 : tc.src)) return;
|
|
14602
|
+
const el = document.createElement("track");
|
|
14603
|
+
el.src = tc.src;
|
|
14604
|
+
el.kind = tc.kind || "captions";
|
|
14605
|
+
el.srclang = tc.srclang || "en";
|
|
14606
|
+
el.label = tc.label || tc.srclang || "Track";
|
|
14607
|
+
if (tc.default) el.default = true;
|
|
14608
|
+
if (tc.describedSrc) {
|
|
14609
|
+
el.setAttribute("data-desc-src", tc.describedSrc);
|
|
14610
|
+
}
|
|
14611
|
+
this.player.element.appendChild(el);
|
|
14612
|
+
});
|
|
14613
|
+
}
|
|
14614
|
+
if (typeof this.player.invalidateTrackCache === "function") {
|
|
14615
|
+
this.player.invalidateTrackCache();
|
|
14616
|
+
}
|
|
14617
|
+
if (this.player.audioDescriptionManager && typeof this.player.audioDescriptionManager.initFromSourceElements === "function") {
|
|
14618
|
+
try {
|
|
14619
|
+
this.player.audioDescriptionManager.captionTracks = [];
|
|
14620
|
+
this.player.audioDescriptionManager.initFromSourceElements(this.player.sourceElements, this.player.trackElements);
|
|
14621
|
+
} catch (e) {
|
|
14622
|
+
}
|
|
14623
|
+
}
|
|
14624
|
+
if (this.player.captionManager && typeof this.player.captionManager.loadTracks === "function") {
|
|
14625
|
+
try {
|
|
14626
|
+
this.player.captionManager.tracks = [];
|
|
14627
|
+
this.player.captionManager.currentTrack = null;
|
|
14628
|
+
this.player.captionManager.loadTracks();
|
|
14629
|
+
} catch (e) {
|
|
14630
|
+
}
|
|
14631
|
+
}
|
|
14632
|
+
if (typeof this.player.updateControlBar === "function") {
|
|
14633
|
+
this.player.updateControlBar();
|
|
14634
|
+
}
|
|
14635
|
+
} catch (e) {
|
|
14636
|
+
}
|
|
14637
|
+
this.updateTrackInfo(track);
|
|
14638
|
+
this.updatePlaylistUI();
|
|
14639
|
+
this.player.emit("playlisttrackselect", {
|
|
14640
|
+
index,
|
|
14641
|
+
item: track,
|
|
14642
|
+
total: this.tracks.length
|
|
14643
|
+
});
|
|
14644
|
+
}
|
|
14242
14645
|
/**
|
|
14243
14646
|
* Play a specific track
|
|
14244
14647
|
* @param {number} index - Track index
|
|
14245
14648
|
* @param {boolean} userInitiated - Whether this was triggered by user action (default: false)
|
|
14246
14649
|
*/
|
|
14247
14650
|
async play(index, userInitiated = false) {
|
|
14651
|
+
var _a, _b;
|
|
14248
14652
|
if (index < 0 || index >= this.tracks.length) {
|
|
14249
14653
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
14250
14654
|
return;
|
|
@@ -14271,13 +14675,21 @@
|
|
|
14271
14675
|
return;
|
|
14272
14676
|
}
|
|
14273
14677
|
}
|
|
14678
|
+
let srcToLoad = track.src;
|
|
14679
|
+
if (((_b = (_a = this.player) == null ? void 0 : _a.audioDescriptionManager) == null ? void 0 : _b.desiredState) && track.audioDescriptionSrc) {
|
|
14680
|
+
this.player.originalSrc = track.src;
|
|
14681
|
+
this.player.audioDescriptionManager.originalSource = track.src;
|
|
14682
|
+
this.player.audioDescriptionManager.src = track.audioDescriptionSrc;
|
|
14683
|
+
srcToLoad = track.audioDescriptionSrc;
|
|
14684
|
+
}
|
|
14274
14685
|
this.player.load({
|
|
14275
|
-
src:
|
|
14686
|
+
src: srcToLoad,
|
|
14276
14687
|
type: track.type,
|
|
14277
14688
|
poster: track.poster,
|
|
14278
14689
|
tracks: track.tracks || [],
|
|
14279
14690
|
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
14280
|
-
signLanguageSrc: track.signLanguageSrc || null
|
|
14691
|
+
signLanguageSrc: track.signLanguageSrc || null,
|
|
14692
|
+
signLanguageSources: track.signLanguageSources || {}
|
|
14281
14693
|
});
|
|
14282
14694
|
this.updateTrackInfo(track);
|
|
14283
14695
|
this.updatePlaylistUI();
|