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
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"format": "esm"
|
|
12
12
|
},
|
|
13
13
|
"src/i18n/languages/en.js": {
|
|
14
|
-
"bytes":
|
|
14
|
+
"bytes": 7637,
|
|
15
15
|
"imports": [],
|
|
16
16
|
"format": "esm"
|
|
17
17
|
},
|
|
18
18
|
"src/i18n/languages/de.js": {
|
|
19
|
-
"bytes":
|
|
19
|
+
"bytes": 9427,
|
|
20
20
|
"imports": [],
|
|
21
21
|
"format": "esm"
|
|
22
22
|
},
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"format": "esm"
|
|
110
110
|
},
|
|
111
111
|
"src/controls/ControlBar.js": {
|
|
112
|
-
"bytes":
|
|
112
|
+
"bytes": 147152,
|
|
113
113
|
"imports": [
|
|
114
114
|
{
|
|
115
115
|
"path": "src/utils/DOMUtils.js",
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
"format": "esm"
|
|
187
187
|
},
|
|
188
188
|
"src/renderers/HTML5Renderer.js": {
|
|
189
|
-
"bytes":
|
|
189
|
+
"bytes": 10921,
|
|
190
190
|
"imports": [],
|
|
191
191
|
"format": "esm"
|
|
192
192
|
},
|
|
@@ -346,7 +346,7 @@
|
|
|
346
346
|
"format": "esm"
|
|
347
347
|
},
|
|
348
348
|
"src/renderers/HLSRenderer.js": {
|
|
349
|
-
"bytes":
|
|
349
|
+
"bytes": 12151,
|
|
350
350
|
"imports": [
|
|
351
351
|
{
|
|
352
352
|
"path": "src/renderers/HTML5Renderer.js",
|
|
@@ -362,7 +362,7 @@
|
|
|
362
362
|
"format": "esm"
|
|
363
363
|
},
|
|
364
364
|
"src/core/Player.js": {
|
|
365
|
-
"bytes":
|
|
365
|
+
"bytes": 224782,
|
|
366
366
|
"imports": [
|
|
367
367
|
{
|
|
368
368
|
"path": "src/utils/EventEmitter.js",
|
|
@@ -473,7 +473,7 @@
|
|
|
473
473
|
"format": "esm"
|
|
474
474
|
},
|
|
475
475
|
"src/features/PlaylistManager.js": {
|
|
476
|
-
"bytes":
|
|
476
|
+
"bytes": 57201,
|
|
477
477
|
"imports": [
|
|
478
478
|
{
|
|
479
479
|
"path": "src/utils/DOMUtils.js",
|
|
@@ -529,10 +529,10 @@
|
|
|
529
529
|
},
|
|
530
530
|
"bytes": 4730
|
|
531
531
|
},
|
|
532
|
-
"dist/prod/vidply.HLSRenderer-
|
|
532
|
+
"dist/prod/vidply.HLSRenderer-ESR6NAMI.min.js": {
|
|
533
533
|
"imports": [
|
|
534
534
|
{
|
|
535
|
-
"path": "dist/prod/vidply.HTML5Renderer-
|
|
535
|
+
"path": "dist/prod/vidply.HTML5Renderer-6ROXQSQY.min.js",
|
|
536
536
|
"kind": "dynamic-import"
|
|
537
537
|
}
|
|
538
538
|
],
|
|
@@ -542,10 +542,10 @@
|
|
|
542
542
|
"entryPoint": "src/renderers/HLSRenderer.js",
|
|
543
543
|
"inputs": {
|
|
544
544
|
"src/renderers/HLSRenderer.js": {
|
|
545
|
-
"bytesInOutput":
|
|
545
|
+
"bytesInOutput": 6514
|
|
546
546
|
}
|
|
547
547
|
},
|
|
548
|
-
"bytes":
|
|
548
|
+
"bytes": 6658
|
|
549
549
|
},
|
|
550
550
|
"dist/prod/vidply.SoundCloudRenderer-MOR2CUFH.min.js": {
|
|
551
551
|
"imports": [],
|
|
@@ -564,15 +564,15 @@
|
|
|
564
564
|
"dist/prod/vidply.esm.min.js": {
|
|
565
565
|
"imports": [
|
|
566
566
|
{
|
|
567
|
-
"path": "dist/prod/vidply.chunk-
|
|
567
|
+
"path": "dist/prod/vidply.chunk-7HVHEUHH.min.js",
|
|
568
568
|
"kind": "import-statement"
|
|
569
569
|
},
|
|
570
570
|
{
|
|
571
|
-
"path": "dist/prod/vidply.chunk-
|
|
571
|
+
"path": "dist/prod/vidply.chunk-IQKD4GUB.min.js",
|
|
572
572
|
"kind": "import-statement"
|
|
573
573
|
},
|
|
574
574
|
{
|
|
575
|
-
"path": "dist/prod/vidply.TranscriptManager-
|
|
575
|
+
"path": "dist/prod/vidply.TranscriptManager-B65LKXGG.min.js",
|
|
576
576
|
"kind": "dynamic-import"
|
|
577
577
|
},
|
|
578
578
|
{
|
|
@@ -584,7 +584,7 @@
|
|
|
584
584
|
"kind": "dynamic-import"
|
|
585
585
|
},
|
|
586
586
|
{
|
|
587
|
-
"path": "dist/prod/vidply.HLSRenderer-
|
|
587
|
+
"path": "dist/prod/vidply.HLSRenderer-ESR6NAMI.min.js",
|
|
588
588
|
"kind": "dynamic-import"
|
|
589
589
|
},
|
|
590
590
|
{
|
|
@@ -609,7 +609,7 @@
|
|
|
609
609
|
"bytesInOutput": 1009
|
|
610
610
|
},
|
|
611
611
|
"src/controls/ControlBar.js": {
|
|
612
|
-
"bytesInOutput":
|
|
612
|
+
"bytesInOutput": 63355
|
|
613
613
|
},
|
|
614
614
|
"src/controls/CaptionManager.js": {
|
|
615
615
|
"bytesInOutput": 7279
|
|
@@ -624,18 +624,18 @@
|
|
|
624
624
|
"bytesInOutput": 19117
|
|
625
625
|
},
|
|
626
626
|
"src/core/Player.js": {
|
|
627
|
-
"bytesInOutput":
|
|
627
|
+
"bytesInOutput": 80485
|
|
628
628
|
},
|
|
629
629
|
"src/features/PlaylistManager.js": {
|
|
630
|
-
"bytesInOutput":
|
|
630
|
+
"bytesInOutput": 24268
|
|
631
631
|
},
|
|
632
632
|
"src/index.js": {
|
|
633
633
|
"bytesInOutput": 1869
|
|
634
634
|
}
|
|
635
635
|
},
|
|
636
|
-
"bytes":
|
|
636
|
+
"bytes": 212078
|
|
637
637
|
},
|
|
638
|
-
"dist/prod/vidply.de-
|
|
638
|
+
"dist/prod/vidply.de-IHKC573T.min.js": {
|
|
639
639
|
"imports": [],
|
|
640
640
|
"exports": [
|
|
641
641
|
"de"
|
|
@@ -643,10 +643,10 @@
|
|
|
643
643
|
"entryPoint": "src/i18n/languages/de.js",
|
|
644
644
|
"inputs": {
|
|
645
645
|
"src/i18n/languages/de.js": {
|
|
646
|
-
"bytesInOutput":
|
|
646
|
+
"bytesInOutput": 7512
|
|
647
647
|
}
|
|
648
648
|
},
|
|
649
|
-
"bytes":
|
|
649
|
+
"bytes": 7647
|
|
650
650
|
},
|
|
651
651
|
"dist/prod/vidply.es-3IJCQLJ7.min.js": {
|
|
652
652
|
"imports": [],
|
|
@@ -687,10 +687,10 @@
|
|
|
687
687
|
},
|
|
688
688
|
"bytes": 8204
|
|
689
689
|
},
|
|
690
|
-
"dist/prod/vidply.HTML5Renderer-
|
|
690
|
+
"dist/prod/vidply.HTML5Renderer-6ROXQSQY.min.js": {
|
|
691
691
|
"imports": [
|
|
692
692
|
{
|
|
693
|
-
"path": "dist/prod/vidply.chunk-
|
|
693
|
+
"path": "dist/prod/vidply.chunk-7HVHEUHH.min.js",
|
|
694
694
|
"kind": "import-statement"
|
|
695
695
|
}
|
|
696
696
|
],
|
|
@@ -701,22 +701,22 @@
|
|
|
701
701
|
"inputs": {},
|
|
702
702
|
"bytes": 192
|
|
703
703
|
},
|
|
704
|
-
"dist/prod/vidply.chunk-
|
|
704
|
+
"dist/prod/vidply.chunk-7HVHEUHH.min.js": {
|
|
705
705
|
"imports": [],
|
|
706
706
|
"exports": [
|
|
707
707
|
"a"
|
|
708
708
|
],
|
|
709
709
|
"inputs": {
|
|
710
710
|
"src/renderers/HTML5Renderer.js": {
|
|
711
|
-
"bytesInOutput":
|
|
711
|
+
"bytesInOutput": 5387
|
|
712
712
|
}
|
|
713
713
|
},
|
|
714
|
-
"bytes":
|
|
714
|
+
"bytes": 5521
|
|
715
715
|
},
|
|
716
|
-
"dist/prod/vidply.TranscriptManager-
|
|
716
|
+
"dist/prod/vidply.TranscriptManager-B65LKXGG.min.js": {
|
|
717
717
|
"imports": [
|
|
718
718
|
{
|
|
719
|
-
"path": "dist/prod/vidply.chunk-
|
|
719
|
+
"path": "dist/prod/vidply.chunk-IQKD4GUB.min.js",
|
|
720
720
|
"kind": "import-statement"
|
|
721
721
|
}
|
|
722
722
|
],
|
|
@@ -731,10 +731,10 @@
|
|
|
731
731
|
},
|
|
732
732
|
"bytes": 43042
|
|
733
733
|
},
|
|
734
|
-
"dist/prod/vidply.chunk-
|
|
734
|
+
"dist/prod/vidply.chunk-IQKD4GUB.min.js": {
|
|
735
735
|
"imports": [
|
|
736
736
|
{
|
|
737
|
-
"path": "dist/prod/vidply.de-
|
|
737
|
+
"path": "dist/prod/vidply.de-IHKC573T.min.js",
|
|
738
738
|
"kind": "dynamic-import"
|
|
739
739
|
},
|
|
740
740
|
{
|
|
@@ -771,7 +771,7 @@
|
|
|
771
771
|
"bytesInOutput": 2348
|
|
772
772
|
},
|
|
773
773
|
"src/i18n/languages/en.js": {
|
|
774
|
-
"bytesInOutput":
|
|
774
|
+
"bytesInOutput": 6385
|
|
775
775
|
},
|
|
776
776
|
"src/i18n/translations.js": {
|
|
777
777
|
"bytesInOutput": 340
|
|
@@ -801,7 +801,7 @@
|
|
|
801
801
|
"bytesInOutput": 776
|
|
802
802
|
}
|
|
803
803
|
},
|
|
804
|
-
"bytes":
|
|
804
|
+
"bytes": 40477
|
|
805
805
|
},
|
|
806
806
|
"dist/prod/vidply.YouTubeRenderer-MFC2GMAC.min.js": {
|
|
807
807
|
"imports": [],
|
package/package.json
CHANGED
|
@@ -27,6 +27,10 @@ export class ControlBar {
|
|
|
27
27
|
init() {
|
|
28
28
|
this.createElement();
|
|
29
29
|
this.createControls();
|
|
30
|
+
// Ensure time UI reflects any prefilled state (e.g. initialDuration)
|
|
31
|
+
// even when media metadata is deferred and 'loadedmetadata' won't fire yet.
|
|
32
|
+
this.updateDuration();
|
|
33
|
+
this.updateProgress();
|
|
30
34
|
this.attachEvents();
|
|
31
35
|
this.setupAutoHide();
|
|
32
36
|
this.setupOverflowDetection();
|
|
@@ -715,7 +719,22 @@ export class ControlBar {
|
|
|
715
719
|
}
|
|
716
720
|
|
|
717
721
|
// 4. Playback speed button
|
|
718
|
-
|
|
722
|
+
// IMPORTANT: Don't rely on renderer.constructor.name here.
|
|
723
|
+
// In production builds, class names are minified (e.g. "class s"), which would break the check.
|
|
724
|
+
// Instead, detect HLS by the current source URL.
|
|
725
|
+
const src = this.player.currentSource
|
|
726
|
+
|| this.player.element?.getAttribute?.('src')
|
|
727
|
+
|| this.player.element?.currentSrc
|
|
728
|
+
|| this.player.element?.src
|
|
729
|
+
|| this.player.element?.querySelector?.('source')?.getAttribute?.('src')
|
|
730
|
+
|| this.player.element?.querySelector?.('source')?.src
|
|
731
|
+
|| '';
|
|
732
|
+
const isHlsSource = typeof src === 'string' && src.includes('.m3u8');
|
|
733
|
+
const isVideoElement = this.player.element?.tagName?.toLowerCase() === 'video';
|
|
734
|
+
const hideSpeedForThisPlayer =
|
|
735
|
+
(!!this.player.options.hideSpeedForHls && isHlsSource)
|
|
736
|
+
|| (!!this.player.options.hideSpeedForHlsVideo && isHlsSource && isVideoElement);
|
|
737
|
+
if (this.player.options.speedButton && !hideSpeedForThisPlayer) {
|
|
719
738
|
const btn = this.createSpeedButton();
|
|
720
739
|
btn.dataset.overflowPriority = '1';
|
|
721
740
|
btn.dataset.overflowPriorityMobile = '3';
|
|
@@ -831,22 +850,44 @@ export class ControlBar {
|
|
|
831
850
|
|
|
832
851
|
// Helper methods to check for available features
|
|
833
852
|
hasChapterTracks() {
|
|
853
|
+
// 1) Prefer already-loaded TextTracks (fast + accurate)
|
|
834
854
|
const textTracks = this.player.element.textTracks;
|
|
835
855
|
for (let i = 0; i < textTracks.length; i++) {
|
|
836
|
-
if (textTracks[i].kind === 'chapters')
|
|
837
|
-
return true;
|
|
856
|
+
if (textTracks[i].kind === 'chapters') return true;
|
|
838
857
|
}
|
|
858
|
+
|
|
859
|
+
// 2) Fallback to DOM <track> elements (works before tracks are fully loaded)
|
|
860
|
+
const trackEls = Array.from(this.player.element.querySelectorAll('track[kind="chapters"]'));
|
|
861
|
+
if (trackEls.length > 0) return true;
|
|
862
|
+
|
|
863
|
+
// 3) Playlist metadata fallback (works even when we intentionally defer loading)
|
|
864
|
+
const current = this.player.playlistManager?.getCurrentTrack?.();
|
|
865
|
+
if (current?.tracks && Array.isArray(current.tracks)) {
|
|
866
|
+
return current.tracks.some(t => t?.kind === 'chapters');
|
|
839
867
|
}
|
|
868
|
+
|
|
840
869
|
return false;
|
|
841
870
|
}
|
|
842
871
|
|
|
843
872
|
hasCaptionTracks() {
|
|
873
|
+
// 1) Prefer already-loaded TextTracks
|
|
844
874
|
const textTracks = this.player.element.textTracks;
|
|
845
875
|
for (let i = 0; i < textTracks.length; i++) {
|
|
846
|
-
if (textTracks[i].kind === 'captions' || textTracks[i].kind === 'subtitles')
|
|
876
|
+
if (textTracks[i].kind === 'captions' || textTracks[i].kind === 'subtitles') return true;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// 2) Fallback to DOM <track> elements
|
|
880
|
+
const trackEls = Array.from(this.player.element.querySelectorAll('track'));
|
|
881
|
+
if (trackEls.some(el => (el.getAttribute('kind') === 'captions' || el.getAttribute('kind') === 'subtitles'))) {
|
|
847
882
|
return true;
|
|
848
883
|
}
|
|
884
|
+
|
|
885
|
+
// 3) Playlist metadata fallback
|
|
886
|
+
const current = this.player.playlistManager?.getCurrentTrack?.();
|
|
887
|
+
if (current?.tracks && Array.isArray(current.tracks)) {
|
|
888
|
+
return current.tracks.some(t => t?.kind === 'captions' || t?.kind === 'subtitles');
|
|
849
889
|
}
|
|
890
|
+
|
|
850
891
|
return false;
|
|
851
892
|
}
|
|
852
893
|
|
|
@@ -948,6 +989,8 @@ export class ControlBar {
|
|
|
948
989
|
this.currentPreviewTime = null;
|
|
949
990
|
this.previewThumbnailTimeout = null;
|
|
950
991
|
this.previewSupported = false;
|
|
992
|
+
this.previewVideoReady = false;
|
|
993
|
+
this.previewVideoInitialized = false;
|
|
951
994
|
|
|
952
995
|
// Check if preview is supported (HTML5 video only)
|
|
953
996
|
// Check if element is a video
|
|
@@ -957,80 +1000,75 @@ export class ControlBar {
|
|
|
957
1000
|
return;
|
|
958
1001
|
}
|
|
959
1002
|
|
|
960
|
-
//
|
|
961
|
-
//
|
|
962
|
-
|
|
1003
|
+
// IMPORTANT: do NOT create/load the preview video until the user has started playback at least once.
|
|
1004
|
+
// Otherwise we'd trigger heavy MP4 network traffic just by hovering the progress bar.
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* Lazily create the hidden preview video (only after playback started once)
|
|
1009
|
+
*/
|
|
1010
|
+
ensurePreviewVideoInitialized() {
|
|
1011
|
+
if (this.previewVideoInitialized) return;
|
|
1012
|
+
if (!this.player?.state?.hasStartedPlayback) return;
|
|
1013
|
+
|
|
963
1014
|
const renderer = this.player.renderer;
|
|
964
1015
|
const hasVideoMedia = renderer && renderer.media && renderer.media.tagName === 'VIDEO';
|
|
965
|
-
|
|
966
|
-
// Check if it's HTML5Renderer by checking:
|
|
967
|
-
// 1. Has media property that is a video element
|
|
968
|
-
// 2. Media is the same as player.element (HTML5Renderer sets this.media = player.element)
|
|
969
|
-
// 3. Doesn't have hls property (HLSRenderer has hls property)
|
|
970
|
-
// 4. Has seek method (all renderers have this, but combined with above checks it's reliable)
|
|
971
|
-
const isHTML5Renderer = hasVideoMedia &&
|
|
1016
|
+
const isHTML5Renderer = hasVideoMedia &&
|
|
972
1017
|
renderer.media === this.player.element &&
|
|
973
1018
|
!renderer.hls &&
|
|
974
1019
|
typeof renderer.seek === 'function';
|
|
975
|
-
|
|
1020
|
+
|
|
976
1021
|
this.previewSupported = isHTML5Renderer && hasVideoMedia;
|
|
1022
|
+
if (!this.previewSupported) return;
|
|
977
1023
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
this.previewVideo.style.width = '1px';
|
|
987
|
-
this.previewVideo.style.height = '1px';
|
|
988
|
-
this.previewVideo.style.top = '-9999px';
|
|
989
|
-
|
|
990
|
-
// Copy source and attributes from main video
|
|
991
|
-
const mainVideo = renderer.media || this.player.element;
|
|
992
|
-
let videoSrc = null;
|
|
993
|
-
|
|
994
|
-
if (mainVideo.src) {
|
|
995
|
-
videoSrc = mainVideo.src;
|
|
996
|
-
} else {
|
|
997
|
-
const source = mainVideo.querySelector('source');
|
|
998
|
-
if (source) {
|
|
999
|
-
videoSrc = source.src;
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
if (!videoSrc) {
|
|
1004
|
-
this.player.log('No video source found for preview', 'warn');
|
|
1005
|
-
this.previewSupported = false;
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
// Copy crossOrigin if set (important for CORS)
|
|
1010
|
-
if (mainVideo.crossOrigin) {
|
|
1011
|
-
this.previewVideo.crossOrigin = mainVideo.crossOrigin;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
// Handle errors gracefully
|
|
1015
|
-
this.previewVideo.addEventListener('error', (e) => {
|
|
1016
|
-
this.player.log('Preview video failed to load:', e, 'warn');
|
|
1017
|
-
this.previewSupported = false;
|
|
1018
|
-
});
|
|
1019
|
-
|
|
1020
|
-
// Wait for metadata to be loaded before using
|
|
1021
|
-
this.previewVideo.addEventListener('loadedmetadata', () => {
|
|
1022
|
-
this.previewVideoReady = true;
|
|
1023
|
-
}, { once: true });
|
|
1024
|
-
|
|
1025
|
-
// Append to player container (hidden) BEFORE setting src
|
|
1026
|
-
if (this.player.container) {
|
|
1027
|
-
this.player.container.appendChild(this.previewVideo);
|
|
1024
|
+
const mainVideo = renderer.media || this.player.element;
|
|
1025
|
+
let videoSrc = null;
|
|
1026
|
+
if (mainVideo.src) {
|
|
1027
|
+
videoSrc = mainVideo.src;
|
|
1028
|
+
} else {
|
|
1029
|
+
const source = mainVideo.querySelector('source');
|
|
1030
|
+
if (source) {
|
|
1031
|
+
videoSrc = source.src;
|
|
1028
1032
|
}
|
|
1029
|
-
|
|
1030
|
-
// Set source after appending to DOM
|
|
1031
|
-
this.previewVideo.src = videoSrc;
|
|
1032
|
-
this.previewVideoReady = false;
|
|
1033
1033
|
}
|
|
1034
|
+
|
|
1035
|
+
if (!videoSrc) {
|
|
1036
|
+
this.player.log('No video source found for preview', 'warn');
|
|
1037
|
+
this.previewSupported = false;
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// Create a hidden video element for capturing frames
|
|
1042
|
+
this.previewVideo = document.createElement('video');
|
|
1043
|
+
this.previewVideo.muted = true;
|
|
1044
|
+
this.previewVideo.preload = 'auto'; // Need more than metadata to capture frames
|
|
1045
|
+
this.previewVideo.playsInline = true;
|
|
1046
|
+
this.previewVideo.style.position = 'absolute';
|
|
1047
|
+
this.previewVideo.style.visibility = 'hidden';
|
|
1048
|
+
this.previewVideo.style.width = '1px';
|
|
1049
|
+
this.previewVideo.style.height = '1px';
|
|
1050
|
+
this.previewVideo.style.top = '-9999px';
|
|
1051
|
+
|
|
1052
|
+
if (mainVideo.crossOrigin) {
|
|
1053
|
+
this.previewVideo.crossOrigin = mainVideo.crossOrigin;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
this.previewVideo.addEventListener('error', (e) => {
|
|
1057
|
+
this.player.log('Preview video failed to load:', e, 'warn');
|
|
1058
|
+
this.previewSupported = false;
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
this.previewVideo.addEventListener('loadedmetadata', () => {
|
|
1062
|
+
this.previewVideoReady = true;
|
|
1063
|
+
}, { once: true });
|
|
1064
|
+
|
|
1065
|
+
if (this.player.container) {
|
|
1066
|
+
this.player.container.appendChild(this.previewVideo);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
this.previewVideo.src = videoSrc;
|
|
1070
|
+
this.previewVideoReady = false;
|
|
1071
|
+
this.previewVideoInitialized = true;
|
|
1034
1072
|
}
|
|
1035
1073
|
|
|
1036
1074
|
/**
|
|
@@ -1203,10 +1241,21 @@ export class ControlBar {
|
|
|
1203
1241
|
// Update tooltip position
|
|
1204
1242
|
this.controls.progressTooltip.style.left = `${left}px`;
|
|
1205
1243
|
this.controls.progressTooltip.style.display = 'block';
|
|
1206
|
-
|
|
1207
|
-
//
|
|
1244
|
+
|
|
1245
|
+
// Only show preview thumbnails after the user has started playback at least once.
|
|
1246
|
+
// Before that, show just the timestamp (no empty preview box).
|
|
1247
|
+
if (!this.player?.state?.hasStartedPlayback) {
|
|
1248
|
+
if (this.controls.progressPreview) {
|
|
1249
|
+
this.controls.progressPreview.style.display = 'none';
|
|
1250
|
+
}
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
this.ensurePreviewVideoInitialized();
|
|
1208
1255
|
if (this.previewSupported) {
|
|
1209
1256
|
this.updatePreviewThumbnail(time);
|
|
1257
|
+
} else if (this.controls.progressPreview) {
|
|
1258
|
+
this.controls.progressPreview.style.display = 'none';
|
|
1210
1259
|
}
|
|
1211
1260
|
}
|
|
1212
1261
|
});
|