vidply 1.0.20 → 1.0.22

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.
@@ -129,14 +129,21 @@ var init_HTML5Renderer = __esm({
129
129
  });
130
130
  }
131
131
  play() {
132
+ const scrollX = window.scrollX;
133
+ const scrollY = window.scrollY;
132
134
  const promise = this.media.play();
135
+ window.scrollTo(scrollX, scrollY);
133
136
  if (promise !== void 0) {
134
137
  promise.catch((error) => {
135
138
  this.player.log("Play failed:", error, "warn");
136
139
  if (this.player.options.autoplay && !this.player.state.muted) {
137
140
  this.player.log("Retrying play with muted audio", "info");
138
141
  this.media.muted = true;
139
- this.media.play().catch((err) => {
142
+ const retryScrollX = window.scrollX;
143
+ const retryScrollY = window.scrollY;
144
+ this.media.play().then(() => {
145
+ window.scrollTo(retryScrollX, retryScrollY);
146
+ }).catch((err) => {
140
147
  this.player.handleError(err);
141
148
  });
142
149
  }
@@ -558,6 +565,14 @@ var en = {
558
565
  minutes: "{count} minutes",
559
566
  second: "{count} second",
560
567
  seconds: "{count} seconds"
568
+ },
569
+ playlist: {
570
+ title: "Playlist",
571
+ trackOf: "Track {current} of {total}",
572
+ nowPlaying: "Now playing: Track {current} of {total}. {title}{artist}",
573
+ by: " by ",
574
+ untitled: "Untitled",
575
+ trackUntitled: "Track {number}"
561
576
  }
562
577
  };
563
578
 
@@ -717,6 +732,14 @@ var de = {
717
732
  minutes: "{count} Minuten",
718
733
  second: "{count} Sekunde",
719
734
  seconds: "{count} Sekunden"
735
+ },
736
+ playlist: {
737
+ title: "Wiedergabeliste",
738
+ trackOf: "Titel {current} von {total}",
739
+ nowPlaying: "L\xE4uft gerade: Titel {current} von {total}. {title}{artist}",
740
+ by: " von ",
741
+ untitled: "Ohne Titel",
742
+ trackUntitled: "Titel {number}"
720
743
  }
721
744
  };
722
745
 
@@ -876,6 +899,14 @@ var es = {
876
899
  minutes: "{count} minutos",
877
900
  second: "{count} segundo",
878
901
  seconds: "{count} segundos"
902
+ },
903
+ playlist: {
904
+ title: "Lista de reproducci\xF3n",
905
+ trackOf: "Pista {current} de {total}",
906
+ nowPlaying: "Reproduciendo ahora: Pista {current} de {total}. {title}{artist}",
907
+ by: " por ",
908
+ untitled: "Sin t\xEDtulo",
909
+ trackUntitled: "Pista {number}"
879
910
  }
880
911
  };
881
912
 
@@ -1035,6 +1066,14 @@ var fr = {
1035
1066
  minutes: "{count} minutes",
1036
1067
  second: "{count} seconde",
1037
1068
  seconds: "{count} secondes"
1069
+ },
1070
+ playlist: {
1071
+ title: "Liste de lecture",
1072
+ trackOf: "Piste {current} sur {total}",
1073
+ nowPlaying: "Lecture en cours : Piste {current} sur {total}. {title}{artist}",
1074
+ by: " par ",
1075
+ untitled: "Sans titre",
1076
+ trackUntitled: "Piste {number}"
1038
1077
  }
1039
1078
  };
1040
1079
 
@@ -1194,6 +1233,14 @@ var ja = {
1194
1233
  minutes: "{count}\u5206",
1195
1234
  second: "{count}\u79D2",
1196
1235
  seconds: "{count}\u79D2"
1236
+ },
1237
+ playlist: {
1238
+ title: "\u30D7\u30EC\u30A4\u30EA\u30B9\u30C8",
1239
+ trackOf: "\u30C8\u30E9\u30C3\u30AF {current}/{total}",
1240
+ nowPlaying: "\u518D\u751F\u4E2D: \u30C8\u30E9\u30C3\u30AF {current}/{total}. {title}{artist}",
1241
+ by: " - ",
1242
+ untitled: "\u30BF\u30A4\u30C8\u30EB\u306A\u3057",
1243
+ trackUntitled: "\u30C8\u30E9\u30C3\u30AF {number}"
1197
1244
  }
1198
1245
  };
1199
1246
 
@@ -2680,7 +2727,8 @@ var ControlBar = class {
2680
2727
  attributes: {
2681
2728
  "type": "button",
2682
2729
  "aria-label": i18n.t("player.quality"),
2683
- "aria-expanded": "false"
2730
+ "aria-expanded": "false",
2731
+ "title": i18n.t("player.quality")
2684
2732
  }
2685
2733
  });
