unified-video-framework 1.4.147 → 1.4.149
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unified-video-framework",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.149",
|
|
4
4
|
"description": "Cross-platform video player framework supporting iOS, Android, Web, Smart TVs (Samsung/LG), Roku, and more",
|
|
5
5
|
"main": "packages/core/dist/index.js",
|
|
6
6
|
"types": "packages/core/dist/index.d.ts",
|
|
@@ -51,6 +51,7 @@ export declare class WebPlayer extends BasePlayer {
|
|
|
51
51
|
private _TOGGLE_DEBOUNCE_MS;
|
|
52
52
|
private hasTriedButtonFallback;
|
|
53
53
|
private lastUserInteraction;
|
|
54
|
+
private showTimeTooltip;
|
|
54
55
|
private debugLog;
|
|
55
56
|
private debugError;
|
|
56
57
|
private debugWarn;
|
|
@@ -69,6 +70,12 @@ export declare class WebPlayer extends BasePlayer {
|
|
|
69
70
|
protected loadScript(src: string): Promise<void>;
|
|
70
71
|
private loadSubtitles;
|
|
71
72
|
private isAbortPlayError;
|
|
73
|
+
private isAutoplayRestrictionError;
|
|
74
|
+
private showPlayOverlay;
|
|
75
|
+
private hidePlayOverlay;
|
|
76
|
+
private updateTimeTooltip;
|
|
77
|
+
private hideTimeTooltip;
|
|
78
|
+
private setupUserInteractionTracking;
|
|
72
79
|
play(): Promise<void>;
|
|
73
80
|
pause(): void;
|
|
74
81
|
requestPause(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebPlayer.d.ts","sourceRoot":"","sources":["../src/WebPlayer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAUjD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,GAAG,EAAE,GAAG,CAAC;QACT,MAAM,EAAE,GAAG,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;KACxD;CACF;AAED,qBAAa,SAAU,SAAQ,UAAU;IACvC,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAChD,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,mBAAmB,CAAc;IACzC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,UAAU,CAAkB;IAGpC,OAAO,CAAC,cAAc,CAKpB;IACF,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAA4B;IAEjD,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,iBAAiB,CAAkB;IAG3C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,yBAAyB,CAAa;IAC9C,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,mBAAmB,CAAiB;IAC5C,OAAO,CAAC,KAAK,CAAa;IAG1B,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,mBAAmB,CAAO;IAGlC,OAAO,CAAC,sBAAsB,CAAkB;IAChD,OAAO,CAAC,mBAAmB,CAAa;IAGxC,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,SAAS;IAOX,UAAU,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;cA4B9D,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"WebPlayer.d.ts","sourceRoot":"","sources":["../src/WebPlayer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAUjD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,GAAG,EAAE,GAAG,CAAC;QACT,MAAM,EAAE,GAAG,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;KACxD;CACF;AAED,qBAAa,SAAU,SAAQ,UAAU;IACvC,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAChD,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,mBAAmB,CAAc;IACzC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,UAAU,CAAkB;IAGpC,OAAO,CAAC,cAAc,CAKpB;IACF,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAA4B;IAEjD,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,iBAAiB,CAAkB;IAG3C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,yBAAyB,CAAa;IAC9C,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,mBAAmB,CAAiB;IAC5C,OAAO,CAAC,KAAK,CAAa;IAG1B,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,mBAAmB,CAAO;IAGlC,OAAO,CAAC,sBAAsB,CAAkB;IAChD,OAAO,CAAC,mBAAmB,CAAa;IAGxC,OAAO,CAAC,eAAe,CAAkB;IAGzC,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,SAAS;IAOX,UAAU,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;cA4B9D,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAkJ5C,OAAO,CAAC,wBAAwB;IAsHhC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,oBAAoB;IAYtB,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDtC,OAAO,CAAC,gBAAgB;YAcV,OAAO;IAiErB,OAAO,CAAC,cAAc;YAyBR,QAAQ;IA4DtB,OAAO,CAAC,iBAAiB;YAQX,UAAU;IAMxB,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhD,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,0BAA0B;IAkBlC,OAAO,CAAC,eAAe;IAkHvB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,4BAA4B;IAsB9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyD3B,KAAK,IAAI,IAAI;IAkBN,YAAY,IAAI,IAAI;IAO3B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAwBxB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B,IAAI,IAAI,IAAI;IAMZ,MAAM,IAAI,IAAI;IAOd,cAAc,IAAI,MAAM;IAOxB,YAAY,IAAI,GAAG,EAAE;IAIrB,iBAAiB,IAAI,GAAG;IAIxB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAW/B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOnC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAkBhC,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAwDhC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC/B,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAetC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3C,WAAW,IAAI,IAAI;IAUnB,iBAAiB,IAAI,IAAI;IAUzB,OAAO,CAAC,cAAc;YAmBR,0BAA0B;IAwCxC,OAAO,CAAC,eAAe;IAwCvB,uBAAuB,IAAI,IAAI;IA4D/B,OAAO,CAAC,4BAA4B;YAoEtB,gCAAgC;IAgBxC,+BAA+B,IAAI,OAAO,CAAC,IAAI,CAAC;IAkGtD,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAmC3C,4BAA4B,IAAI,IAAI;IA4D9B,gCAAgC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IA8DtE,0BAA0B,IAAI,IAAI;IAqK5B,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IA4C3C,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAc9C,SAAS,CAAC,eAAe,IAAI,IAAI;IASjC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAi6FrB,OAAO,CAAC,uBAAuB;IA4DjC,OAAO,CAAC,oBAAoB;IAyU5B,OAAO,CAAC,2BAA2B;IA4bnC,SAAS,CAAC,sBAAsB,IAAI,IAAI;IAoLxC,SAAS,CAAC,cAAc,IAAI,IAAI;IAmKzB,gBAAgB,CAAC,MAAM,EAAE,GAAG;IA2CnC,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,sBAAsB;IAsDvB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAetC,oBAAoB,IAAI,IAAI;IAO5B,kBAAkB,IAAI,IAAI;IAOjC,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,oBAAoB;IA4B5B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,wBAAwB;IAyEhC,OAAO,CAAC,qBAAqB;IA8FtB,yBAAyB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI;IAiBxE,0BAA0B,CAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAwB1F,OAAO,CAAC,oCAAoC;IAqBrC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IA2DjC,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,iBAAiB;YAgCX,SAAS;IAYvB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,gBAAgB;IA6BxB,OAAO,CAAC,uBAAuB;IAoB/B,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,uBAAuB;IA6D/B,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,qBAAqB;IAoH7B,OAAO,CAAC,wBAAwB;IA+ChC,OAAO,CAAC,wBAAwB;IA6BhC,OAAO,CAAC,2BAA2B;IAkDnC,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,0BAA0B;IAgBlC,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,sBAAsB;IA4B9B,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,WAAW;YAoBL,QAAQ;YAqGR,UAAU;IAqBxB,OAAO,CAAC,gBAAgB;IA2CxB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,YAAY;IA6BpB,OAAO,CAAC,sBAAsB;IA6B9B,OAAO,CAAC,sBAAsB;IAiF9B,OAAO,CAAC,uBAAuB;IAuB/B,OAAO,CAAC,4BAA4B;IAoDpC,OAAO,CAAC,oBAAoB;IA+BrB,aAAa,IAAI,IAAI;IAarB,aAAa,IAAI,IAAI;IAYrB,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAe9B,kBAAkB,IAAI,OAAO;YAKtB,OAAO;IAgBf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA2C/B"}
|
|
@@ -49,6 +49,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
49
49
|
this._TOGGLE_DEBOUNCE_MS = 120;
|
|
50
50
|
this.hasTriedButtonFallback = false;
|
|
51
51
|
this.lastUserInteraction = 0;
|
|
52
|
+
this.showTimeTooltip = false;
|
|
52
53
|
}
|
|
53
54
|
debugLog(message, ...args) {
|
|
54
55
|
if (this.config.debug) {
|
|
@@ -100,7 +101,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
100
101
|
this.video.className = 'uvf-video';
|
|
101
102
|
this.video.controls = false;
|
|
102
103
|
this.video.autoplay = this.config.autoPlay ?? false;
|
|
103
|
-
this.video.muted = this.config.muted ?? false;
|
|
104
|
+
this.video.muted = this.config.autoPlay ? true : (this.config.muted ?? false);
|
|
104
105
|
this.video.loop = this.config.loop ?? false;
|
|
105
106
|
this.video.playsInline = this.config.playsInline ?? true;
|
|
106
107
|
this.video.preload = this.config.preload ?? 'metadata';
|
|
@@ -123,6 +124,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
123
124
|
this.setupKeyboardShortcuts();
|
|
124
125
|
this.setupWatermark();
|
|
125
126
|
this.setupFullscreenListeners();
|
|
127
|
+
this.setupUserInteractionTracking();
|
|
126
128
|
try {
|
|
127
129
|
const pw = this.config.paywall || null;
|
|
128
130
|
if (pw && pw.enabled) {
|
|
@@ -395,7 +397,15 @@ export class WebPlayer extends BasePlayer {
|
|
|
395
397
|
}));
|
|
396
398
|
this.updateSettingsMenu();
|
|
397
399
|
if (this.config.autoPlay) {
|
|
398
|
-
this.play()
|
|
400
|
+
this.play().catch(error => {
|
|
401
|
+
if (this.isAutoplayRestrictionError(error)) {
|
|
402
|
+
this.debugWarn('HLS autoplay blocked, showing play overlay');
|
|
403
|
+
this.showPlayOverlay();
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
this.debugError('HLS autoplay failed:', error);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
399
409
|
}
|
|
400
410
|
});
|
|
401
411
|
this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {
|
|
@@ -531,6 +541,157 @@ export class WebPlayer extends BasePlayer {
|
|
|
531
541
|
return !!err && ((err.name === 'AbortError') ||
|
|
532
542
|
(typeof err.message === 'string' && /interrupted by a call to pause\(\)/i.test(err.message)));
|
|
533
543
|
}
|
|
544
|
+
isAutoplayRestrictionError(err) {
|
|
545
|
+
if (!err)
|
|
546
|
+
return false;
|
|
547
|
+
const message = (err.message || '').toLowerCase();
|
|
548
|
+
const name = (err.name || '').toLowerCase();
|
|
549
|
+
return (name === 'notallowederror' ||
|
|
550
|
+
message.includes('user didn\'t interact') ||
|
|
551
|
+
message.includes('autoplay') ||
|
|
552
|
+
message.includes('gesture') ||
|
|
553
|
+
message.includes('user activation') ||
|
|
554
|
+
message.includes('play() failed') ||
|
|
555
|
+
message.includes('user interaction'));
|
|
556
|
+
}
|
|
557
|
+
showPlayOverlay() {
|
|
558
|
+
this.hidePlayOverlay();
|
|
559
|
+
const overlay = document.createElement('div');
|
|
560
|
+
overlay.id = 'uvf-play-overlay';
|
|
561
|
+
overlay.className = 'uvf-play-overlay';
|
|
562
|
+
const playButton = document.createElement('button');
|
|
563
|
+
playButton.className = 'uvf-play-button';
|
|
564
|
+
playButton.innerHTML = `
|
|
565
|
+
<svg viewBox="0 0 24 24" fill="currentColor">
|
|
566
|
+
<path d="M8 5v14l11-7z"/>
|
|
567
|
+
</svg>
|
|
568
|
+
`;
|
|
569
|
+
const message = document.createElement('div');
|
|
570
|
+
message.className = 'uvf-play-message';
|
|
571
|
+
message.textContent = 'Click to play';
|
|
572
|
+
overlay.appendChild(playButton);
|
|
573
|
+
overlay.appendChild(message);
|
|
574
|
+
playButton.addEventListener('click', async (e) => {
|
|
575
|
+
e.stopPropagation();
|
|
576
|
+
this.lastUserInteraction = Date.now();
|
|
577
|
+
try {
|
|
578
|
+
await this.play();
|
|
579
|
+
}
|
|
580
|
+
catch (error) {
|
|
581
|
+
this.debugError('Failed to play after user interaction:', error);
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
overlay.addEventListener('click', async (e) => {
|
|
585
|
+
if (e.target === overlay) {
|
|
586
|
+
e.stopPropagation();
|
|
587
|
+
this.lastUserInteraction = Date.now();
|
|
588
|
+
try {
|
|
589
|
+
await this.play();
|
|
590
|
+
}
|
|
591
|
+
catch (error) {
|
|
592
|
+
this.debugError('Failed to play after user interaction:', error);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
const style = document.createElement('style');
|
|
597
|
+
style.textContent = `
|
|
598
|
+
.uvf-play-overlay {
|
|
599
|
+
position: absolute;
|
|
600
|
+
top: 0;
|
|
601
|
+
left: 0;
|
|
602
|
+
width: 100%;
|
|
603
|
+
height: 100%;
|
|
604
|
+
background: rgba(0, 0, 0, 0.7);
|
|
605
|
+
display: flex;
|
|
606
|
+
flex-direction: column;
|
|
607
|
+
justify-content: center;
|
|
608
|
+
align-items: center;
|
|
609
|
+
z-index: 1000;
|
|
610
|
+
cursor: pointer;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
.uvf-play-button {
|
|
614
|
+
width: 80px;
|
|
615
|
+
height: 80px;
|
|
616
|
+
border-radius: 50%;
|
|
617
|
+
background: rgba(255, 255, 255, 0.9);
|
|
618
|
+
border: none;
|
|
619
|
+
color: #000;
|
|
620
|
+
cursor: pointer;
|
|
621
|
+
display: flex;
|
|
622
|
+
align-items: center;
|
|
623
|
+
justify-content: center;
|
|
624
|
+
transition: all 0.3s ease;
|
|
625
|
+
margin-bottom: 16px;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.uvf-play-button:hover {
|
|
629
|
+
background: #fff;
|
|
630
|
+
transform: scale(1.1);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.uvf-play-button svg {
|
|
634
|
+
width: 32px;
|
|
635
|
+
height: 32px;
|
|
636
|
+
margin-left: 4px;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.uvf-play-message {
|
|
640
|
+
color: white;
|
|
641
|
+
font-size: 16px;
|
|
642
|
+
font-weight: 500;
|
|
643
|
+
text-align: center;
|
|
644
|
+
opacity: 0.9;
|
|
645
|
+
}
|
|
646
|
+
`;
|
|
647
|
+
if (!document.getElementById('uvf-play-overlay-styles')) {
|
|
648
|
+
style.id = 'uvf-play-overlay-styles';
|
|
649
|
+
document.head.appendChild(style);
|
|
650
|
+
}
|
|
651
|
+
if (this.playerWrapper) {
|
|
652
|
+
this.playerWrapper.appendChild(overlay);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
hidePlayOverlay() {
|
|
656
|
+
const overlay = document.getElementById('uvf-play-overlay');
|
|
657
|
+
if (overlay) {
|
|
658
|
+
overlay.remove();
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
updateTimeTooltip(e) {
|
|
662
|
+
const progressBar = document.getElementById('uvf-progress-bar');
|
|
663
|
+
const tooltip = document.getElementById('uvf-time-tooltip');
|
|
664
|
+
if (!progressBar || !tooltip || !this.video)
|
|
665
|
+
return;
|
|
666
|
+
const rect = progressBar.getBoundingClientRect();
|
|
667
|
+
const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
|
|
668
|
+
const percent = (x / rect.width);
|
|
669
|
+
const time = percent * this.video.duration;
|
|
670
|
+
tooltip.textContent = this.formatTime(time);
|
|
671
|
+
tooltip.style.left = `${x}px`;
|
|
672
|
+
tooltip.classList.add('visible');
|
|
673
|
+
}
|
|
674
|
+
hideTimeTooltip() {
|
|
675
|
+
const tooltip = document.getElementById('uvf-time-tooltip');
|
|
676
|
+
if (tooltip) {
|
|
677
|
+
tooltip.classList.remove('visible');
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
setupUserInteractionTracking() {
|
|
681
|
+
const interactionEvents = ['click', 'mousedown', 'keydown', 'touchstart'];
|
|
682
|
+
const updateLastInteraction = () => {
|
|
683
|
+
this.lastUserInteraction = Date.now();
|
|
684
|
+
this.debugLog('User interaction detected at:', this.lastUserInteraction);
|
|
685
|
+
};
|
|
686
|
+
interactionEvents.forEach(eventType => {
|
|
687
|
+
document.addEventListener(eventType, updateLastInteraction, { passive: true });
|
|
688
|
+
});
|
|
689
|
+
if (this.playerWrapper) {
|
|
690
|
+
interactionEvents.forEach(eventType => {
|
|
691
|
+
this.playerWrapper.addEventListener(eventType, updateLastInteraction, { passive: true });
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
}
|
|
534
695
|
async play() {
|
|
535
696
|
if (!this.video)
|
|
536
697
|
throw new Error('Video element not initialized');
|
|
@@ -554,6 +715,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
554
715
|
this._deferredPause = false;
|
|
555
716
|
this.video.pause();
|
|
556
717
|
}
|
|
718
|
+
this.hidePlayOverlay();
|
|
557
719
|
await super.play();
|
|
558
720
|
}
|
|
559
721
|
catch (err) {
|
|
@@ -561,6 +723,11 @@ export class WebPlayer extends BasePlayer {
|
|
|
561
723
|
if (this.isAbortPlayError(err)) {
|
|
562
724
|
return;
|
|
563
725
|
}
|
|
726
|
+
if (this.isAutoplayRestrictionError(err)) {
|
|
727
|
+
this.debugWarn('Autoplay blocked by browser policy - showing play overlay');
|
|
728
|
+
this.showPlayOverlay();
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
564
731
|
this.handleError({
|
|
565
732
|
code: 'PLAY_ERROR',
|
|
566
733
|
message: `Failed to start playbook: ${err}`,
|
|
@@ -1690,10 +1857,22 @@ export class WebPlayer extends BasePlayer {
|
|
|
1690
1857
|
width: 100%;
|
|
1691
1858
|
position: relative;
|
|
1692
1859
|
cursor: pointer;
|
|
1693
|
-
padding:
|
|
1860
|
+
padding: 6px 0;
|
|
1694
1861
|
overflow: visible;
|
|
1695
1862
|
}
|
|
1696
1863
|
|
|
1864
|
+
/* Extended touch area for better mobile UX without affecting visual spacing */
|
|
1865
|
+
.uvf-progress-bar-wrapper::before {
|
|
1866
|
+
content: '';
|
|
1867
|
+
position: absolute;
|
|
1868
|
+
top: -8px;
|
|
1869
|
+
bottom: -8px;
|
|
1870
|
+
left: 0;
|
|
1871
|
+
right: 0;
|
|
1872
|
+
cursor: pointer;
|
|
1873
|
+
z-index: 10;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1697
1876
|
.uvf-progress-bar {
|
|
1698
1877
|
width: 100%;
|
|
1699
1878
|
height: 2px;
|
|
@@ -1774,30 +1953,102 @@ export class WebPlayer extends BasePlayer {
|
|
|
1774
1953
|
left: 0;
|
|
1775
1954
|
height: 100%;
|
|
1776
1955
|
background: linear-gradient(90deg,
|
|
1777
|
-
#ff4500 0%,
|
|
1778
|
-
#ff5722 25%,
|
|
1779
|
-
#ff6b35 50%,
|
|
1780
|
-
#ff7043 75%,
|
|
1781
|
-
#ff8c69 100%
|
|
1956
|
+
var(--uvf-accent-1, #ff4500) 0%,
|
|
1957
|
+
var(--uvf-accent-1, #ff5722) 25%,
|
|
1958
|
+
var(--uvf-accent-2, #ff6b35) 50%,
|
|
1959
|
+
var(--uvf-accent-2, #ff7043) 75%,
|
|
1960
|
+
var(--uvf-accent-2, #ff8c69) 100%
|
|
1782
1961
|
);
|
|
1783
1962
|
border-radius: 4px;
|
|
1784
1963
|
pointer-events: none;
|
|
1785
1964
|
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
1786
1965
|
z-index: 2;
|
|
1787
|
-
box-shadow: 0 0 12px rgba(255, 87, 34, 0.3);
|
|
1966
|
+
box-shadow: 0 0 12px var(--uvf-accent-1-20, rgba(255, 87, 34, 0.3));
|
|
1788
1967
|
}
|
|
1789
1968
|
|
|
1790
1969
|
.uvf-progress-bar-wrapper:hover .uvf-progress-filled {
|
|
1791
1970
|
border-radius: 6px;
|
|
1792
1971
|
background: linear-gradient(90deg,
|
|
1793
|
-
#ff4500 0%,
|
|
1794
|
-
#ff5722 20%,
|
|
1795
|
-
#ff6b35 40%,
|
|
1796
|
-
#ff7043 60%,
|
|
1797
|
-
#ff8c69 80%,
|
|
1798
|
-
#ffa500 100%
|
|
1972
|
+
var(--uvf-accent-1, #ff4500) 0%,
|
|
1973
|
+
var(--uvf-accent-1, #ff5722) 20%,
|
|
1974
|
+
var(--uvf-accent-2, #ff6b35) 40%,
|
|
1975
|
+
var(--uvf-accent-2, #ff7043) 60%,
|
|
1976
|
+
var(--uvf-accent-2, #ff8c69) 80%,
|
|
1977
|
+
var(--uvf-accent-2, #ffa500) 100%
|
|
1799
1978
|
);
|
|
1800
|
-
box-shadow: 0 0 20px rgba(255, 87, 34, 0.5);
|
|
1979
|
+
box-shadow: 0 0 20px var(--uvf-accent-1-20, rgba(255, 87, 34, 0.5));
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
/* Progress Bar Handle/Thumb */
|
|
1983
|
+
.uvf-progress-handle {
|
|
1984
|
+
position: absolute;
|
|
1985
|
+
top: 50%;
|
|
1986
|
+
left: 0;
|
|
1987
|
+
width: 14px;
|
|
1988
|
+
height: 14px;
|
|
1989
|
+
background: #fff;
|
|
1990
|
+
border: 2px solid var(--uvf-accent-1, #ff5722);
|
|
1991
|
+
border-radius: 50%;
|
|
1992
|
+
transform: translate(-50%, -50%);
|
|
1993
|
+
cursor: grab;
|
|
1994
|
+
opacity: 0;
|
|
1995
|
+
transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
1996
|
+
z-index: 3;
|
|
1997
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
.uvf-progress-bar-wrapper:hover .uvf-progress-handle {
|
|
2001
|
+
opacity: 1;
|
|
2002
|
+
transform: translate(-50%, -50%) scale(1);
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
.uvf-progress-handle:hover {
|
|
2006
|
+
transform: translate(-50%, -50%) scale(1.2);
|
|
2007
|
+
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.4);
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
.uvf-progress-handle:active,
|
|
2011
|
+
.uvf-progress-handle.dragging {
|
|
2012
|
+
cursor: grabbing;
|
|
2013
|
+
transform: translate(-50%, -50%) scale(1.3);
|
|
2014
|
+
box-shadow: 0 4px 16px rgba(255, 87, 34, 0.4);
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
/* Time Tooltip */
|
|
2018
|
+
.uvf-time-tooltip {
|
|
2019
|
+
position: absolute;
|
|
2020
|
+
bottom: 100%;
|
|
2021
|
+
left: 0;
|
|
2022
|
+
margin-bottom: 8px;
|
|
2023
|
+
padding: 4px 8px;
|
|
2024
|
+
background: rgba(0, 0, 0, 0.8);
|
|
2025
|
+
color: #fff;
|
|
2026
|
+
font-size: 12px;
|
|
2027
|
+
font-weight: 500;
|
|
2028
|
+
border-radius: 4px;
|
|
2029
|
+
white-space: nowrap;
|
|
2030
|
+
opacity: 0;
|
|
2031
|
+
transform: translateX(-50%) translateY(4px);
|
|
2032
|
+
transition: all 0.2s ease;
|
|
2033
|
+
pointer-events: none;
|
|
2034
|
+
z-index: 20;
|
|
2035
|
+
backdrop-filter: blur(4px);
|
|
2036
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
.uvf-time-tooltip::after {
|
|
2040
|
+
content: '';
|
|
2041
|
+
position: absolute;
|
|
2042
|
+
top: 100%;
|
|
2043
|
+
left: 50%;
|
|
2044
|
+
transform: translateX(-50%);
|
|
2045
|
+
border: 4px solid transparent;
|
|
2046
|
+
border-top-color: rgba(0, 0, 0, 0.8);
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
.uvf-time-tooltip.visible {
|
|
2050
|
+
opacity: 1;
|
|
2051
|
+
transform: translateX(-50%) translateY(0);
|
|
1801
2052
|
}
|
|
1802
2053
|
|
|
1803
2054
|
|
|
@@ -1805,7 +2056,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
1805
2056
|
/* Mobile responsive design with enhanced touch targets */
|
|
1806
2057
|
@media (max-width: 768px) {
|
|
1807
2058
|
.uvf-progress-bar-wrapper {
|
|
1808
|
-
padding:
|
|
2059
|
+
padding: 8px 0; /* Optimized touch area */
|
|
1809
2060
|
}
|
|
1810
2061
|
|
|
1811
2062
|
.uvf-progress-bar {
|
|
@@ -4405,7 +4656,9 @@ export class WebPlayer extends BasePlayer {
|
|
|
4405
4656
|
<div class="uvf-progress-bar">
|
|
4406
4657
|
<div class="uvf-progress-buffered" id="uvf-progress-buffered"></div>
|
|
4407
4658
|
<div class="uvf-progress-filled" id="uvf-progress-filled"></div>
|
|
4659
|
+
<div class="uvf-progress-handle" id="uvf-progress-handle"></div>
|
|
4408
4660
|
</div>
|
|
4661
|
+
<div class="uvf-time-tooltip" id="uvf-time-tooltip">00:00</div>
|
|
4409
4662
|
`;
|
|
4410
4663
|
progressSection.appendChild(progressBar);
|
|
4411
4664
|
const controlsRow = document.createElement('div');
|
|
@@ -4702,6 +4955,24 @@ export class WebPlayer extends BasePlayer {
|
|
|
4702
4955
|
this.isDragging = true;
|
|
4703
4956
|
this.handleProgressChange(e);
|
|
4704
4957
|
});
|
|
4958
|
+
progressBar?.addEventListener('mouseenter', () => {
|
|
4959
|
+
this.showTimeTooltip = true;
|
|
4960
|
+
});
|
|
4961
|
+
progressBar?.addEventListener('mouseleave', () => {
|
|
4962
|
+
this.showTimeTooltip = false;
|
|
4963
|
+
this.hideTimeTooltip();
|
|
4964
|
+
});
|
|
4965
|
+
progressBar?.addEventListener('mousemove', (e) => {
|
|
4966
|
+
if (!this.isDragging && this.showTimeTooltip) {
|
|
4967
|
+
this.updateTimeTooltip(e);
|
|
4968
|
+
}
|
|
4969
|
+
});
|
|
4970
|
+
progressBar?.addEventListener('touchstart', (e) => {
|
|
4971
|
+
e.preventDefault();
|
|
4972
|
+
this.isDragging = true;
|
|
4973
|
+
const touch = e.touches[0];
|
|
4974
|
+
this.handleProgressChange(touch);
|
|
4975
|
+
}, { passive: false });
|
|
4705
4976
|
document.addEventListener('mousemove', (e) => {
|
|
4706
4977
|
if (this.isVolumeSliding) {
|
|
4707
4978
|
this.handleVolumeChange(e);
|
|
@@ -4710,6 +4981,13 @@ export class WebPlayer extends BasePlayer {
|
|
|
4710
4981
|
this.handleProgressChange(e);
|
|
4711
4982
|
}
|
|
4712
4983
|
});
|
|
4984
|
+
document.addEventListener('touchmove', (e) => {
|
|
4985
|
+
if (this.isDragging && progressBar) {
|
|
4986
|
+
e.preventDefault();
|
|
4987
|
+
const touch = e.touches[0];
|
|
4988
|
+
this.handleProgressChange(touch);
|
|
4989
|
+
}
|
|
4990
|
+
}, { passive: false });
|
|
4713
4991
|
document.addEventListener('mouseup', () => {
|
|
4714
4992
|
if (this.isVolumeSliding) {
|
|
4715
4993
|
this.isVolumeSliding = false;
|
|
@@ -4721,13 +4999,26 @@ export class WebPlayer extends BasePlayer {
|
|
|
4721
4999
|
}
|
|
4722
5000
|
if (this.isDragging) {
|
|
4723
5001
|
this.isDragging = false;
|
|
5002
|
+
const handle = document.getElementById('uvf-progress-handle');
|
|
5003
|
+
handle?.classList.remove('dragging');
|
|
5004
|
+
}
|
|
5005
|
+
});
|
|
5006
|
+
document.addEventListener('touchend', () => {
|
|
5007
|
+
if (this.isDragging) {
|
|
5008
|
+
this.isDragging = false;
|
|
5009
|
+
const handle = document.getElementById('uvf-progress-handle');
|
|
5010
|
+
handle?.classList.remove('dragging');
|
|
4724
5011
|
}
|
|
4725
5012
|
});
|
|
4726
5013
|
this.video.addEventListener('timeupdate', () => {
|
|
4727
5014
|
const progressFilled = document.getElementById('uvf-progress-filled');
|
|
5015
|
+
const progressHandle = document.getElementById('uvf-progress-handle');
|
|
4728
5016
|
if (this.video && progressFilled) {
|
|
4729
5017
|
const percent = (this.video.currentTime / this.video.duration) * 100;
|
|
4730
5018
|
progressFilled.style.width = percent + '%';
|
|
5019
|
+
if (progressHandle && !this.isDragging) {
|
|
5020
|
+
progressHandle.style.left = percent + '%';
|
|
5021
|
+
}
|
|
4731
5022
|
}
|
|
4732
5023
|
this.updateTimeDisplay();
|
|
4733
5024
|
});
|
|
@@ -5371,6 +5662,12 @@ export class WebPlayer extends BasePlayer {
|
|
|
5371
5662
|
}
|
|
5372
5663
|
if (progressHandle) {
|
|
5373
5664
|
progressHandle.style.left = percent + '%';
|
|
5665
|
+
if (this.isDragging) {
|
|
5666
|
+
progressHandle.classList.add('dragging');
|
|
5667
|
+
}
|
|
5668
|
+
else {
|
|
5669
|
+
progressHandle.classList.remove('dragging');
|
|
5670
|
+
}
|
|
5374
5671
|
}
|
|
5375
5672
|
this.seek(time);
|
|
5376
5673
|
}
|