@edm-webplayer/webplayer-angular 0.1.31 → 0.1.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.
|
@@ -78,12 +78,19 @@ class PlyrPlayerComponent {
|
|
|
78
78
|
recommendationBlocker;
|
|
79
79
|
recommendationBlockerActiveZone;
|
|
80
80
|
topClickBlocker;
|
|
81
|
+
gestureOverlay;
|
|
81
82
|
menuObserver;
|
|
82
83
|
playbackEnded = false;
|
|
83
84
|
overlayBlockAll = false;
|
|
84
85
|
endedPosterOverlay;
|
|
85
86
|
fullscreenCleanup;
|
|
86
|
-
|
|
87
|
+
interactionUnmuteCleanup;
|
|
88
|
+
pendingStartTime;
|
|
89
|
+
pendingGesturePlay = false;
|
|
90
|
+
onResize = () => {
|
|
91
|
+
this.updateRecommendationBlockerSafeZone();
|
|
92
|
+
this.updateGestureOverlaySafeZone();
|
|
93
|
+
};
|
|
87
94
|
onTopBlockerPointerDown = (event) => {
|
|
88
95
|
try {
|
|
89
96
|
event.preventDefault();
|
|
@@ -119,6 +126,30 @@ class PlyrPlayerComponent {
|
|
|
119
126
|
this.applyTheme(this.config.ui.colors);
|
|
120
127
|
}
|
|
121
128
|
}
|
|
129
|
+
flushPendingStartTime(target, success) {
|
|
130
|
+
const pending = this.pendingStartTime;
|
|
131
|
+
if (!pending) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const tolerance = 0.35;
|
|
135
|
+
if (Math.abs(pending.value - target) > tolerance) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const callbacks = pending.queue.slice();
|
|
139
|
+
pending.queue.length = 0;
|
|
140
|
+
if (success) {
|
|
141
|
+
this.pendingStartTime = undefined;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
pending.blockPlayback = false;
|
|
145
|
+
}
|
|
146
|
+
callbacks.forEach((cb) => {
|
|
147
|
+
try {
|
|
148
|
+
cb();
|
|
149
|
+
}
|
|
150
|
+
catch { }
|
|
151
|
+
});
|
|
152
|
+
}
|
|
122
153
|
getControlsSafeZone() {
|
|
123
154
|
const controls = (this.plyr?.elements?.controls ?? null);
|
|
124
155
|
const menuHeight = this.getOpenMenuHeight();
|
|
@@ -143,7 +174,9 @@ class PlyrPlayerComponent {
|
|
|
143
174
|
const host = this.config?.video_host;
|
|
144
175
|
if (this.overlayBlockAll &&
|
|
145
176
|
(host === 'youtube' || host === 'vimeo')) {
|
|
146
|
-
|
|
177
|
+
if (this.playbackEnded) {
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
147
180
|
}
|
|
148
181
|
return this.getControlsSafeZone();
|
|
149
182
|
}
|
|
@@ -340,13 +373,12 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
340
373
|
this.updateTopClickBlockerSafeZone();
|
|
341
374
|
}
|
|
342
375
|
updateRecommendationBlockerSafeZone() {
|
|
343
|
-
|
|
344
|
-
return;
|
|
345
|
-
const safeZone = this.getOverlaySafeZone();
|
|
376
|
+
const overlaySafeZone = this.getOverlaySafeZone();
|
|
346
377
|
if (this.recommendationBlockerActiveZone) {
|
|
347
|
-
this.recommendationBlockerActiveZone.style.bottom = `${
|
|
378
|
+
this.recommendationBlockerActiveZone.style.bottom = `${overlaySafeZone}px`;
|
|
348
379
|
}
|
|
349
|
-
this.updateTopClickBlockerSafeZone(
|
|
380
|
+
this.updateTopClickBlockerSafeZone(overlaySafeZone);
|
|
381
|
+
this.updateGestureOverlaySafeZone(this.getControlsSafeZone());
|
|
350
382
|
}
|
|
351
383
|
updateTopClickBlockerSafeZone(precomputed) {
|
|
352
384
|
if (!this.topClickBlocker)
|
|
@@ -355,6 +387,13 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
355
387
|
const safeZone = Math.max(0, safeZoneRaw);
|
|
356
388
|
this.topClickBlocker.style.bottom = `${safeZone}px`;
|
|
357
389
|
}
|
|
390
|
+
updateGestureOverlaySafeZone(precomputed) {
|
|
391
|
+
if (!this.gestureOverlay)
|
|
392
|
+
return;
|
|
393
|
+
const safeZoneRaw = typeof precomputed === 'number' ? precomputed : this.getControlsSafeZone();
|
|
394
|
+
const safeZone = Math.max(0, safeZoneRaw);
|
|
395
|
+
this.gestureOverlay.style.bottom = `${safeZone}px`;
|
|
396
|
+
}
|
|
358
397
|
togglePlayback(force) {
|
|
359
398
|
if (!this.plyr)
|
|
360
399
|
return;
|
|
@@ -372,6 +411,9 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
372
411
|
}
|
|
373
412
|
const shouldPlay = typeof force === 'boolean' ? !!force : !this.plyr.playing;
|
|
374
413
|
if (shouldPlay) {
|
|
414
|
+
if (this.deferUntilStartTimeSettles(() => this.togglePlayback(true))) {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
375
417
|
if (ended) {
|
|
376
418
|
try {
|
|
377
419
|
if (typeof this.plyr.restart === 'function') {
|
|
@@ -386,6 +428,7 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
386
428
|
this.playbackEnded = false;
|
|
387
429
|
this.overlayBlockAll = false;
|
|
388
430
|
this.updateRecommendationBlockerSafeZone();
|
|
431
|
+
this.hideGestureOverlay();
|
|
389
432
|
try {
|
|
390
433
|
const result = this.plyr.play?.();
|
|
391
434
|
if (result && typeof result.catch === 'function') {
|
|
@@ -477,6 +520,380 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
477
520
|
}
|
|
478
521
|
return 'ontouchstart' in window;
|
|
479
522
|
}
|
|
523
|
+
isIframeProvider() {
|
|
524
|
+
return this.config?.video_host === 'youtube' || this.config?.video_host === 'vimeo';
|
|
525
|
+
}
|
|
526
|
+
shouldAutoplay() {
|
|
527
|
+
return !!(this.config?.autoplay || this.config?.is_live);
|
|
528
|
+
}
|
|
529
|
+
requiresMutedAutoplay() {
|
|
530
|
+
return this.isIOSDevice();
|
|
531
|
+
}
|
|
532
|
+
setPlayerMutedState(muted, volume = 1, target) {
|
|
533
|
+
if (this.plyr) {
|
|
534
|
+
try {
|
|
535
|
+
this.plyr.muted = muted;
|
|
536
|
+
}
|
|
537
|
+
catch { }
|
|
538
|
+
if (!muted) {
|
|
539
|
+
try {
|
|
540
|
+
this.plyr.volume = volume;
|
|
541
|
+
}
|
|
542
|
+
catch { }
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
const media = target ?? this.videoRef?.nativeElement ?? null;
|
|
546
|
+
if (media) {
|
|
547
|
+
try {
|
|
548
|
+
media.muted = muted;
|
|
549
|
+
}
|
|
550
|
+
catch { }
|
|
551
|
+
if (!muted && typeof media.volume === 'number') {
|
|
552
|
+
try {
|
|
553
|
+
media.volume = volume;
|
|
554
|
+
}
|
|
555
|
+
catch { }
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
clearAutoplayUnlockListener() {
|
|
560
|
+
if (this.interactionUnmuteCleanup) {
|
|
561
|
+
try {
|
|
562
|
+
this.interactionUnmuteCleanup();
|
|
563
|
+
}
|
|
564
|
+
catch { }
|
|
565
|
+
this.interactionUnmuteCleanup = undefined;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
ensureAutoplayUnlockListener() {
|
|
569
|
+
if (typeof window === 'undefined' ||
|
|
570
|
+
this.interactionUnmuteCleanup ||
|
|
571
|
+
!this.shouldAutoplay()) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
const capture = true;
|
|
575
|
+
const handler = () => {
|
|
576
|
+
this.setPlayerMutedState(false);
|
|
577
|
+
try {
|
|
578
|
+
this.plyr?.play();
|
|
579
|
+
}
|
|
580
|
+
catch { }
|
|
581
|
+
this.clearAutoplayUnlockListener();
|
|
582
|
+
};
|
|
583
|
+
window.addEventListener('touchend', handler, capture);
|
|
584
|
+
window.addEventListener('pointerup', handler, capture);
|
|
585
|
+
window.addEventListener('click', handler, capture);
|
|
586
|
+
this.interactionUnmuteCleanup = () => {
|
|
587
|
+
window.removeEventListener('touchend', handler, capture);
|
|
588
|
+
window.removeEventListener('pointerup', handler, capture);
|
|
589
|
+
window.removeEventListener('click', handler, capture);
|
|
590
|
+
this.interactionUnmuteCleanup = undefined;
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
scheduleUserInteractionUnmute(video) {
|
|
594
|
+
this.unmuteAfterDelay(video || undefined);
|
|
595
|
+
this.ensureAutoplayUnlockListener();
|
|
596
|
+
}
|
|
597
|
+
requestStartTimeSeek(start, opts = {}) {
|
|
598
|
+
if (!(start > 0)) {
|
|
599
|
+
this.pendingStartTime = undefined;
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const video = opts.video ?? this.videoRef?.nativeElement ?? null;
|
|
603
|
+
const normalized = Math.max(0, start);
|
|
604
|
+
const tolerance = 0.35;
|
|
605
|
+
const pending = this.pendingStartTime;
|
|
606
|
+
if (pending && Math.abs(pending.value - normalized) <= tolerance) {
|
|
607
|
+
pending.video = video ?? pending.video;
|
|
608
|
+
pending.blockPlayback = true;
|
|
609
|
+
}
|
|
610
|
+
else {
|
|
611
|
+
const carryQueue = this.pendingStartTime?.queue ?? [];
|
|
612
|
+
this.pendingStartTime = {
|
|
613
|
+
value: normalized,
|
|
614
|
+
video,
|
|
615
|
+
queue: carryQueue,
|
|
616
|
+
blockPlayback: true,
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
this.applyStartTimeToCurrentSource(normalized, { video });
|
|
620
|
+
}
|
|
621
|
+
deferUntilStartTimeSettles(callback) {
|
|
622
|
+
if (!this.pendingStartTime || !this.pendingStartTime.blockPlayback)
|
|
623
|
+
return false;
|
|
624
|
+
this.pendingStartTime.queue.push(callback);
|
|
625
|
+
return true;
|
|
626
|
+
}
|
|
627
|
+
retryPendingStartTime() {
|
|
628
|
+
if (!this.pendingStartTime) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
const { value, video } = this.pendingStartTime;
|
|
632
|
+
this.applyStartTimeToCurrentSource(value, {
|
|
633
|
+
video: video ?? this.videoRef?.nativeElement ?? null,
|
|
634
|
+
attempts: 3,
|
|
635
|
+
delayMs: 150,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
applyStartTimeToCurrentSource(start, opts = {}) {
|
|
639
|
+
if (!this.plyr || !(start > 0)) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const video = opts.video ?? this.videoRef?.nativeElement ?? null;
|
|
643
|
+
let attempts = Math.max(1, opts.attempts ?? 6);
|
|
644
|
+
const delayMs = opts.delayMs ?? 250;
|
|
645
|
+
const tolerance = 0.35;
|
|
646
|
+
const scheduleRetry = () => {
|
|
647
|
+
attempts -= 1;
|
|
648
|
+
if (attempts > 0) {
|
|
649
|
+
setTimeout(trySeek, delayMs);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
this.flushPendingStartTime(start, false);
|
|
653
|
+
};
|
|
654
|
+
const verifyAfterAttempt = () => {
|
|
655
|
+
const current = this.plyr?.currentTime || 0;
|
|
656
|
+
if (Math.abs(current - start) <= tolerance) {
|
|
657
|
+
attempts = 0;
|
|
658
|
+
this.flushPendingStartTime(start, true);
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
scheduleRetry();
|
|
662
|
+
};
|
|
663
|
+
const trySeek = () => {
|
|
664
|
+
if (!this.plyr)
|
|
665
|
+
return;
|
|
666
|
+
let maybePromise = null;
|
|
667
|
+
try {
|
|
668
|
+
const result = this.seekUsingHostAPI(start, video);
|
|
669
|
+
if (result && typeof result.then === 'function') {
|
|
670
|
+
maybePromise = result;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
catch {
|
|
674
|
+
scheduleRetry();
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
if (maybePromise) {
|
|
678
|
+
maybePromise
|
|
679
|
+
.then(() => verifyAfterAttempt())
|
|
680
|
+
.catch(() => scheduleRetry());
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
verifyAfterAttempt();
|
|
684
|
+
};
|
|
685
|
+
trySeek();
|
|
686
|
+
}
|
|
687
|
+
seekUsingHostAPI(target, video) {
|
|
688
|
+
if (!Number.isFinite(target) || target < 0) {
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
if (this.config.video_host === 'vimeo') {
|
|
692
|
+
const embed = this.plyr?.embed;
|
|
693
|
+
if (embed && typeof embed.setCurrentTime === 'function') {
|
|
694
|
+
try {
|
|
695
|
+
return embed.setCurrentTime(target);
|
|
696
|
+
}
|
|
697
|
+
catch {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (video) {
|
|
703
|
+
try {
|
|
704
|
+
video.currentTime = target;
|
|
705
|
+
}
|
|
706
|
+
catch { }
|
|
707
|
+
}
|
|
708
|
+
try {
|
|
709
|
+
this.plyr.currentTime = target;
|
|
710
|
+
}
|
|
711
|
+
catch { }
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
ensureGestureOverlay() {
|
|
715
|
+
if (this.gestureOverlay && this.gestureOverlay.isConnected) {
|
|
716
|
+
return this.gestureOverlay;
|
|
717
|
+
}
|
|
718
|
+
const wrapper = this.getVideoWrapper();
|
|
719
|
+
if (!wrapper) {
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
const overlay = this.document.createElement('button');
|
|
723
|
+
overlay.type = 'button';
|
|
724
|
+
overlay.className = 'plyr-gesture-overlay';
|
|
725
|
+
overlay.style.position = 'absolute';
|
|
726
|
+
overlay.style.top = '0';
|
|
727
|
+
overlay.style.left = '0';
|
|
728
|
+
overlay.style.right = '0';
|
|
729
|
+
overlay.style.bottom = '0';
|
|
730
|
+
overlay.style.width = '100%';
|
|
731
|
+
overlay.style.height = '100%';
|
|
732
|
+
overlay.style.display = 'none';
|
|
733
|
+
overlay.style.alignItems = 'center';
|
|
734
|
+
overlay.style.justifyContent = 'center';
|
|
735
|
+
overlay.style.padding = '0 16px';
|
|
736
|
+
overlay.style.background = 'rgba(0,0,0,0.35)';
|
|
737
|
+
overlay.style.backdropFilter = 'blur(1px)';
|
|
738
|
+
overlay.style.border = '0';
|
|
739
|
+
overlay.style.zIndex = '16';
|
|
740
|
+
overlay.style.color = 'var(--theme-text-color, #fff)';
|
|
741
|
+
overlay.style.fontSize = '14px';
|
|
742
|
+
overlay.style.fontWeight = '600';
|
|
743
|
+
overlay.style.textAlign = 'center';
|
|
744
|
+
overlay.style.cursor = 'pointer';
|
|
745
|
+
overlay.style.touchAction = 'manipulation';
|
|
746
|
+
overlay.style.pointerEvents = 'none';
|
|
747
|
+
overlay.textContent = 'Toque para reproduzir';
|
|
748
|
+
wrapper.appendChild(overlay);
|
|
749
|
+
this.gestureOverlay = overlay;
|
|
750
|
+
this.updateGestureOverlaySafeZone();
|
|
751
|
+
return overlay;
|
|
752
|
+
}
|
|
753
|
+
hideGestureOverlay() {
|
|
754
|
+
if (this.gestureOverlay) {
|
|
755
|
+
this.gestureOverlay.style.display = 'none';
|
|
756
|
+
this.gestureOverlay.style.pointerEvents = 'none';
|
|
757
|
+
}
|
|
758
|
+
this.pendingGesturePlay = false;
|
|
759
|
+
}
|
|
760
|
+
requestGestureToPlay(video) {
|
|
761
|
+
if (!this.isIframeProvider()) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (this.pendingGesturePlay) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
const overlay = this.ensureGestureOverlay();
|
|
768
|
+
if (!overlay) {
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
this.pendingGesturePlay = true;
|
|
772
|
+
const media = video ?? this.videoRef?.nativeElement ?? null;
|
|
773
|
+
const onInteraction = (event) => {
|
|
774
|
+
try {
|
|
775
|
+
event.preventDefault();
|
|
776
|
+
}
|
|
777
|
+
catch { }
|
|
778
|
+
try {
|
|
779
|
+
event.stopPropagation();
|
|
780
|
+
}
|
|
781
|
+
catch { }
|
|
782
|
+
overlay.removeEventListener('click', onInteraction);
|
|
783
|
+
overlay.removeEventListener('touchend', onInteraction);
|
|
784
|
+
overlay.style.display = 'none';
|
|
785
|
+
this.pendingGesturePlay = false;
|
|
786
|
+
this.clearAutoplayUnlockListener();
|
|
787
|
+
this.setPlayerMutedState(this.requiresMutedAutoplay(), 1, media);
|
|
788
|
+
try {
|
|
789
|
+
const result = this.plyr?.play();
|
|
790
|
+
if (result && typeof result.catch === 'function') {
|
|
791
|
+
result.catch(() => {
|
|
792
|
+
this.requestGestureToPlay(media);
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
catch {
|
|
797
|
+
this.requestGestureToPlay(media);
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
overlay.addEventListener('click', onInteraction, { once: true });
|
|
801
|
+
overlay.addEventListener('touchend', onInteraction, { once: true });
|
|
802
|
+
this.updateGestureOverlaySafeZone();
|
|
803
|
+
overlay.style.pointerEvents = 'auto';
|
|
804
|
+
overlay.style.display = 'flex';
|
|
805
|
+
}
|
|
806
|
+
shouldShowGestureOverlayForError(error) {
|
|
807
|
+
if (!this.isIframeProvider()) {
|
|
808
|
+
return false;
|
|
809
|
+
}
|
|
810
|
+
if (!error) {
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
const err = error;
|
|
814
|
+
const name = typeof err.name === 'string' ? err.name.toLowerCase() : '';
|
|
815
|
+
const message = typeof err.message === 'string' ? err.message.toLowerCase() : '';
|
|
816
|
+
if (!name && !message) {
|
|
817
|
+
return true;
|
|
818
|
+
}
|
|
819
|
+
return (name.includes('notallowed') ||
|
|
820
|
+
name.includes('notallowederror') ||
|
|
821
|
+
name.includes('gesture') ||
|
|
822
|
+
message.includes('gesture') ||
|
|
823
|
+
message.includes('user interaction') ||
|
|
824
|
+
message.includes('user activation') ||
|
|
825
|
+
message.includes('without user') ||
|
|
826
|
+
message.includes('play() failed'));
|
|
827
|
+
}
|
|
828
|
+
startAutoplayFlow(video) {
|
|
829
|
+
if (!this.shouldAutoplay() || !this.plyr)
|
|
830
|
+
return;
|
|
831
|
+
if (this.deferUntilStartTimeSettles(() => this.startAutoplayFlow(video))) {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
const media = video ?? this.videoRef?.nativeElement ?? null;
|
|
835
|
+
const tryPlay = (muted) => {
|
|
836
|
+
this.setPlayerMutedState(muted, 1, media);
|
|
837
|
+
let playResult;
|
|
838
|
+
try {
|
|
839
|
+
playResult = this.plyr.play();
|
|
840
|
+
}
|
|
841
|
+
catch (error) {
|
|
842
|
+
if (!muted) {
|
|
843
|
+
tryPlay(true);
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
if (media) {
|
|
847
|
+
try {
|
|
848
|
+
const nativePlay = media.play();
|
|
849
|
+
if (nativePlay && typeof nativePlay.catch === 'function') {
|
|
850
|
+
nativePlay.catch(() => { });
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
catch { }
|
|
854
|
+
}
|
|
855
|
+
this.scheduleUserInteractionUnmute(media);
|
|
856
|
+
if (this.shouldShowGestureOverlayForError(error)) {
|
|
857
|
+
this.requestGestureToPlay(media);
|
|
858
|
+
}
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (playResult && typeof playResult.catch === 'function') {
|
|
862
|
+
playResult.catch((error) => {
|
|
863
|
+
if (!muted) {
|
|
864
|
+
tryPlay(true);
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
if (media) {
|
|
868
|
+
try {
|
|
869
|
+
const nativePlay = media.play();
|
|
870
|
+
if (nativePlay && typeof nativePlay.catch === 'function') {
|
|
871
|
+
nativePlay.catch(() => { });
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
catch { }
|
|
875
|
+
}
|
|
876
|
+
this.scheduleUserInteractionUnmute(media);
|
|
877
|
+
if (this.shouldShowGestureOverlayForError(error)) {
|
|
878
|
+
this.requestGestureToPlay(media);
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
if (muted) {
|
|
884
|
+
this.scheduleUserInteractionUnmute(media);
|
|
885
|
+
}
|
|
886
|
+
else {
|
|
887
|
+
this.clearAutoplayUnlockListener();
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
if (this.requiresMutedAutoplay()) {
|
|
891
|
+
tryPlay(true);
|
|
892
|
+
}
|
|
893
|
+
else {
|
|
894
|
+
tryPlay(false);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
480
897
|
setupControlsVisibility() {
|
|
481
898
|
const container = this.plyr?.elements?.container;
|
|
482
899
|
if (!container) {
|
|
@@ -632,11 +1049,13 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
632
1049
|
orientationLocked = false;
|
|
633
1050
|
};
|
|
634
1051
|
const onEnterFullscreen = () => {
|
|
1052
|
+
console.log('event: enterfullscreen');
|
|
635
1053
|
if (isPortrait()) {
|
|
636
1054
|
lockLandscape();
|
|
637
1055
|
}
|
|
638
1056
|
};
|
|
639
1057
|
const onExitFullscreen = () => {
|
|
1058
|
+
console.log('event: exitfullscreen');
|
|
640
1059
|
unlockOrientation();
|
|
641
1060
|
};
|
|
642
1061
|
const onOrientationChange = () => {
|
|
@@ -663,12 +1082,28 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
663
1082
|
this.fullscreenCleanup?.();
|
|
664
1083
|
this.fullscreenCleanup = undefined;
|
|
665
1084
|
this.plyr?.destroy();
|
|
1085
|
+
this.clearAutoplayUnlockListener();
|
|
1086
|
+
this.hideGestureOverlay();
|
|
666
1087
|
this.recommendationBlocker = null;
|
|
667
1088
|
const speedOptions = [1, 1.25, 1.5, 2];
|
|
668
1089
|
const locale = this.resolveLocale();
|
|
669
1090
|
const captionsLanguage = this.resolveCaptionsLanguage(locale) ?? 'pt';
|
|
670
1091
|
const hideVimeoRecommendations = this.shouldHideVimeoRecommendations();
|
|
671
1092
|
const vimeoPremium = Boolean(this.config?.vimeo_premium);
|
|
1093
|
+
const shouldAutoplay = this.shouldAutoplay();
|
|
1094
|
+
const startMuted = this.requiresMutedAutoplay();
|
|
1095
|
+
try {
|
|
1096
|
+
this.videoRef.nativeElement.muted = startMuted;
|
|
1097
|
+
}
|
|
1098
|
+
catch { }
|
|
1099
|
+
try {
|
|
1100
|
+
this.videoRef.nativeElement.playsInline = true;
|
|
1101
|
+
}
|
|
1102
|
+
catch { }
|
|
1103
|
+
try {
|
|
1104
|
+
this.videoRef.nativeElement.autoplay = shouldAutoplay;
|
|
1105
|
+
}
|
|
1106
|
+
catch { }
|
|
672
1107
|
const vimeoOptions = {
|
|
673
1108
|
byline: false,
|
|
674
1109
|
portrait: false,
|
|
@@ -680,6 +1115,9 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
680
1115
|
quality: "auto",
|
|
681
1116
|
transparent: false,
|
|
682
1117
|
};
|
|
1118
|
+
vimeoOptions.autoplay = shouldAutoplay;
|
|
1119
|
+
vimeoOptions.muted = startMuted;
|
|
1120
|
+
vimeoOptions.playsinline = true;
|
|
683
1121
|
if (hideVimeoRecommendations) {
|
|
684
1122
|
vimeoOptions.controls = false;
|
|
685
1123
|
vimeoOptions.sidedock = 0;
|
|
@@ -695,6 +1133,9 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
695
1133
|
youtubePlayerVars.playerVars = {
|
|
696
1134
|
hl: locale,
|
|
697
1135
|
cc_lang_pref: captionsLanguage || locale.split('-')[0]?.toLowerCase(),
|
|
1136
|
+
autoplay: shouldAutoplay ? 1 : 0,
|
|
1137
|
+
mute: startMuted ? 1 : 0,
|
|
1138
|
+
playsinline: 1,
|
|
698
1139
|
};
|
|
699
1140
|
if (captionsLanguage) {
|
|
700
1141
|
youtubePlayerVars.playerVars.cc_load_policy = 1;
|
|
@@ -732,7 +1173,8 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
732
1173
|
clickToPlay: true,
|
|
733
1174
|
hideControls: false,
|
|
734
1175
|
keyboard: { focused: true, global: false },
|
|
735
|
-
|
|
1176
|
+
autoplay: shouldAutoplay,
|
|
1177
|
+
muted: startMuted,
|
|
736
1178
|
};
|
|
737
1179
|
plyrOptions.hl = locale;
|
|
738
1180
|
if (captionsLanguage) {
|
|
@@ -760,8 +1202,7 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
760
1202
|
const apply = () => {
|
|
761
1203
|
const dur = this.plyr.duration || 0;
|
|
762
1204
|
const start = this.resolveStartTime(this.config.last_time, this.config.last_percent, dur);
|
|
763
|
-
|
|
764
|
-
this.plyr.currentTime = start;
|
|
1205
|
+
this.requestStartTimeSeek(start);
|
|
765
1206
|
this.plyr.off("ready", apply);
|
|
766
1207
|
};
|
|
767
1208
|
this.plyr.on("ready", apply);
|
|
@@ -790,12 +1231,15 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
790
1231
|
});
|
|
791
1232
|
};
|
|
792
1233
|
this.plyr?.on?.("play", () => {
|
|
1234
|
+
this.retryPendingStartTime();
|
|
1235
|
+
this.hideGestureOverlay();
|
|
793
1236
|
this.clearVimeoEndedState();
|
|
794
1237
|
this.playbackEnded = false;
|
|
795
1238
|
this.overlayBlockAll = false;
|
|
796
1239
|
this.updateRecommendationBlockerSafeZone();
|
|
797
1240
|
this.toggleRecommendationBlocker(false);
|
|
798
1241
|
parent.postMessage('playing_video', "*");
|
|
1242
|
+
console.log('event: playing_video');
|
|
799
1243
|
this.postCastEvent({ event: 'play', currentTime: this.plyr.currentTime || 0 });
|
|
800
1244
|
});
|
|
801
1245
|
this.plyr?.on?.("timeupdate", onTimeUpdate);
|
|
@@ -813,6 +1257,7 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
813
1257
|
this.playbackEnded = true;
|
|
814
1258
|
this.overlayBlockAll = true;
|
|
815
1259
|
this.updateRecommendationBlockerSafeZone();
|
|
1260
|
+
console.log('event: ended');
|
|
816
1261
|
parent.postMessage('event: ended', "*");
|
|
817
1262
|
this.postCastEvent({ event: 'ended', currentTime: this.plyr.currentTime || 0 });
|
|
818
1263
|
this.progressService.ended$.next();
|
|
@@ -821,7 +1266,7 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
821
1266
|
});
|
|
822
1267
|
}
|
|
823
1268
|
unmuteAfterDelay(video, delayMs = 2000, volume = 1) {
|
|
824
|
-
if (!this.
|
|
1269
|
+
if (!this.shouldAutoplay())
|
|
825
1270
|
return;
|
|
826
1271
|
setTimeout(() => {
|
|
827
1272
|
try {
|
|
@@ -876,13 +1321,8 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
876
1321
|
const onReady = () => {
|
|
877
1322
|
this.plyr.off("ready", onReady);
|
|
878
1323
|
const start = this.resolveStartTime(this.config.last_time, this.config.last_percent, this.plyr.duration);
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
if (this.config.autoplay || this.config.is_live) {
|
|
882
|
-
setTimeout(() => {
|
|
883
|
-
this.plyr.play();
|
|
884
|
-
}, 1500);
|
|
885
|
-
}
|
|
1324
|
+
this.requestStartTimeSeek(start);
|
|
1325
|
+
this.startAutoplayFlow();
|
|
886
1326
|
parent.postMessage('playerIsReadyToPlay', "*");
|
|
887
1327
|
parent.postMessage('duration:' + this.plyr.duration, "*");
|
|
888
1328
|
console.log('event: current_time ' + this.plyr.currentTime);
|
|
@@ -944,35 +1384,8 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
944
1384
|
const onLoadedMeta = () => {
|
|
945
1385
|
const dur = this.plyr.duration || video.duration || 0;
|
|
946
1386
|
const start = this.resolveStartTime(this.config.last_time, this.config.last_percent, dur);
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
this.plyr.currentTime = start;
|
|
950
|
-
}
|
|
951
|
-
catch {
|
|
952
|
-
try {
|
|
953
|
-
video.currentTime = start;
|
|
954
|
-
}
|
|
955
|
-
catch { }
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
if (this.config.autoplay) {
|
|
959
|
-
try {
|
|
960
|
-
video.muted = true;
|
|
961
|
-
}
|
|
962
|
-
catch { }
|
|
963
|
-
setTimeout(() => {
|
|
964
|
-
try {
|
|
965
|
-
this.plyr.play();
|
|
966
|
-
}
|
|
967
|
-
catch {
|
|
968
|
-
try {
|
|
969
|
-
video.play();
|
|
970
|
-
}
|
|
971
|
-
catch { }
|
|
972
|
-
}
|
|
973
|
-
this.unmuteAfterDelay(video);
|
|
974
|
-
}, 250);
|
|
975
|
-
}
|
|
1387
|
+
this.requestStartTimeSeek(start, { video });
|
|
1388
|
+
this.startAutoplayFlow(video);
|
|
976
1389
|
video.removeEventListener("loadedmetadata", onLoadedMeta);
|
|
977
1390
|
};
|
|
978
1391
|
video.addEventListener("loadedmetadata", onLoadedMeta);
|
|
@@ -986,17 +1399,8 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
986
1399
|
this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
|
987
1400
|
const dur = video.duration || 0;
|
|
988
1401
|
const start = this.resolveStartTime(this.config.last_time, this.config.last_percent, dur);
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
video.currentTime = start;
|
|
992
|
-
}
|
|
993
|
-
catch { }
|
|
994
|
-
}
|
|
995
|
-
if (this.config.autoplay) {
|
|
996
|
-
video.muted = true;
|
|
997
|
-
video.play().catch(() => { });
|
|
998
|
-
this.unmuteAfterDelay(video);
|
|
999
|
-
}
|
|
1402
|
+
this.requestStartTimeSeek(start, { video });
|
|
1403
|
+
this.startAutoplayFlow(video);
|
|
1000
1404
|
});
|
|
1001
1405
|
this.hls.on(Hls.Events.ERROR, (_evt, data) => {
|
|
1002
1406
|
if (data?.fatal) {
|
|
@@ -1085,6 +1489,7 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
1085
1489
|
this.hls?.destroy();
|
|
1086
1490
|
this.controlsVisibilityCleanup?.();
|
|
1087
1491
|
this.controlsVisibilityCleanup = undefined;
|
|
1492
|
+
this.clearAutoplayUnlockListener();
|
|
1088
1493
|
const container = this.plyr?.elements?.container;
|
|
1089
1494
|
container?.classList.remove("plyr--vimeo-ended");
|
|
1090
1495
|
if (this.recommendationBlocker?.parentElement) {
|
|
@@ -1111,6 +1516,14 @@ ${allPairs.map(([n, v]) => ` ${n}: ${v};`).join('\n')}
|
|
|
1111
1516
|
catch { }
|
|
1112
1517
|
}
|
|
1113
1518
|
this.topClickBlocker = null;
|
|
1519
|
+
if (this.gestureOverlay?.parentElement) {
|
|
1520
|
+
try {
|
|
1521
|
+
this.gestureOverlay.parentElement.removeChild(this.gestureOverlay);
|
|
1522
|
+
}
|
|
1523
|
+
catch { }
|
|
1524
|
+
}
|
|
1525
|
+
this.gestureOverlay = null;
|
|
1526
|
+
this.pendingGesturePlay = false;
|
|
1114
1527
|
this.menuObserver?.disconnect();
|
|
1115
1528
|
this.menuObserver = undefined;
|
|
1116
1529
|
window.removeEventListener('resize', this.onResize);
|