2686
2734
  button.appendChild(createIconElement("hd"));
@@ -7223,7 +7271,10 @@ var YouTubeRenderer = class {
7223
7271
  }
7224
7272
  play() {
7225
7273
  if (this.isReady && this.youtube) {
7274
+ const scrollX = window.scrollX;
7275
+ const scrollY = window.scrollY;
7226
7276
  this.youtube.playVideo();
7277
+ window.scrollTo(scrollX, scrollY);
7227
7278
  }
7228
7279
  }
7229
7280
  pause() {
@@ -7417,9 +7468,12 @@ var VimeoRenderer = class {
7417
7468
  }
7418
7469
  play() {
7419
7470
  if (this.isReady && this.vimeo) {
7471
+ const scrollX = window.scrollX;
7472
+ const scrollY = window.scrollY;
7420
7473
  this.vimeo.play().catch((error) => {
7421
7474
  this.player.log("Play error:", error, "warn");
7422
7475
  });
7476
+ window.scrollTo(scrollX, scrollY);
7423
7477
  }
7424
7478
  }
7425
7479
  pause() {
@@ -7492,6 +7546,11 @@ var HLSRenderer = class {
7492
7546
  }
7493
7547
  }
7494
7548
  canPlayNatively() {
7549
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
7550
+ const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
7551
+ if (!isSafari && !isIOS) {
7552
+ return false;
7553
+ }
7495
7554
  const video = document.createElement("video");
7496
7555
  return video.canPlayType("application/vnd.apple.mpegurl") !== "";
7497
7556
  }
@@ -7666,7 +7725,10 @@ var HLSRenderer = class {
7666
7725
  }
7667
7726
  }
