vidply 1.0.26 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/{vidply.HLSRenderer-X46P47LY.js → vidply.HLSRenderer-ENLZE4QS.js} +13 -8
- package/dist/dev/vidply.HLSRenderer-ENLZE4QS.js.map +7 -0
- package/dist/dev/{vidply.HTML5Renderer-LXQ3I45Q.js → vidply.HTML5Renderer-6SBDI6S2.js} +2 -2
- package/dist/dev/vidply.SoundCloudRenderer-CD7VJKNS.js +280 -0
- package/dist/dev/vidply.SoundCloudRenderer-CD7VJKNS.js.map +7 -0
- package/dist/dev/vidply.TranscriptManager-QSF2PWUN.js +1744 -0
- package/dist/dev/vidply.TranscriptManager-QSF2PWUN.js.map +7 -0
- package/dist/dev/vidply.TranscriptManager-UTJBQC5B.js +1744 -0
- package/dist/dev/vidply.TranscriptManager-UTJBQC5B.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-5663PYKK.js +1631 -0
- package/dist/dev/vidply.chunk-5663PYKK.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.chunk-SRM7VNHG.js +1638 -0
- package/dist/dev/vidply.chunk-SRM7VNHG.js.map +7 -0
- package/dist/dev/vidply.de-RXAJM5QE.js +181 -0
- package/dist/dev/vidply.de-RXAJM5QE.js.map +7 -0
- package/dist/dev/vidply.de-SNL6AJ4D.js +188 -0
- package/dist/dev/vidply.de-SNL6AJ4D.js.map +7 -0
- package/dist/dev/vidply.es-2QCQKZ4U.js +188 -0
- package/dist/dev/vidply.es-2QCQKZ4U.js.map +7 -0
- package/dist/dev/vidply.es-SADVLJTQ.js +181 -0
- package/dist/dev/vidply.es-SADVLJTQ.js.map +7 -0
- package/dist/dev/vidply.esm.js +297 -21
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/dev/vidply.fr-FJAZRL4L.js +188 -0
- package/dist/dev/vidply.fr-FJAZRL4L.js.map +7 -0
- package/dist/dev/vidply.fr-V3VAYBBT.js +181 -0
- package/dist/dev/vidply.fr-V3VAYBBT.js.map +7 -0
- package/dist/dev/vidply.ja-2XQOW53T.js +188 -0
- package/dist/dev/vidply.ja-2XQOW53T.js.map +7 -0
- package/dist/dev/vidply.ja-KL2TLZGJ.js +181 -0
- package/dist/dev/vidply.ja-KL2TLZGJ.js.map +7 -0
- package/dist/legacy/vidply.js +662 -36
- package/dist/legacy/vidply.js.map +3 -3
- package/dist/legacy/vidply.min.js +1 -1
- package/dist/legacy/vidply.min.meta.json +38 -25
- 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.TranscriptManager-DZ2WZU3K.min.js +6 -0
- package/dist/prod/vidply.TranscriptManager-E5QHGFIR.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-5DWTMWEO.min.js +6 -0
- package/dist/prod/vidply.chunk-IBNYTGGM.min.js +6 -0
- package/dist/prod/vidply.chunk-OXXPY2XB.min.js +6 -0
- package/dist/prod/vidply.de-FR3XX54P.min.js +6 -0
- package/dist/prod/vidply.de-HGJBCLLE.min.js +6 -0
- package/dist/prod/vidply.es-3IJCQLJ7.min.js +6 -0
- package/dist/prod/vidply.es-CZEBXCZN.min.js +6 -0
- package/dist/prod/vidply.esm.min.js +5 -5
- package/dist/prod/vidply.fr-HFOL7MWA.min.js +6 -0
- package/dist/prod/vidply.fr-NC4VEAPH.min.js +6 -0
- package/dist/prod/vidply.ja-4ZC6ZQLV.min.js +6 -0
- package/dist/prod/vidply.ja-QTVU5C25.min.js +6 -0
- package/dist/vidply.css +51 -0
- package/dist/vidply.esm.min.meta.json +87 -59
- package/dist/vidply.min.css +1 -1
- package/package.json +1 -1
- package/src/controls/TranscriptManager.js +1 -1
- package/src/core/Player.js +117 -8
- package/src/features/PlaylistManager.js +324 -16
- package/src/i18n/languages/de.js +9 -1
- package/src/i18n/languages/en.js +9 -1
- package/src/i18n/languages/es.js +9 -1
- package/src/i18n/languages/fr.js +9 -1
- package/src/i18n/languages/ja.js +9 -1
- package/src/renderers/HLSRenderer.js +17 -9
- package/src/renderers/HTML5Renderer.js +5 -0
- package/src/renderers/SoundCloudRenderer.js +355 -0
- package/src/renderers/VimeoRenderer.js +20 -4
- package/src/renderers/YouTubeRenderer.js +12 -6
- package/src/styles/vidply.css +51 -0
- package/dist/dev/vidply.HLSRenderer-X46P47LY.js.map +0 -7
- package/dist/dev/vidply.VimeoRenderer-DCETT5IZ.js.map +0 -7
- package/dist/dev/vidply.YouTubeRenderer-QLMMD757.js.map +0 -7
- package/dist/dev/vidply.chunk-UEIJOJH6.js.map +0 -7
- package/dist/prod/vidply.HLSRenderer-LDXSMWTI.min.js +0 -6
- package/dist/prod/vidply.VimeoRenderer-P3PU27S7.min.js +0 -6
- package/dist/prod/vidply.YouTubeRenderer-DGKKWB5M.min.js +0 -6
- package/dist/prod/vidply.chunk-BQBGEJF7.min.js +0 -6
- /package/dist/dev/{vidply.HTML5Renderer-LXQ3I45Q.js.map → vidply.HTML5Renderer-6SBDI6S2.js.map} +0 -0
package/dist/legacy/vidply.js
CHANGED
|
@@ -307,6 +307,7 @@
|
|
|
307
307
|
},
|
|
308
308
|
transcript: {
|
|
309
309
|
title: "Transcript",
|
|
310
|
+
ariaLabel: "Video Transcript",
|
|
310
311
|
close: "Close transcript",
|
|
311
312
|
loading: "Loading transcript...",
|
|
312
313
|
noTranscript: "No transcript available for this video.",
|
|
@@ -373,7 +374,14 @@
|
|
|
373
374
|
currentlyPlaying: "Currently playing",
|
|
374
375
|
notPlaying: "Not playing",
|
|
375
376
|
pressEnterPlay: "Press Enter to play",
|
|
376
|
-
pressEnterRestart: "Press Enter to restart"
|
|
377
|
+
pressEnterRestart: "Press Enter to restart",
|
|
378
|
+
keyboardInstructions: "Playlist navigation: Use Up and Down arrow keys to move between tracks. Press Page Up or Page Down to skip 5 tracks. Press Home to go to first track, End to go to last track. Press Enter or Space to play the selected track.",
|
|
379
|
+
endOfPlaylist: "End of playlist. {current} of {total}.",
|
|
380
|
+
beginningOfPlaylist: "Beginning of playlist. 1 of {total}.",
|
|
381
|
+
jumpedToLastTrack: "Jumped to last track. {current} of {total}.",
|
|
382
|
+
jumpedToFirstTrack: "Jumped to first track. 1 of {total}.",
|
|
383
|
+
firstTrack: "First track. 1 of {total}.",
|
|
384
|
+
lastTrack: "Last track. {current} of {total}."
|
|
377
385
|
}
|
|
378
386
|
};
|
|
379
387
|
}
|
|
@@ -487,6 +495,7 @@
|
|
|
487
495
|
},
|
|
488
496
|
transcript: {
|
|
489
497
|
title: "Transkript",
|
|
498
|
+
ariaLabel: "Video-Transkript",
|
|
490
499
|
close: "Transkript schließen",
|
|
491
500
|
loading: "Transkript wird geladen...",
|
|
492
501
|
noTranscript: "Kein Transkript für dieses Video verfügbar.",
|
|
@@ -553,7 +562,14 @@
|
|
|
553
562
|
currentlyPlaying: "Wird gerade abgespielt",
|
|
554
563
|
notPlaying: "Nicht aktiv",
|
|
555
564
|
pressEnterPlay: "Eingabetaste zum Abspielen",
|
|
556
|
-
pressEnterRestart: "Eingabetaste zum Neustart"
|
|
565
|
+
pressEnterRestart: "Eingabetaste zum Neustart",
|
|
566
|
+
keyboardInstructions: "Wiedergabelisten-Navigation: Verwenden Sie die Pfeiltasten nach oben und unten, um zwischen Titeln zu wechseln. Drücken Sie Bild auf oder Bild ab, um 5 Titel zu überspringen. Drücken Sie Pos1, um zum ersten Titel zu springen, Ende für den letzten Titel. Drücken Sie die Eingabetaste oder Leertaste, um den ausgewählten Titel abzuspielen.",
|
|
567
|
+
endOfPlaylist: "Ende der Wiedergabeliste. {current} von {total}.",
|
|
568
|
+
beginningOfPlaylist: "Anfang der Wiedergabeliste. 1 von {total}.",
|
|
569
|
+
jumpedToLastTrack: "Zum letzten Titel gesprungen. {current} von {total}.",
|
|
570
|
+
jumpedToFirstTrack: "Zum ersten Titel gesprungen. 1 von {total}.",
|
|
571
|
+
firstTrack: "Erster Titel. 1 von {total}.",
|
|
572
|
+
lastTrack: "Letzter Titel. {current} von {total}."
|
|
557
573
|
}
|
|
558
574
|
};
|
|
559
575
|
}
|
|
@@ -667,6 +683,7 @@
|
|
|
667
683
|
},
|
|
668
684
|
transcript: {
|
|
669
685
|
title: "Transcripción",
|
|
686
|
+
ariaLabel: "Transcripción de video",
|
|
670
687
|
close: "Cerrar transcripción",
|
|
671
688
|
loading: "Cargando transcripción...",
|
|
672
689
|
noTranscript: "No hay transcripción disponible para este video.",
|
|
@@ -733,7 +750,14 @@
|
|
|
733
750
|
currentlyPlaying: "Reproduciendo actualmente",
|
|
734
751
|
notPlaying: "Sin reproducir",
|
|
735
752
|
pressEnterPlay: "Pulsa Enter para reproducir",
|
|
736
|
-
pressEnterRestart: "Pulsa Enter para reiniciar"
|
|
753
|
+
pressEnterRestart: "Pulsa Enter para reiniciar",
|
|
754
|
+
keyboardInstructions: "Navegación de lista de reproducción: Use las teclas de flecha arriba y abajo para moverse entre pistas. Pulse Retroceder página o Avanzar página para saltar 5 pistas. Pulse Inicio para ir a la primera pista, Fin para la última pista. Pulse Intro o Espacio para reproducir la pista seleccionada.",
|
|
755
|
+
endOfPlaylist: "Fin de la lista de reproducción. {current} de {total}.",
|
|
756
|
+
beginningOfPlaylist: "Inicio de la lista de reproducción. 1 de {total}.",
|
|
757
|
+
jumpedToLastTrack: "Saltó a la última pista. {current} de {total}.",
|
|
758
|
+
jumpedToFirstTrack: "Saltó a la primera pista. 1 de {total}.",
|
|
759
|
+
firstTrack: "Primera pista. 1 de {total}.",
|
|
760
|
+
lastTrack: "Última pista. {current} de {total}."
|
|
737
761
|
}
|
|
738
762
|
};
|
|
739
763
|
}
|
|
@@ -847,6 +871,7 @@
|
|
|
847
871
|
},
|
|
848
872
|
transcript: {
|
|
849
873
|
title: "Transcription",
|
|
874
|
+
ariaLabel: "Transcription vidéo",
|
|
850
875
|
close: "Fermer la transcription",
|
|
851
876
|
loading: "Chargement de la transcription...",
|
|
852
877
|
noTranscript: "Aucune transcription disponible pour cette vidéo.",
|
|
@@ -913,7 +938,14 @@
|
|
|
913
938
|
currentlyPlaying: "En cours de lecture",
|
|
914
939
|
notPlaying: "Non en lecture",
|
|
915
940
|
pressEnterPlay: "Appuyez sur Entrée pour lire",
|
|
916
|
-
pressEnterRestart: "Appuyez sur Entrée pour recommencer"
|
|
941
|
+
pressEnterRestart: "Appuyez sur Entrée pour recommencer",
|
|
942
|
+
keyboardInstructions: "Navigation de la liste de lecture : Utilisez les touches fléchées haut et bas pour naviguer entre les pistes. Appuyez sur Page précédente ou Page suivante pour sauter 5 pistes. Appuyez sur Début pour aller à la première piste, Fin pour la dernière piste. Appuyez sur Entrée ou Espace pour lire la piste sélectionnée.",
|
|
943
|
+
endOfPlaylist: "Fin de la liste de lecture. {current} sur {total}.",
|
|
944
|
+
beginningOfPlaylist: "Début de la liste de lecture. 1 sur {total}.",
|
|
945
|
+
jumpedToLastTrack: "Sauté à la dernière piste. {current} sur {total}.",
|
|
946
|
+
jumpedToFirstTrack: "Sauté à la première piste. 1 sur {total}.",
|
|
947
|
+
firstTrack: "Première piste. 1 sur {total}.",
|
|
948
|
+
lastTrack: "Dernière piste. {current} sur {total}."
|
|
917
949
|
}
|
|
918
950
|
};
|
|
919
951
|
}
|
|
@@ -1027,6 +1059,7 @@
|
|
|
1027
1059
|
},
|
|
1028
1060
|
transcript: {
|
|
1029
1061
|
title: "文字起こし",
|
|
1062
|
+
ariaLabel: "ビデオ文字起こし",
|
|
1030
1063
|
close: "文字起こしを閉じる",
|
|
1031
1064
|
loading: "文字起こしを読み込み中...",
|
|
1032
1065
|
noTranscript: "このビデオの文字起こしはありません。",
|
|
@@ -1093,7 +1126,14 @@
|
|
|
1093
1126
|
currentlyPlaying: "再生中",
|
|
1094
1127
|
notPlaying: "停止中",
|
|
1095
1128
|
pressEnterPlay: "Enterキーで再生",
|
|
1096
|
-
pressEnterRestart: "Enterキーで最初から再生"
|
|
1129
|
+
pressEnterRestart: "Enterキーで最初から再生",
|
|
1130
|
+
keyboardInstructions: "プレイリストナビゲーション:上下の矢印キーでトラック間を移動します。Page UpまたはPage Downで5トラックをスキップします。Homeで最初のトラックへ、Endで最後のトラックへ移動します。EnterまたはSpaceで選択したトラックを再生します。",
|
|
1131
|
+
endOfPlaylist: "プレイリストの終わりです。{current}/{total}。",
|
|
1132
|
+
beginningOfPlaylist: "プレイリストの始めです。1/{total}。",
|
|
1133
|
+
jumpedToLastTrack: "最後のトラックにジャンプしました。{current}/{total}。",
|
|
1134
|
+
jumpedToFirstTrack: "最初のトラックにジャンプしました。1/{total}。",
|
|
1135
|
+
firstTrack: "最初のトラックです。1/{total}。",
|
|
1136
|
+
lastTrack: "最後のトラックです。{current}/{total}。"
|
|
1097
1137
|
}
|
|
1098
1138
|
};
|
|
1099
1139
|
}
|
|
@@ -1647,6 +1687,9 @@
|
|
|
1647
1687
|
this.attachEvents();
|
|
1648
1688
|
this.media.preload = this.player.options.preload;
|
|
1649
1689
|
this.media.load();
|
|
1690
|
+
if (this.player.container) {
|
|
1691
|
+
this.player.container.classList.remove("vidply-external-controls");
|
|
1692
|
+
}
|
|
1650
1693
|
}
|
|
1651
1694
|
attachEvents() {
|
|
1652
1695
|
this.media.addEventListener("loadedmetadata", () => {
|
|
@@ -2821,7 +2864,7 @@
|
|
|
2821
2864
|
className: "".concat(this.player.options.classPrefix, "-transcript-window"),
|
|
2822
2865
|
attributes: {
|
|
2823
2866
|
"role": "dialog",
|
|
2824
|
-
"aria-label": "
|
|
2867
|
+
"aria-label": i18n.t("transcript.ariaLabel"),
|
|
2825
2868
|
"tabindex": "-1"
|
|
2826
2869
|
}
|
|
2827
2870
|
});
|
|
@@ -4417,7 +4460,8 @@
|
|
|
4417
4460
|
this.iframe = null;
|
|
4418
4461
|
}
|
|
4419
4462
|
async init() {
|
|
4420
|
-
|
|
4463
|
+
const src = this.player.currentSource || this.player.element.src;
|
|
4464
|
+
this.videoId = this.extractVideoId(src);
|
|
4421
4465
|
if (!this.videoId) {
|
|
4422
4466
|
throw new Error("Invalid YouTube URL");
|
|
4423
4467
|
}
|
|
@@ -4466,7 +4510,8 @@
|
|
|
4466
4510
|
this.iframe = document.createElement("div");
|
|
4467
4511
|
this.iframe.id = "youtube-player-".concat(Math.random().toString(36).substr(2, 9));
|
|
4468
4512
|
this.iframe.style.width = "100%";
|
|
4469
|
-
this.iframe.style.
|
|
4513
|
+
this.iframe.style.aspectRatio = "16 / 9";
|
|
4514
|
+
this.iframe.style.maxHeight = "100%";
|
|
4470
4515
|
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
4471
4516
|
}
|
|
4472
4517
|
async initializePlayer() {
|
|
@@ -4476,9 +4521,12 @@
|
|
|
4476
4521
|
width: "100%",
|
|
4477
4522
|
height: "100%",
|
|
4478
4523
|
playerVars: {
|
|
4479
|
-
controls:
|
|
4480
|
-
|
|
4481
|
-
|
|
4524
|
+
controls: 1,
|
|
4525
|
+
// Use YouTube native controls
|
|
4526
|
+
disablekb: 0,
|
|
4527
|
+
// Allow keyboard controls
|
|
4528
|
+
fs: 1,
|
|
4529
|
+
// Allow fullscreen
|
|
4482
4530
|
modestbranding: 1,
|
|
4483
4531
|
rel: 0,
|
|
4484
4532
|
showinfo: 0,
|
|
@@ -4491,6 +4539,9 @@
|
|
|
4491
4539
|
onReady: (event) => {
|
|
4492
4540
|
this.isReady = true;
|
|
4493
4541
|
this.attachEvents();
|
|
4542
|
+
if (this.player.container) {
|
|
4543
|
+
this.player.container.classList.add("vidply-external-controls");
|
|
4544
|
+
}
|
|
4494
4545
|
resolve();
|
|
4495
4546
|
},
|
|
4496
4547
|
onStateChange: (event) => this.handleStateChange(event),
|
|
@@ -4644,7 +4695,8 @@
|
|
|
4644
4695
|
this.iframe = null;
|
|
4645
4696
|
}
|
|
4646
4697
|
async init() {
|
|
4647
|
-
|
|
4698
|
+
const src = this.player.currentSource || this.player.element.src;
|
|
4699
|
+
this.videoId = this.extractVideoId(src);
|
|
4648
4700
|
if (!this.videoId) {
|
|
4649
4701
|
throw new Error("Invalid Vimeo URL");
|
|
4650
4702
|
}
|
|
@@ -4683,7 +4735,8 @@
|
|
|
4683
4735
|
this.iframe = document.createElement("div");
|
|
4684
4736
|
this.iframe.id = "vimeo-player-".concat(Math.random().toString(36).substr(2, 9));
|
|
4685
4737
|
this.iframe.style.width = "100%";
|
|
4686
|
-
this.iframe.style.
|
|
4738
|
+
this.iframe.style.aspectRatio = "16 / 9";
|
|
4739
|
+
this.iframe.style.maxHeight = "100%";
|
|
4687
4740
|
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
4688
4741
|
}
|
|
4689
4742
|
async initializePlayer() {
|
|
@@ -4691,7 +4744,8 @@
|
|
|
4691
4744
|
id: this.videoId,
|
|
4692
4745
|
width: "100%",
|
|
4693
4746
|
height: "100%",
|
|
4694
|
-
controls:
|
|
4747
|
+
controls: true,
|
|
4748
|
+
// Use Vimeo native controls
|
|
4695
4749
|
autoplay: this.player.options.autoplay,
|
|
4696
4750
|
muted: this.player.options.muted,
|
|
4697
4751
|
loop: this.player.options.loop,
|
|
@@ -4703,6 +4757,16 @@
|
|
|
4703
4757
|
this.vimeo = new window.Vimeo.Player(this.iframe.id, options);
|
|
4704
4758
|
await this.vimeo.ready();
|
|
4705
4759
|
this.isReady = true;
|
|
4760
|
+
const vimeoIframe = this.iframe.querySelector("iframe");
|
|
4761
|
+
if (vimeoIframe) {
|
|
4762
|
+
vimeoIframe.style.width = "100%";
|
|
4763
|
+
vimeoIframe.style.height = "100%";
|
|
4764
|
+
vimeoIframe.setAttribute("width", "100%");
|
|
4765
|
+
vimeoIframe.setAttribute("height", "100%");
|
|
4766
|
+
}
|
|
4767
|
+
if (this.player.container) {
|
|
4768
|
+
this.player.container.classList.add("vidply-external-controls");
|
|
4769
|
+
}
|
|
4706
4770
|
this.attachEvents();
|
|
4707
4771
|
try {
|
|
4708
4772
|
const duration = await this.vimeo.getDuration();
|
|
@@ -4915,12 +4979,14 @@
|
|
|
4915
4979
|
fragLoadingMaxRetryTimeout: 64e3
|
|
4916
4980
|
});
|
|
4917
4981
|
this.hls.attachMedia(this.media);
|
|
4918
|
-
let src;
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4982
|
+
let src = this.player.currentSource;
|
|
4983
|
+
if (!src) {
|
|
4984
|
+
const sourceElement = this.player.element.querySelector("source");
|
|
4985
|
+
if (sourceElement) {
|
|
4986
|
+
src = sourceElement.getAttribute("src");
|
|
4987
|
+
} else {
|
|
4988
|
+
src = this.player.element.getAttribute("src") || this.player.element.src;
|
|
4989
|
+
}
|
|
4924
4990
|
}
|
|
4925
4991
|
this.player.log("Loading HLS source: ".concat(src), "log");
|
|
4926
4992
|
if (!src) {
|
|
@@ -4943,6 +5009,9 @@
|
|
|
4943
5009
|
this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {
|
|
4944
5010
|
this.player.log("HLS manifest loaded, found " + data.levels.length + " quality levels");
|
|
4945
5011
|
this.player.emit("hlsmanifestparsed", data);
|
|
5012
|
+
if (this.player.container) {
|
|
5013
|
+
this.player.container.classList.remove("vidply-external-controls");
|
|
5014
|
+
}
|
|
4946
5015
|
});
|
|
4947
5016
|
this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {
|
|
4948
5017
|
this.player.log("HLS level switched to " + data.level);
|
|
@@ -5101,6 +5170,287 @@
|
|
|
5101
5170
|
}
|
|
5102
5171
|
});
|
|
5103
5172
|
|
|
5173
|
+
// src/renderers/SoundCloudRenderer.js
|
|
5174
|
+
var SoundCloudRenderer_exports = {};
|
|
5175
|
+
__export(SoundCloudRenderer_exports, {
|
|
5176
|
+
SoundCloudRenderer: () => SoundCloudRenderer,
|
|
5177
|
+
default: () => SoundCloudRenderer_default
|
|
5178
|
+
});
|
|
5179
|
+
var SoundCloudRenderer, SoundCloudRenderer_default;
|
|
5180
|
+
var init_SoundCloudRenderer = __esm({
|
|
5181
|
+
"src/renderers/SoundCloudRenderer.js"() {
|
|
5182
|
+
SoundCloudRenderer = class {
|
|
5183
|
+
constructor(player) {
|
|
5184
|
+
this.player = player;
|
|
5185
|
+
this.widget = null;
|
|
5186
|
+
this.trackUrl = null;
|
|
5187
|
+
this.isReady = false;
|
|
5188
|
+
this.iframe = null;
|
|
5189
|
+
this.iframeId = null;
|
|
5190
|
+
}
|
|
5191
|
+
async init() {
|
|
5192
|
+
var _a;
|
|
5193
|
+
this.trackUrl = this.player.currentSource || this.player.element.src || ((_a = this.player.element.querySelector("source")) == null ? void 0 : _a.src);
|
|
5194
|
+
if (!this.trackUrl || !this.isValidSoundCloudUrl(this.trackUrl)) {
|
|
5195
|
+
throw new Error("Invalid SoundCloud URL");
|
|
5196
|
+
}
|
|
5197
|
+
await this.loadSoundCloudAPI();
|
|
5198
|
+
this.createIframe();
|
|
5199
|
+
await this.initializeWidget();
|
|
5200
|
+
}
|
|
5201
|
+
/**
|
|
5202
|
+
* Validate SoundCloud URL
|
|
5203
|
+
* @param {string} url
|
|
5204
|
+
* @returns {boolean}
|
|
5205
|
+
*/
|
|
5206
|
+
isValidSoundCloudUrl(url) {
|
|
5207
|
+
return url.includes("soundcloud.com") || url.includes("api.soundcloud.com");
|
|
5208
|
+
}
|
|
5209
|
+
/**
|
|
5210
|
+
* Check if URL is a playlist/set
|
|
5211
|
+
*/
|
|
5212
|
+
isPlaylist() {
|
|
5213
|
+
return this.trackUrl && this.trackUrl.includes("/sets/");
|
|
5214
|
+
}
|
|
5215
|
+
/**
|
|
5216
|
+
* Extract track/playlist info from URL for embed
|
|
5217
|
+
* SoundCloud URLs can be:
|
|
5218
|
+
* - https://soundcloud.com/artist/track
|
|
5219
|
+
* - https://soundcloud.com/artist/sets/playlist
|
|
5220
|
+
* - https://api.soundcloud.com/tracks/123456
|
|
5221
|
+
*/
|
|
5222
|
+
getEmbedUrl() {
|
|
5223
|
+
const encodedUrl = encodeURIComponent(this.trackUrl);
|
|
5224
|
+
const params = new URLSearchParams({
|
|
5225
|
+
url: this.trackUrl,
|
|
5226
|
+
auto_play: this.player.options.autoplay ? "true" : "false",
|
|
5227
|
+
hide_related: "true",
|
|
5228
|
+
show_comments: "false",
|
|
5229
|
+
show_user: "true",
|
|
5230
|
+
show_reposts: "false",
|
|
5231
|
+
show_teaser: "false",
|
|
5232
|
+
visual: "false",
|
|
5233
|
+
// Use classic player for better control
|
|
5234
|
+
color: "%23007bff"
|
|
5235
|
+
});
|
|
5236
|
+
return "https://w.soundcloud.com/player/?".concat(params.toString());
|
|
5237
|
+
}
|
|
5238
|
+
async loadSoundCloudAPI() {
|
|
5239
|
+
if (window.SC && window.SC.Widget) {
|
|
5240
|
+
return Promise.resolve();
|
|
5241
|
+
}
|
|
5242
|
+
return new Promise((resolve, reject) => {
|
|
5243
|
+
const script = document.createElement("script");
|
|
5244
|
+
script.src = "https://w.soundcloud.com/player/api.js";
|
|
5245
|
+
script.onload = () => {
|
|
5246
|
+
setTimeout(() => {
|
|
5247
|
+
if (window.SC && window.SC.Widget) {
|
|
5248
|
+
resolve();
|
|
5249
|
+
} else {
|
|
5250
|
+
reject(new Error("SoundCloud Widget API not available"));
|
|
5251
|
+
}
|
|
5252
|
+
}, 100);
|
|
5253
|
+
};
|
|
5254
|
+
script.onerror = () => reject(new Error("Failed to load SoundCloud Widget API"));
|
|
5255
|
+
document.head.appendChild(script);
|
|
5256
|
+
});
|
|
5257
|
+
}
|
|
5258
|
+
createIframe() {
|
|
5259
|
+
this.player.element.style.display = "none";
|
|
5260
|
+
this.player.element.removeAttribute("poster");
|
|
5261
|
+
if (this.player.videoWrapper) {
|
|
5262
|
+
this.player.videoWrapper.classList.remove("vidply-forced-poster");
|
|
5263
|
+
this.player.videoWrapper.style.removeProperty("--vidply-poster-image");
|
|
5264
|
+
}
|
|
5265
|
+
this.iframeId = "soundcloud-player-".concat(Math.random().toString(36).substr(2, 9));
|
|
5266
|
+
this.iframe = document.createElement("iframe");
|
|
5267
|
+
this.iframe.id = this.iframeId;
|
|
5268
|
+
this.iframe.scrolling = "no";
|
|
5269
|
+
this.iframe.frameBorder = "no";
|
|
5270
|
+
this.iframe.allow = "autoplay";
|
|
5271
|
+
this.iframe.src = this.getEmbedUrl();
|
|
5272
|
+
this.iframe.style.width = "100%";
|
|
5273
|
+
this.iframe.style.display = "block";
|
|
5274
|
+
if (this.isPlaylist()) {
|
|
5275
|
+
this.iframe.style.aspectRatio = "16 / 9";
|
|
5276
|
+
this.iframe.classList.add("vidply-soundcloud-iframe", "vidply-soundcloud-playlist");
|
|
5277
|
+
} else {
|
|
5278
|
+
this.iframe.style.aspectRatio = "16 / 3";
|
|
5279
|
+
this.iframe.classList.add("vidply-soundcloud-iframe");
|
|
5280
|
+
}
|
|
5281
|
+
this.iframe.style.maxHeight = "100%";
|
|
5282
|
+
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
5283
|
+
}
|
|
5284
|
+
async initializeWidget() {
|
|
5285
|
+
return new Promise((resolve, reject) => {
|
|
5286
|
+
this.iframe.addEventListener("load", () => {
|
|
5287
|
+
try {
|
|
5288
|
+
this.widget = window.SC.Widget(this.iframe);
|
|
5289
|
+
this.widget.bind(window.SC.Widget.Events.READY, () => {
|
|
5290
|
+
this.isReady = true;
|
|
5291
|
+
this.attachEvents();
|
|
5292
|
+
if (this.player.container) {
|
|
5293
|
+
this.player.container.classList.add("vidply-external-controls");
|
|
5294
|
+
}
|
|
5295
|
+
this.widget.getCurrentSound((sound) => {
|
|
5296
|
+
if (sound) {
|
|
5297
|
+
this.player.state.duration = sound.duration / 1e3;
|
|
5298
|
+
this.player.emit("loadedmetadata");
|
|
5299
|
+
}
|
|
5300
|
+
});
|
|
5301
|
+
resolve();
|
|
5302
|
+
});
|
|
5303
|
+
this.widget.bind(window.SC.Widget.Events.ERROR, (error) => {
|
|
5304
|
+
this.player.handleError(new Error("SoundCloud error: ".concat(error.message || "Unknown error")));
|
|
5305
|
+
});
|
|
5306
|
+
} catch (error) {
|
|
5307
|
+
reject(error);
|
|
5308
|
+
}
|
|
5309
|
+
});
|
|
5310
|
+
setTimeout(() => {
|
|
5311
|
+
if (!this.isReady) {
|
|
5312
|
+
reject(new Error("SoundCloud widget initialization timeout"));
|
|
5313
|
+
}
|
|
5314
|
+
}, 1e4);
|
|
5315
|
+
});
|
|
5316
|
+
}
|
|
5317
|
+
attachEvents() {
|
|
5318
|
+
if (!this.widget) return;
|
|
5319
|
+
const Events = window.SC.Widget.Events;
|
|
5320
|
+
this.widget.bind(Events.PLAY, () => {
|
|
5321
|
+
this.player.state.playing = true;
|
|
5322
|
+
this.player.state.paused = false;
|
|
5323
|
+
this.player.state.ended = false;
|
|
5324
|
+
this.player.emit("play");
|
|
5325
|
+
if (this.player.options.onPlay) {
|
|
5326
|
+
this.player.options.onPlay.call(this.player);
|
|
5327
|
+
}
|
|
5328
|
+
});
|
|
5329
|
+
this.widget.bind(Events.PAUSE, () => {
|
|
5330
|
+
this.player.state.playing = false;
|
|
5331
|
+
this.player.state.paused = true;
|
|
5332
|
+
this.player.emit("pause");
|
|
5333
|
+
if (this.player.options.onPause) {
|
|
5334
|
+
this.player.options.onPause.call(this.player);
|
|
5335
|
+
}
|
|
5336
|
+
});
|
|
5337
|
+
this.widget.bind(Events.FINISH, () => {
|
|
5338
|
+
this.player.state.playing = false;
|
|
5339
|
+
this.player.state.paused = true;
|
|
5340
|
+
this.player.state.ended = true;
|
|
5341
|
+
this.player.emit("ended");
|
|
5342
|
+
if (this.player.options.onEnded) {
|
|
5343
|
+
this.player.options.onEnded.call(this.player);
|
|
5344
|
+
}
|
|
5345
|
+
if (this.player.options.loop) {
|
|
5346
|
+
this.seek(0);
|
|
5347
|
+
this.play();
|
|
5348
|
+
}
|
|
5349
|
+
});
|
|
5350
|
+
this.widget.bind(Events.PLAY_PROGRESS, (data) => {
|
|
5351
|
+
const currentTime = data.currentPosition / 1e3;
|
|
5352
|
+
this.player.state.currentTime = currentTime;
|
|
5353
|
+
this.player.emit("timeupdate", currentTime);
|
|
5354
|
+
if (this.player.options.onTimeUpdate) {
|
|
5355
|
+
this.player.options.onTimeUpdate.call(this.player, currentTime);
|
|
5356
|
+
}
|
|
5357
|
+
});
|
|
5358
|
+
this.widget.bind(Events.SEEK, (data) => {
|
|
5359
|
+
this.player.state.currentTime = data.currentPosition / 1e3;
|
|
5360
|
+
this.player.emit("seeked");
|
|
5361
|
+
});
|
|
5362
|
+
this.widget.bind(Events.LOAD_PROGRESS, (data) => {
|
|
5363
|
+
if (this.player.state.duration) {
|
|
5364
|
+
const buffered = data.loadedProgress * this.player.state.duration;
|
|
5365
|
+
this.player.emit("progress", buffered);
|
|
5366
|
+
}
|
|
5367
|
+
});
|
|
5368
|
+
}
|
|
5369
|
+
play() {
|
|
5370
|
+
if (this.isReady && this.widget) {
|
|
5371
|
+
const scrollX = window.scrollX;
|
|
5372
|
+
const scrollY = window.scrollY;
|
|
5373
|
+
this.widget.play();
|
|
5374
|
+
window.scrollTo(scrollX, scrollY);
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
pause() {
|
|
5378
|
+
if (this.isReady && this.widget) {
|
|
5379
|
+
this.widget.pause();
|
|
5380
|
+
}
|
|
5381
|
+
}
|
|
5382
|
+
seek(time) {
|
|
5383
|
+
if (this.isReady && this.widget) {
|
|
5384
|
+
this.widget.seekTo(time * 1e3);
|
|
5385
|
+
this.player.state.currentTime = time;
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
setVolume(volume) {
|
|
5389
|
+
if (this.isReady && this.widget) {
|
|
5390
|
+
this.widget.setVolume(volume * 100);
|
|
5391
|
+
this.player.state.volume = volume;
|
|
5392
|
+
}
|
|
5393
|
+
}
|
|
5394
|
+
setMuted(muted) {
|
|
5395
|
+
if (this.isReady && this.widget) {
|
|
5396
|
+
if (muted) {
|
|
5397
|
+
this.widget.getVolume((vol) => {
|
|
5398
|
+
this._previousVolume = vol;
|
|
5399
|
+
this.widget.setVolume(0);
|
|
5400
|
+
});
|
|
5401
|
+
} else {
|
|
5402
|
+
this.widget.setVolume(this._previousVolume || 100);
|
|
5403
|
+
}
|
|
5404
|
+
this.player.state.muted = muted;
|
|
5405
|
+
}
|
|
5406
|
+
}
|
|
5407
|
+
setPlaybackSpeed(speed) {
|
|
5408
|
+
this.player.log("SoundCloud does not support playback speed control", "warn");
|
|
5409
|
+
}
|
|
5410
|
+
/**
|
|
5411
|
+
* Get current track info
|
|
5412
|
+
* @returns {Promise<Object>}
|
|
5413
|
+
*/
|
|
5414
|
+
getCurrentSound() {
|
|
5415
|
+
return new Promise((resolve) => {
|
|
5416
|
+
if (this.isReady && this.widget) {
|
|
5417
|
+
this.widget.getCurrentSound((sound) => {
|
|
5418
|
+
resolve(sound);
|
|
5419
|
+
});
|
|
5420
|
+
} else {
|
|
5421
|
+
resolve(null);
|
|
5422
|
+
}
|
|
5423
|
+
});
|
|
5424
|
+
}
|
|
5425
|
+
destroy() {
|
|
5426
|
+
if (this.widget) {
|
|
5427
|
+
const Events = window.SC.Widget.Events;
|
|
5428
|
+
try {
|
|
5429
|
+
this.widget.unbind(Events.READY);
|
|
5430
|
+
this.widget.unbind(Events.PLAY);
|
|
5431
|
+
this.widget.unbind(Events.PAUSE);
|
|
5432
|
+
this.widget.unbind(Events.FINISH);
|
|
5433
|
+
this.widget.unbind(Events.PLAY_PROGRESS);
|
|
5434
|
+
this.widget.unbind(Events.SEEK);
|
|
5435
|
+
this.widget.unbind(Events.LOAD_PROGRESS);
|
|
5436
|
+
this.widget.unbind(Events.ERROR);
|
|
5437
|
+
} catch (e) {
|
|
5438
|
+
}
|
|
5439
|
+
}
|
|
5440
|
+
if (this.iframe && this.iframe.parentNode) {
|
|
5441
|
+
this.iframe.parentNode.removeChild(this.iframe);
|
|
5442
|
+
}
|
|
5443
|
+
if (this.player.element) {
|
|
5444
|
+
this.player.element.style.display = "";
|
|
5445
|
+
}
|
|
5446
|
+
this.widget = null;
|
|
5447
|
+
this.isReady = false;
|
|
5448
|
+
}
|
|
5449
|
+
};
|
|
5450
|
+
SoundCloudRenderer_default = SoundCloudRenderer;
|
|
5451
|
+
}
|
|
5452
|
+
});
|
|
5453
|
+
|
|
5104
5454
|
// src/utils/EventEmitter.js
|
|
5105
5455
|
var EventEmitter = class {
|
|
5106
5456
|
constructor() {
|
|
@@ -8180,6 +8530,7 @@
|
|
|
8180
8530
|
this.element.appendChild(mediaElement);
|
|
8181
8531
|
this.element = mediaElement;
|
|
8182
8532
|
}
|
|
8533
|
+
this._originalElement = this.element;
|
|
8183
8534
|
this.options = __spreadValues({
|
|
8184
8535
|
// Display
|
|
8185
8536
|
width: null,
|
|
@@ -8594,10 +8945,12 @@
|
|
|
8594
8945
|
}
|
|
8595
8946
|
async initializeRenderer() {
|
|
8596
8947
|
var _a;
|
|
8597
|
-
|
|
8948
|
+
let src = this._pendingSource || this.element.src || ((_a = this.element.querySelector("source")) == null ? void 0 : _a.src);
|
|
8598
8949
|
if (!src) {
|
|
8599
8950
|
throw new Error("No media source found");
|
|
8600
8951
|
}
|
|
8952
|
+
this.currentSource = src;
|
|
8953
|
+
this._pendingSource = null;
|
|
8601
8954
|
const sourceElements = this.sourceElements;
|
|
8602
8955
|
for (const sourceEl of sourceElements) {
|
|
8603
8956
|
const descSrc = sourceEl.getAttribute("data-desc-src");
|
|
@@ -8658,6 +9011,9 @@
|
|
|
8658
9011
|
} else if (src.includes(".m3u8")) {
|
|
8659
9012
|
const module = await Promise.resolve().then(() => (init_HLSRenderer(), HLSRenderer_exports));
|
|
8660
9013
|
rendererClass = module.HLSRenderer || module.default;
|
|
9014
|
+
} else if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
|
|
9015
|
+
const module = await Promise.resolve().then(() => (init_SoundCloudRenderer(), SoundCloudRenderer_exports));
|
|
9016
|
+
rendererClass = module.SoundCloudRenderer || module.default;
|
|
8661
9017
|
}
|
|
8662
9018
|
this.log("Using ".concat((rendererClass == null ? void 0 : rendererClass.name) || "HTML5Renderer", " renderer"));
|
|
8663
9019
|
this.renderer = new rendererClass(this);
|
|
@@ -8769,6 +9125,11 @@
|
|
|
8769
9125
|
const resolvedPoster = this.resolvePosterPath(poster);
|
|
8770
9126
|
this.videoWrapper.style.setProperty("--vidply-poster-image", 'url("'.concat(resolvedPoster, '")'));
|
|
8771
9127
|
this.videoWrapper.classList.add("vidply-forced-poster");
|
|
9128
|
+
if (this._isAudioContent && this.container) {
|
|
9129
|
+
this.container.classList.add("vidply-audio-content");
|
|
9130
|
+
} else if (this.container) {
|
|
9131
|
+
this.container.classList.remove("vidply-audio-content");
|
|
9132
|
+
}
|
|
8772
9133
|
}
|
|
8773
9134
|
hidePosterOverlay() {
|
|
8774
9135
|
if (!this.videoWrapper) {
|
|
@@ -8811,6 +9172,15 @@
|
|
|
8811
9172
|
* @param {string} [config.audioDescriptionSrc] - Audio description video URL
|
|
8812
9173
|
* @param {string} [config.signLanguageSrc] - Sign language video URL
|
|
8813
9174
|
*/
|
|
9175
|
+
/**
|
|
9176
|
+
* Check if a source URL requires an external renderer (YouTube, Vimeo, SoundCloud, HLS)
|
|
9177
|
+
* @param {string} src - Source URL
|
|
9178
|
+
* @returns {boolean}
|
|
9179
|
+
*/
|
|
9180
|
+
isExternalRendererUrl(src) {
|
|
9181
|
+
if (!src) return false;
|
|
9182
|
+
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");
|
|
9183
|
+
}
|
|
8814
9184
|
async load(config) {
|
|
8815
9185
|
var _a;
|
|
8816
9186
|
try {
|
|
@@ -8823,12 +9193,44 @@
|
|
|
8823
9193
|
const existingTracks = this.trackElements;
|
|
8824
9194
|
existingTracks.forEach((track) => track.remove());
|
|
8825
9195
|
this.invalidateTrackCache();
|
|
8826
|
-
|
|
8827
|
-
if (
|
|
8828
|
-
this.
|
|
9196
|
+
const isExternalRenderer = this.isExternalRendererUrl(config.src);
|
|
9197
|
+
if (isExternalRenderer) {
|
|
9198
|
+
this._switchingRenderer = true;
|
|
9199
|
+
}
|
|
9200
|
+
if (!isExternalRenderer) {
|
|
9201
|
+
this.element.src = config.src;
|
|
9202
|
+
if (config.type) {
|
|
9203
|
+
this.element.type = config.type;
|
|
9204
|
+
}
|
|
9205
|
+
} else {
|
|
9206
|
+
this.element.removeAttribute("src");
|
|
9207
|
+
const sources = this.element.querySelectorAll("source");
|
|
9208
|
+
sources.forEach((s) => s.removeAttribute("src"));
|
|
9209
|
+
}
|
|
9210
|
+
this._pendingSource = config.src;
|
|
9211
|
+
this._isAudioContent = config.type && config.type.startsWith("audio/");
|
|
9212
|
+
if (this.container) {
|
|
9213
|
+
if (this._isAudioContent) {
|
|
9214
|
+
this.container.classList.add("vidply-audio-content");
|
|
9215
|
+
} else {
|
|
9216
|
+
this.container.classList.remove("vidply-audio-content");
|
|
9217
|
+
}
|
|
8829
9218
|
}
|
|
8830
9219
|
if (config.poster && this.element.tagName === "VIDEO") {
|
|
8831
|
-
|
|
9220
|
+
if (this._isAudioContent) {
|
|
9221
|
+
this.element.removeAttribute("poster");
|
|
9222
|
+
if (this.videoWrapper) {
|
|
9223
|
+
const resolvedPoster = this.resolvePosterPath(config.poster);
|
|
9224
|
+
this.videoWrapper.style.setProperty("--vidply-poster-image", 'url("'.concat(resolvedPoster, '")'));
|
|
9225
|
+
this.videoWrapper.classList.add("vidply-forced-poster");
|
|
9226
|
+
}
|
|
9227
|
+
} else {
|
|
9228
|
+
this.element.poster = this.resolvePosterPath(config.poster);
|
|
9229
|
+
if (this.videoWrapper) {
|
|
9230
|
+
this.videoWrapper.classList.remove("vidply-forced-poster");
|
|
9231
|
+
this.videoWrapper.style.removeProperty("--vidply-poster-image");
|
|
9232
|
+
}
|
|
9233
|
+
}
|
|
8832
9234
|
}
|
|
8833
9235
|
if (config.tracks && config.tracks.length > 0) {
|
|
8834
9236
|
config.tracks.forEach((trackConfig) => {
|
|
@@ -8871,6 +9273,13 @@
|
|
|
8871
9273
|
this.renderer.media = this.element;
|
|
8872
9274
|
this.element.load();
|
|
8873
9275
|
}
|
|
9276
|
+
if (isExternalRenderer) {
|
|
9277
|
+
setTimeout(() => {
|
|
9278
|
+
this._switchingRenderer = false;
|
|
9279
|
+
}, 500);
|
|
9280
|
+
} else {
|
|
9281
|
+
this._switchingRenderer = false;
|
|
9282
|
+
}
|
|
8874
9283
|
window.scrollTo(scrollX, scrollY);
|
|
8875
9284
|
if (this.captionManager) {
|
|
8876
9285
|
this.captionManager.destroy();
|
|
@@ -8929,11 +9338,13 @@
|
|
|
8929
9338
|
const isYouTube = src.includes("youtube.com") || src.includes("youtu.be");
|
|
8930
9339
|
const isVimeo = src.includes("vimeo.com");
|
|
8931
9340
|
const isHLS = src.includes(".m3u8");
|
|
9341
|
+
const isSoundCloud = src.includes("soundcloud.com") || src.includes("api.soundcloud.com");
|
|
8932
9342
|
const currentRendererName = this.renderer.constructor.name;
|
|
8933
9343
|
if (isYouTube && currentRendererName !== "YouTubeRenderer") return true;
|
|
8934
9344
|
if (isVimeo && currentRendererName !== "VimeoRenderer") return true;
|
|
8935
9345
|
if (isHLS && currentRendererName !== "HLSRenderer") return true;
|
|
8936
|
-
if (
|
|
9346
|
+
if (isSoundCloud && currentRendererName !== "SoundCloudRenderer") return true;
|
|
9347
|
+
if (!isYouTube && !isVimeo && !isHLS && !isSoundCloud && currentRendererName !== "HTML5Renderer") return true;
|
|
8937
9348
|
return false;
|
|
8938
9349
|
}
|
|
8939
9350
|
// Playback controls
|
|
@@ -11148,6 +11559,10 @@
|
|
|
11148
11559
|
}
|
|
11149
11560
|
// Error handling
|
|
11150
11561
|
handleError(error) {
|
|
11562
|
+
if (this._switchingRenderer) {
|
|
11563
|
+
this.log("Suppressing error during renderer switch:", error, "debug");
|
|
11564
|
+
return;
|
|
11565
|
+
}
|
|
11151
11566
|
this.log("Error:", error, "error");
|
|
11152
11567
|
this.emit("error", error);
|
|
11153
11568
|
if (this.options.onError) {
|
|
@@ -11691,7 +12106,9 @@
|
|
|
11691
12106
|
autoPlayFirst: options.autoPlayFirst !== false,
|
|
11692
12107
|
// Default true - auto-play first track on load
|
|
11693
12108
|
loop: options.loop || false,
|
|
11694
|
-
showPanel: options.showPanel !== false
|
|
12109
|
+
showPanel: options.showPanel !== false,
|
|
12110
|
+
// Default true
|
|
12111
|
+
recreatePlayers: options.recreatePlayers || false
|
|
11695
12112
|
}, options);
|
|
11696
12113
|
this.container = null;
|
|
11697
12114
|
this.playlistPanel = null;
|
|
@@ -11699,6 +12116,8 @@
|
|
|
11699
12116
|
this.navigationFeedback = null;
|
|
11700
12117
|
this.isPanelVisible = this.options.showPanel !== false;
|
|
11701
12118
|
this.isChangingTrack = false;
|
|
12119
|
+
this.hostElement = options.hostElement || null;
|
|
12120
|
+
this.PlayerClass = options.PlayerClass || null;
|
|
11702
12121
|
this.handleTrackEnd = this.handleTrackEnd.bind(this);
|
|
11703
12122
|
this.handleTrackError = this.handleTrackError.bind(this);
|
|
11704
12123
|
this.player.playlistManager = this;
|
|
@@ -11708,6 +12127,159 @@
|
|
|
11708
12127
|
this.loadPlaylist(this.initialTracks);
|
|
11709
12128
|
}
|
|
11710
12129
|
}
|
|
12130
|
+
/**
|
|
12131
|
+
* Determine the media type for a track
|
|
12132
|
+
* @param {Object} track - Track object
|
|
12133
|
+
* @returns {string} - 'audio', 'video', 'youtube', 'vimeo', 'soundcloud', 'hls'
|
|
12134
|
+
*/
|
|
12135
|
+
getTrackMediaType(track) {
|
|
12136
|
+
const src = track.src || "";
|
|
12137
|
+
if (src.includes("youtube.com") || src.includes("youtu.be")) {
|
|
12138
|
+
return "youtube";
|
|
12139
|
+
}
|
|
12140
|
+
if (src.includes("vimeo.com")) {
|
|
12141
|
+
return "vimeo";
|
|
12142
|
+
}
|
|
12143
|
+
if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
|
|
12144
|
+
return "soundcloud";
|
|
12145
|
+
}
|
|
12146
|
+
if (src.includes(".m3u8")) {
|
|
12147
|
+
return "hls";
|
|
12148
|
+
}
|
|
12149
|
+
if (track.type && track.type.startsWith("audio/")) {
|
|
12150
|
+
return "audio";
|
|
12151
|
+
}
|
|
12152
|
+
return "video";
|
|
12153
|
+
}
|
|
12154
|
+
/**
|
|
12155
|
+
* Recreate the player with the appropriate element type for the track
|
|
12156
|
+
* @param {Object} track - Track to load
|
|
12157
|
+
* @param {boolean} autoPlay - Whether to auto-play after creation
|
|
12158
|
+
*/
|
|
12159
|
+
async recreatePlayerForTrack(track, autoPlay = false) {
|
|
12160
|
+
if (!this.hostElement || !this.PlayerClass) {
|
|
12161
|
+
console.warn("VidPly Playlist: Cannot recreate player - missing hostElement or PlayerClass");
|
|
12162
|
+
return false;
|
|
12163
|
+
}
|
|
12164
|
+
const mediaType = this.getTrackMediaType(track);
|
|
12165
|
+
const elementType = mediaType === "audio" ? "audio" : "video";
|
|
12166
|
+
const wasVisible = this.isPanelVisible;
|
|
12167
|
+
const savedTracks = [...this.tracks];
|
|
12168
|
+
const savedIndex = this.currentIndex;
|
|
12169
|
+
if (this.trackArtworkElement && this.trackArtworkElement.parentNode) {
|
|
12170
|
+
this.trackArtworkElement.parentNode.removeChild(this.trackArtworkElement);
|
|
12171
|
+
}
|
|
12172
|
+
if (this.trackInfoElement && this.trackInfoElement.parentNode) {
|
|
12173
|
+
this.trackInfoElement.parentNode.removeChild(this.trackInfoElement);
|
|
12174
|
+
}
|
|
12175
|
+
if (this.navigationFeedback && this.navigationFeedback.parentNode) {
|
|
12176
|
+
this.navigationFeedback.parentNode.removeChild(this.navigationFeedback);
|
|
12177
|
+
}
|
|
12178
|
+
if (this.playlistPanel && this.playlistPanel.parentNode) {
|
|
12179
|
+
this.playlistPanel.parentNode.removeChild(this.playlistPanel);
|
|
12180
|
+
}
|
|
12181
|
+
if (this.player) {
|
|
12182
|
+
this.player.off("ended", this.handleTrackEnd);
|
|
12183
|
+
this.player.off("error", this.handleTrackError);
|
|
12184
|
+
this.player.destroy();
|
|
12185
|
+
}
|
|
12186
|
+
this.hostElement.innerHTML = "";
|
|
12187
|
+
const mediaElement = document.createElement(elementType);
|
|
12188
|
+
mediaElement.setAttribute("preload", "metadata");
|
|
12189
|
+
if (elementType === "video" && track.poster && (mediaType === "video" || mediaType === "hls")) {
|
|
12190
|
+
mediaElement.setAttribute("poster", track.poster);
|
|
12191
|
+
}
|
|
12192
|
+
const isExternalRenderer = ["youtube", "vimeo", "soundcloud", "hls"].includes(mediaType);
|
|
12193
|
+
if (!isExternalRenderer) {
|
|
12194
|
+
const source = document.createElement("source");
|
|
12195
|
+
source.src = track.src;
|
|
12196
|
+
if (track.type) {
|
|
12197
|
+
source.type = track.type;
|
|
12198
|
+
}
|
|
12199
|
+
mediaElement.appendChild(source);
|
|
12200
|
+
if (track.tracks && track.tracks.length > 0) {
|
|
12201
|
+
track.tracks.forEach((trackConfig) => {
|
|
12202
|
+
const trackEl = document.createElement("track");
|
|
12203
|
+
trackEl.src = trackConfig.src;
|
|
12204
|
+
trackEl.kind = trackConfig.kind || "captions";
|
|
12205
|
+
trackEl.srclang = trackConfig.srclang || "en";
|
|
12206
|
+
trackEl.label = trackConfig.label || trackConfig.srclang;
|
|
12207
|
+
if (trackConfig.default) {
|
|
12208
|
+
trackEl.default = true;
|
|
12209
|
+
}
|
|
12210
|
+
mediaElement.appendChild(trackEl);
|
|
12211
|
+
});
|
|
12212
|
+
}
|
|
12213
|
+
}
|
|
12214
|
+
this.hostElement.appendChild(mediaElement);
|
|
12215
|
+
const playerOptions = {
|
|
12216
|
+
mediaType: elementType,
|
|
12217
|
+
poster: track.poster,
|
|
12218
|
+
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
12219
|
+
audioDescriptionDuration: track.audioDescriptionDuration || null,
|
|
12220
|
+
signLanguageSrc: track.signLanguageSrc || null
|
|
12221
|
+
};
|
|
12222
|
+
this.player = new this.PlayerClass(mediaElement, playerOptions);
|
|
12223
|
+
this.player.playlistManager = this;
|
|
12224
|
+
await new Promise((resolve) => {
|
|
12225
|
+
this.player.on("ready", resolve);
|
|
12226
|
+
});
|
|
12227
|
+
this.player.on("ended", this.handleTrackEnd);
|
|
12228
|
+
this.player.on("error", this.handleTrackError);
|
|
12229
|
+
if (this.player.container) {
|
|
12230
|
+
if (this.trackArtworkElement) {
|
|
12231
|
+
const videoWrapper = this.player.container.querySelector(".vidply-video-wrapper");
|
|
12232
|
+
if (videoWrapper) {
|
|
12233
|
+
this.player.container.insertBefore(this.trackArtworkElement, videoWrapper);
|
|
12234
|
+
} else {
|
|
12235
|
+
this.player.container.appendChild(this.trackArtworkElement);
|
|
12236
|
+
}
|
|
12237
|
+
}
|
|
12238
|
+
if (this.trackInfoElement) {
|
|
12239
|
+
this.player.container.appendChild(this.trackInfoElement);
|
|
12240
|
+
}
|
|
12241
|
+
if (this.navigationFeedback) {
|
|
12242
|
+
this.player.container.appendChild(this.navigationFeedback);
|
|
12243
|
+
}
|
|
12244
|
+
if (this.playlistPanel) {
|
|
12245
|
+
this.player.container.appendChild(this.playlistPanel);
|
|
12246
|
+
}
|
|
12247
|
+
}
|
|
12248
|
+
this.container = this.player.container;
|
|
12249
|
+
this.updatePlayerControls();
|
|
12250
|
+
this.tracks = savedTracks;
|
|
12251
|
+
this.currentIndex = savedIndex;
|
|
12252
|
+
this.updatePlaylistUI();
|
|
12253
|
+
this.isPanelVisible = wasVisible;
|
|
12254
|
+
if (this.playlistPanel) {
|
|
12255
|
+
this.playlistPanel.style.display = wasVisible ? "" : "none";
|
|
12256
|
+
}
|
|
12257
|
+
if (isExternalRenderer) {
|
|
12258
|
+
this.player.load({
|
|
12259
|
+
src: track.src,
|
|
12260
|
+
type: track.type,
|
|
12261
|
+
poster: track.poster,
|
|
12262
|
+
tracks: track.tracks || [],
|
|
12263
|
+
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
12264
|
+
signLanguageSrc: track.signLanguageSrc || null
|
|
12265
|
+
});
|
|
12266
|
+
} else {
|
|
12267
|
+
this.player.load({
|
|
12268
|
+
src: track.src,
|
|
12269
|
+
type: track.type,
|
|
12270
|
+
poster: track.poster,
|
|
12271
|
+
tracks: track.tracks || [],
|
|
12272
|
+
audioDescriptionSrc: track.audioDescriptionSrc || null,
|
|
12273
|
+
signLanguageSrc: track.signLanguageSrc || null
|
|
12274
|
+
});
|
|
12275
|
+
}
|
|
12276
|
+
if (autoPlay) {
|
|
12277
|
+
setTimeout(() => {
|
|
12278
|
+
this.player.play();
|
|
12279
|
+
}, 100);
|
|
12280
|
+
}
|
|
12281
|
+
return true;
|
|
12282
|
+
}
|
|
11711
12283
|
init() {
|
|
11712
12284
|
this.player.on("ended", this.handleTrackEnd);
|
|
11713
12285
|
this.player.on("error", this.handleTrackError);
|
|
@@ -11818,7 +12390,7 @@
|
|
|
11818
12390
|
* Load a track without playing
|
|
11819
12391
|
* @param {number} index - Track index
|
|
11820
12392
|
*/
|
|
11821
|
-
loadTrack(index) {
|
|
12393
|
+
async loadTrack(index) {
|
|
11822
12394
|
if (index < 0 || index >= this.tracks.length) {
|
|
11823
12395
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
11824
12396
|
return;
|
|
@@ -11826,6 +12398,25 @@
|
|
|
11826
12398
|
const track = this.tracks[index];
|
|
11827
12399
|
this.isChangingTrack = true;
|
|
11828
12400
|
this.currentIndex = index;
|
|
12401
|
+
if (this.options.recreatePlayers && this.hostElement && this.PlayerClass) {
|
|
12402
|
+
const currentMediaType = this.player ? this.player.element.tagName === "AUDIO" ? "audio" : "video" : null;
|
|
12403
|
+
const newMediaType = this.getTrackMediaType(track);
|
|
12404
|
+
const newElementType = newMediaType === "audio" || newMediaType === "soundcloud" ? "audio" : "video";
|
|
12405
|
+
if (currentMediaType !== newElementType) {
|
|
12406
|
+
await this.recreatePlayerForTrack(track, false);
|
|
12407
|
+
this.updateTrackInfo(track);
|
|
12408
|
+
this.updatePlaylistUI();
|
|
12409
|
+
this.player.emit("playlisttrackchange", {
|
|
12410
|
+
index,
|
|
12411
|
+
item: track,
|
|
12412
|
+
total: this.tracks.length
|
|
12413
|
+
});
|
|
12414
|
+
setTimeout(() => {
|
|
12415
|
+
this.isChangingTrack = false;
|
|
12416
|
+
}, 150);
|
|
12417
|
+
return;
|
|
12418
|
+
}
|
|
12419
|
+
}
|
|
11829
12420
|
this.player.load({
|
|
11830
12421
|
src: track.src,
|
|
11831
12422
|
type: track.type,
|
|
@@ -11850,7 +12441,7 @@
|
|
|
11850
12441
|
* @param {number} index - Track index
|
|
11851
12442
|
* @param {boolean} userInitiated - Whether this was triggered by user action (default: false)
|
|
11852
12443
|
*/
|
|
11853
|
-
play(index, userInitiated = false) {
|
|
12444
|
+
async play(index, userInitiated = false) {
|
|
11854
12445
|
if (index < 0 || index >= this.tracks.length) {
|
|
11855
12446
|
console.warn("VidPly Playlist: Invalid track index", index);
|
|
11856
12447
|
return;
|
|
@@ -11858,6 +12449,25 @@
|
|
|
11858
12449
|
const track = this.tracks[index];
|
|
11859
12450
|
this.isChangingTrack = true;
|
|
11860
12451
|
this.currentIndex = index;
|
|
12452
|
+
if (this.options.recreatePlayers && this.hostElement && this.PlayerClass) {
|
|
12453
|
+
const currentMediaType = this.player ? this.player.element.tagName === "AUDIO" ? "audio" : "video" : null;
|
|
12454
|
+
const newMediaType = this.getTrackMediaType(track);
|
|
12455
|
+
const newElementType = newMediaType === "audio" || newMediaType === "soundcloud" ? "audio" : "video";
|
|
12456
|
+
if (currentMediaType !== newElementType) {
|
|
12457
|
+
await this.recreatePlayerForTrack(track, true);
|
|
12458
|
+
this.updateTrackInfo(track);
|
|
12459
|
+
this.updatePlaylistUI();
|
|
12460
|
+
this.player.emit("playlisttrackchange", {
|
|
12461
|
+
index,
|
|
12462
|
+
item: track,
|
|
12463
|
+
total: this.tracks.length
|
|
12464
|
+
});
|
|
12465
|
+
setTimeout(() => {
|
|
12466
|
+
this.isChangingTrack = false;
|
|
12467
|
+
}, 150);
|
|
12468
|
+
return;
|
|
12469
|
+
}
|
|
12470
|
+
}
|
|
11861
12471
|
this.player.load({
|
|
11862
12472
|
src: track.src,
|
|
11863
12473
|
type: track.type,
|
|
@@ -11919,10 +12529,26 @@
|
|
|
11919
12529
|
this.next();
|
|
11920
12530
|
}
|
|
11921
12531
|
}
|
|
12532
|
+
/**
|
|
12533
|
+
* Check if a source URL requires an external renderer
|
|
12534
|
+
* @param {string} src - Source URL
|
|
12535
|
+
* @returns {boolean}
|
|
12536
|
+
*/
|
|
12537
|
+
isExternalRendererUrl(src) {
|
|
12538
|
+
if (!src) return false;
|
|
12539
|
+
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");
|
|
12540
|
+
}
|
|
11922
12541
|
/**
|
|
11923
12542
|
* Handle track error
|
|
11924
12543
|
*/
|
|
11925
12544
|
handleTrackError(e) {
|
|
12545
|
+
const currentTrack = this.getCurrentTrack();
|
|
12546
|
+
if (currentTrack && currentTrack.src && this.isExternalRendererUrl(currentTrack.src)) {
|
|
12547
|
+
return;
|
|
12548
|
+
}
|
|
12549
|
+
if (this.isChangingTrack) {
|
|
12550
|
+
return;
|
|
12551
|
+
}
|
|
11926
12552
|
console.error("VidPly Playlist: Track error", e);
|
|
11927
12553
|
if (this.options.autoAdvance) {
|
|
11928
12554
|
setTimeout(() => {
|
|
@@ -12135,7 +12761,7 @@
|
|
|
12135
12761
|
id: "".concat(this.uniqueId, "-keyboard-instructions")
|
|
12136
12762
|
}
|
|
12137
12763
|
});
|
|
12138
|
-
instructions.textContent = "
|
|
12764
|
+
instructions.textContent = i18n.t("playlist.keyboardInstructions");
|
|
12139
12765
|
this.playlistPanel.appendChild(instructions);
|
|
12140
12766
|
const list = DOMUtils.createElement("ul", {
|
|
12141
12767
|
className: "vidply-playlist-list",
|
|
@@ -12291,7 +12917,7 @@
|
|
|
12291
12917
|
if (index < buttons.length - 1) {
|
|
12292
12918
|
newIndex = index + 1;
|
|
12293
12919
|
} else {
|
|
12294
|
-
announcement = "
|
|
12920
|
+
announcement = i18n.t("playlist.endOfPlaylist", { current: buttons.length, total: buttons.length });
|
|
12295
12921
|
}
|
|
12296
12922
|
break;
|
|
12297
12923
|
case "ArrowUp":
|
|
@@ -12300,7 +12926,7 @@
|
|
|
12300
12926
|
if (index > 0) {
|
|
12301
12927
|
newIndex = index - 1;
|
|
12302
12928
|
} else {
|
|
12303
|
-
announcement = "
|
|
12929
|
+
announcement = i18n.t("playlist.beginningOfPlaylist", { total: buttons.length });
|
|
12304
12930
|
}
|
|
12305
12931
|
break;
|
|
12306
12932
|
case "PageDown":
|
|
@@ -12308,7 +12934,7 @@
|
|
|
12308
12934
|
e.stopPropagation();
|
|
12309
12935
|
newIndex = Math.min(index + 5, buttons.length - 1);
|
|
12310
12936
|
if (newIndex === buttons.length - 1 && index !== newIndex) {
|
|
12311
|
-
announcement = "
|
|
12937
|
+
announcement = i18n.t("playlist.jumpedToLastTrack", { current: newIndex + 1, total: buttons.length });
|
|
12312
12938
|
}
|
|
12313
12939
|
break;
|
|
12314
12940
|
case "PageUp":
|
|
@@ -12316,7 +12942,7 @@
|
|
|
12316
12942
|
e.stopPropagation();
|
|
12317
12943
|
newIndex = Math.max(index - 5, 0);
|
|
12318
12944
|
if (newIndex === 0 && index !== newIndex) {
|
|
12319
|
-
announcement = "
|
|
12945
|
+
announcement = i18n.t("playlist.jumpedToFirstTrack", { total: buttons.length });
|
|
12320
12946
|
}
|
|
12321
12947
|
break;
|
|
12322
12948
|
case "Home":
|
|
@@ -12324,7 +12950,7 @@
|
|
|
12324
12950
|
e.stopPropagation();
|
|
12325
12951
|
newIndex = 0;
|
|
12326
12952
|
if (index !== 0) {
|
|
12327
|
-
announcement = "
|
|
12953
|
+
announcement = i18n.t("playlist.firstTrack", { total: buttons.length });
|
|
12328
12954
|
}
|
|
12329
12955
|
break;
|
|
12330
12956
|
case "End":
|
|
@@ -12332,7 +12958,7 @@
|
|
|
12332
12958
|
e.stopPropagation();
|
|
12333
12959
|
newIndex = buttons.length - 1;
|
|
12334
12960
|
if (index !== buttons.length - 1) {
|
|
12335
|
-
announcement = "
|
|
12961
|
+
announcement = i18n.t("playlist.lastTrack", { current: buttons.length, total: buttons.length });
|
|
12336
12962
|
}
|
|
12337
12963
|
break;
|
|
12338
12964
|
}
|