7668
7727
  play() {
7728
+ const scrollX = window.scrollX;
7729
+ const scrollY = window.scrollY;
7669
7730
  const promise = this.media.play();
7731
+ window.scrollTo(scrollX, scrollY);
7670
7732
  if (promise !== void 0) {
7671
7733
  promise.catch((error) => {
7672
7734
  this.player.log("Play failed:", error, "warn");
@@ -8016,6 +8078,16 @@ var Player = class _Player extends EventEmitter {
8016
8078
  className: `${this.options.classPrefix}-video-wrapper`
8017
8079
  });
8018
8080
  this.element.parentNode.insertBefore(this.container, this.element);
8081
+ if (this.element.tagName === "AUDIO" && this.options.poster) {
8082
+ this.trackArtworkElement = DOMUtils.createElement("div", {
8083
+ className: `${this.options.classPrefix}-track-artwork`,
8084
+ attributes: {
8085
+ "aria-hidden": "true"
8086
+ }
8087
+ });
8088
+ this.trackArtworkElement.style.backgroundImage = `url(${this.options.poster})`;
8089
+ this.container.appendChild(this.trackArtworkElement);
8090
+ }
8019
8091
  this.container.appendChild(this.videoWrapper);
8020
8092
  this.videoWrapper.appendChild(this.element);
8021
8093
  this.element.controls = false;
@@ -8324,6 +8396,8 @@ var Player = class _Player extends EventEmitter {
8324
8396
  * @param {string} config.type - Media MIME type
8325
8397
  * @param {string} [config.poster] - Poster image URL
8326
8398
  * @param {Array} [config.tracks] - Text tracks (captions, chapters, etc.)
8399
+ * @param {string} [config.audioDescriptionSrc] - Audio description video URL
8400
+ * @param {string} [config.signLanguageSrc] - Sign language video URL
8327
8401
  */
8328
8402
  async load(config) {
8329
8403
  try {
@@ -8331,6 +8405,8 @@ var Player = class _Player extends EventEmitter {
8331
8405
  if (this.renderer) {
8332
8406
  this.pause();
8333
8407
  }
8408
+ const scrollX = window.scrollX || window.pageXOffset;
8409
+ const scrollY = window.scrollY || window.pageYOffset;
8334
8410
  const existingTracks = this.trackElements;
8335
8411
  existingTracks.forEach((track) => track.remove());
8336
8412
  this.invalidateTrackCache();
@@ -8355,6 +8431,17 @@ var Player = class _Player extends EventEmitter {
8355
8431
  });
8356
8432
  this.invalidateTrackCache();
8357
8433
  }
8434
+ const wasSignLanguageEnabled = this.state.signLanguageEnabled;
8435
+ const wasAudioDescriptionEnabled = this.state.audioDescriptionEnabled;
8436
+ this.audioDescriptionSrc = config.audioDescriptionSrc || null;
8437
+ this.signLanguageSrc = config.signLanguageSrc || null;
8438
+ this.originalSrc = config.src;
8439
+ if (wasAudioDescriptionEnabled) {
8440
+ this.disableAudioDescription();
8441
+ }
8442
+ if (wasSignLanguageEnabled) {
8443
+ this.disableSignLanguage();
8444
+ }
8358
8445
  const shouldChangeRenderer = this.shouldChangeRenderer(config.src);
8359
8446
  if (shouldChangeRenderer && this.renderer) {
8360
8447
  this.renderer.destroy();
@@ -8366,21 +8453,35 @@ var Player = class _Player extends EventEmitter {
8366
8453
  this.renderer.media = this.element;
8367
8454
  this.element.load();
8368
8455
  }
8456
+ window.scrollTo(scrollX, scrollY);
8369
8457
  if (this.captionManager) {
8370
8458
  this.captionManager.destroy();
8371
8459
  this.captionManager = new CaptionManager(this);
8372
8460
  }
8373
8461
  if (this.transcriptManager) {
8374
- const wasVisible = this.transcriptManager.isVisible;
8462
+ const wasTranscriptVisible = this.transcriptManager.isVisible;
8375
8463
  this.transcriptManager.destroy();
8376
8464
  this.transcriptManager = new TranscriptManager(this);
8377
- if (wasVisible) {
8465
+ if (wasTranscriptVisible && this.controlBar && this.controlBar.hasCaptionTracks()) {
8378
8466
  this.transcriptManager.showTranscript();
8379
8467
  }
8380
8468
  }
8381
8469
  if (this.controlBar) {
8382
8470
  this.updateControlBar();
8383
8471
  }
8472
+ window.scrollTo(scrollX, scrollY);
8473
+ if (wasSignLanguageEnabled && this.signLanguageSrc) {
8474
+ setTimeout(() => {
8475
+ this.enableSignLanguage();
8476
+ window.scrollTo(scrollX, scrollY);
8477
+ }, 150);
8478
+ }
8479
+ if (wasAudioDescriptionEnabled && this.audioDescriptionSrc) {
8480
+ setTimeout(() => {
8481
+ this.enableAudioDescription();
8482
+ window.scrollTo(scrollX, scrollY);
8483
+ }, 150);
8484
+ }
8384
8485
  this.emit("sourcechange", config);
8385
8486
  this.log("Media loaded successfully");
8386
8487
  } catch (error) {
@@ -8402,6 +8503,7 @@ var Player = class _Player extends EventEmitter {
8402
8503
  controlBar.createControls();
8403
8504
  controlBar.attachEvents();
8404
8505
  controlBar.setupAutoHide();
8506
+ controlBar.setupOverflowDetection();
8405
8507
  }
8406
8508
  shouldChangeRenderer(src) {
8407
8509
  if (!this.renderer) return true;
@@ -11146,6 +11248,7 @@ var PlaylistManager = class {
11146
11248
  this.trackInfoElement = null;
11147
11249
  this.navigationFeedback = null;
11148
11250
  this.isPanelVisible = this.options.showPanel !== false;
11251
+ this.isChangingTrack = false;
11149
11252
  this.handleTrackEnd = this.handleTrackEnd.bind(this);
11150
11253
  this.handleTrackError = this.handleTrackError.bind(this);
11151
11254
  this.player.playlistManager = this;
@@ -11269,12 +11372,15 @@ var PlaylistManager = class {
11269
11372
  return;
11270
11373
  }
11271
11374
  const track = this.tracks[index];
11375
+ this.isChangingTrack = true;
11272
11376
  this.currentIndex = index;
11273
11377
  this.player.load({
11274
11378
  src: track.src,
11275
11379
  type: track.type,
11276
11380
  poster: track.poster,
11277
- tracks: track.tracks || []
11381
+ tracks: track.tracks || [],
11382
+ audioDescriptionSrc: track.audioDescriptionSrc || null,
11383
+ signLanguageSrc: track.signLanguageSrc || null
11278
11384
  });
11279
11385
  this.updateTrackInfo(track);
11280
11386
  this.updatePlaylistUI();
@@ -11283,6 +11389,9 @@ var PlaylistManager = class {
11283
11389
  item: track,
11284
11390
  total: this.tracks.length
11285
11391
  });
11392
+ setTimeout(() => {
11393
+ this.isChangingTrack = false;
11394
+ }, 150);
11286
11395
  }
11287
11396
  /**
11288
11397
  * Play a specific track
@@ -11295,12 +11404,15 @@ var PlaylistManager = class {
11295
11404
  return;
11296
11405
  }
11297
11406
  const track = this.tracks[index];
11407
+ this.isChangingTrack = true;
11298
11408
  this.currentIndex = index;
11299
11409
  this.player.load({
11300
11410
  src: track.src,
11301
11411
  type: track.type,
11302
11412
  poster: track.poster,
11303
- tracks: track.tracks || []
11413
+ tracks: track.tracks || [],
11414
+ audioDescriptionSrc: track.audioDescriptionSrc || null,
11415
+ signLanguageSrc: track.signLanguageSrc || null
11304
11416
  });
11305
11417
  this.updateTrackInfo(track);
11306
11418
  this.updatePlaylistUI();
@@ -11311,6 +11423,9 @@ var PlaylistManager = class {
11311
11423
  });
11312
11424
  setTimeout(() => {
11313
11425
  this.player.play();
11426
+ setTimeout(() => {
11427
+ this.isChangingTrack = false;
11428
+ }, 50);
11314
11429
  }, 100);
11315
11430
  }
11316
11431
  /**
@@ -11345,6 +11460,9 @@ var PlaylistManager = class {
11345
11460
  * Handle track end
11346
11461
  */
11347
11462
  handleTrackEnd() {
11463
+ if (this.isChangingTrack) {
11464
+ return;
11465
+ }
11348
11466
  if (this.options.autoAdvance) {
11349
11467
  this.next();
11350
11468
  }
@@ -11413,6 +11531,21 @@ var PlaylistManager = class {
11413
11531
  console.warn("VidPly Playlist: No container found");
11414
11532
  return;
11415
11533
  }
11534
+ if (this.player.element.tagName === "AUDIO") {
11535
+ this.trackArtworkElement = DOMUtils.createElement("div", {
11536
+ className: "vidply-track-artwork",
11537
+ attributes: {
11538
+ "aria-hidden": "true"
11539
+ }
11540
+ });
11541
+ this.trackArtworkElement.style.display = "none";
11542
+ const videoWrapper = this.container.querySelector(".vidply-video-wrapper");
11543
+ if (videoWrapper) {
11544
+ this.container.insertBefore(this.trackArtworkElement, videoWrapper);
11545
+ } else {
11546
+ this.container.appendChild(this.trackArtworkElement);
11547
+ }
11548
+ }
11416
11549
  this.trackInfoElement = DOMUtils.createElement("div", {
11417
11550
  className: "vidply-track-info",
11418
11551
  attributes: {
@@ -11437,7 +11570,7 @@ var PlaylistManager = class {
11437
11570
  attributes: {
11438
11571
  id: `${this.uniqueId}-panel`,
11439
11572
  role: "region",
11440
- "aria-label": "Media playlist",
11573
+ "aria-label": i18n.t("playlist.title"),
11441
11574
  "aria-labelledby": `${this.uniqueId}-heading`
11442
11575
  }
11443
11576
  });
@@ -11451,16 +11584,39 @@ var PlaylistManager = class {
11451
11584
  if (!this.trackInfoElement) return;
11452
11585
  const trackNumber = this.currentIndex + 1;
11453
11586
  const totalTracks = this.tracks.length;
11454
- const trackTitle = track.title || "Untitled";
11587
+ const trackTitle = track.title || i18n.t("playlist.untitled");
11455
11588
  const trackArtist = track.artist || "";
11456
- const announcement = `Now playing: Track ${trackNumber} of ${totalTracks}. ${trackTitle}${trackArtist ? " by " + trackArtist : ""}`;
11589
+ const artistPart = trackArtist ? i18n.t("playlist.by") + trackArtist : "";
11590
+ const announcement = i18n.t("playlist.nowPlaying", {
11591
+ current: trackNumber,
11592
+ total: totalTracks,
11593
+ title: trackTitle,
11594
+ artist: artistPart
11595
+ });
11596
+ const trackOfText = i18n.t("playlist.trackOf", {
11597
+ current: trackNumber,
11598
+ total: totalTracks
11599
+ });
11457
11600
  this.trackInfoElement.innerHTML = `
11458
11601
  <span class="vidply-sr-only">${DOMUtils.escapeHTML(announcement)}</span>
11459
- <div class="vidply-track-number" aria-hidden="true">Track ${trackNumber} of ${totalTracks}</div>
11602
+ <div class="vidply-track-number" aria-hidden="true">${DOMUtils.escapeHTML(trackOfText)}</div>
11460
11603
  <div class="vidply-track-title" aria-hidden="true">${DOMUtils.escapeHTML(trackTitle)}</div>
11461
11604
  ${trackArtist ? `<div class="vidply-track-artist" aria-hidden="true">${DOMUtils.escapeHTML(trackArtist)}</div>` : ""}
11462
11605
  `;
11463
11606
  this.trackInfoElement.style.display = "block";
11607
+ this.updateTrackArtwork(track);
11608
+ }
11609
+ /**
11610
+ * Update track artwork display (for audio playlists)
11611
+ */
11612
+ updateTrackArtwork(track) {
11613
+ if (!this.trackArtworkElement) return;
11614
+ if (track.poster) {
11615
+ this.trackArtworkElement.style.backgroundImage = `url(${track.poster})`;
11616
+ this.trackArtworkElement.style.display = "block";
11617
+ } else {
11618
+ this.trackArtworkElement.style.display = "none";
11619
+ }
11464
11620
  }
11465
11621
  /**
11466
11622
  * Render playlist
@@ -11474,7 +11630,7 @@ var PlaylistManager = class {
11474
11630
  id: `${this.uniqueId}-heading`
11475
11631
  }
11476
11632
  });
11477
- header.textContent = `Playlist (${this.tracks.length})`;
11633
+ header.textContent = `${i18n.t("playlist.title")} (${this.tracks.length})`;
11478
11634
  this.playlistPanel.appendChild(header);
11479
11635
  const instructions = DOMUtils.createElement("div", {
11480
11636
  className: "vidply-sr-only",
@@ -11504,9 +11660,12 @@ var PlaylistManager = class {
11504
11660
  * Create playlist item element
11505
11661
  */
11506
11662
  createPlaylistItem(track, index) {
11507
- const trackPosition = `Track ${index + 1} of ${this.tracks.length}`;
11508
- const trackTitle = track.title || `Track ${index + 1}`;
11509
- const trackArtist = track.artist ? ` by ${track.artist}` : "";
11663
+ const trackPosition = i18n.t("playlist.trackOf", {
11664
+ current: index + 1,
11665
+ total: this.tracks.length
11666
+ });
11667
+ const trackTitle = track.title || i18n.t("playlist.trackUntitled", { number: index + 1 });
11668
+ const trackArtist = track.artist ? i18n.t("playlist.by") + track.artist : "";
11510
11669
  const isActive = index === this.currentIndex;
11511
11670
  const statusText = isActive ? "Currently playing" : "Not playing";
11512
11671
  const actionText = isActive ? "Press Enter to restart" : "Press Enter to play";
@@ -11668,9 +11827,12 @@ var PlaylistManager = class {
11668
11827
  const button = buttons[index];
11669
11828
  if (!button) return;
11670
11829
  const track = this.tracks[index];
11671
- const trackPosition = `Track ${index + 1} of ${this.tracks.length}`;
11672
- const trackTitle = track.title || `Track ${index + 1}`;
11673
- const trackArtist = track.artist ? ` by ${track.artist}` : "";
11830
+ const trackPosition = i18n.t("playlist.trackOf", {
11831
+ current: index + 1,
11832
+ total: this.tracks.length
11833
+ });
11834
+ const trackTitle = track.title || i18n.t("playlist.trackUntitled", { number: index + 1 });
11835
+ const trackArtist = track.artist ? i18n.t("playlist.by") + track.artist : "";
11674
11836
  if (index === this.currentIndex) {
11675
11837
  item.classList.add("vidply-playlist-item-active");
11676
11838
  button.setAttribute("aria-current", "true");
@@ -11764,6 +11926,10 @@ var PlaylistManager = class {
11764
11926
  this.trackInfoElement.innerHTML = "";
11765
11927
  this.trackInfoElement.style.display = "none";
11766
11928
  }
11929
+ if (this.trackArtworkElement) {
11930
+ this.trackArtworkElement.style.backgroundImage = "";
11931
+ this.trackArtworkElement.style.display = "none";
11932
+ }
11767
11933
  }
11768
11934
  /**
11769
11935
  * Toggle playlist panel visibility
@@ -11817,6 +11983,9 @@ var PlaylistManager = class {
11817
11983
  destroy() {
11818
11984
  this.player.off("ended", this.handleTrackEnd);
11819
11985
  this.player.off("error", this.handleTrackError);
11986
+ if (this.trackArtworkElement) {
11987
+ this.trackArtworkElement.remove();
11988
+ }
11820
11989
  if (this.trackInfoElement) {
11821
11990
  this.trackInfoElement.remove();
11822
11991
  }