eb-player 2.0.4 → 2.0.6
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/build/eb-player.css +47 -12
- package/dist/build/ebplayer.bundle.js +168 -26
- package/dist/build/ebplayer.bundle.js.map +1 -1
- package/dist/build/types/eb-player.d.ts.map +1 -1
- package/dist/build/types/engines/snapshot/hls.d.ts.map +1 -1
- package/dist/build/types/skin/controls/fullscreen-button.d.ts +14 -1
- package/dist/build/types/skin/controls/fullscreen-button.d.ts.map +1 -1
- package/dist/build/types/skin/controls/seekbar.d.ts +6 -1
- package/dist/build/types/skin/controls/seekbar.d.ts.map +1 -1
- package/dist/dev/easybroadcast.js +169 -27
- package/dist/dev/easybroadcast.js.map +1 -1
- package/dist/eb-player.css +47 -12
- package/dist/players/default/default.js +148 -165
- package/dist/players/equipe/EB_lequipe-preprod.js +70 -72
- package/dist/players/equipe/equipe.js +70 -72
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eb-player.d.ts","sourceRoot":"","sources":["../../../src/eb-player.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"eb-player.d.ts","sourceRoot":"","sources":["../../../src/eb-player.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGjD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,uEAAuE;IACvE,KAAK,IAAI,IAAI,CAAA;IACb,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;CAC5B;AA4DD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,eAAe,CA2L3E;AAED;;;GAGG;AACH,wBAAgB,IAAI,IAAI,IAAI,CAK3B;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,IAAI,CAU9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hls.d.ts","sourceRoot":"","sources":["../../../../../src/engines/snapshot/hls.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hls.d.ts","sourceRoot":"","sources":["../../../../../src/engines/snapshot/hls.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,12 +5,25 @@ import { BaseComponent } from '../base-component';
|
|
|
5
5
|
*
|
|
6
6
|
* - Calls screenfull.toggle() with the closest .eb-player ancestor on click
|
|
7
7
|
* - Subscribes to screenfull 'change' event to update state.isFullscreen
|
|
8
|
-
* -
|
|
8
|
+
* - Falls back to video-element fullscreen on mobile (iOS Safari webkitEnterFullscreen,
|
|
9
|
+
* Android Chrome video.requestFullscreen) when the Fullscreen API is not available
|
|
10
|
+
* for arbitrary elements
|
|
9
11
|
* - Re-renders when state.isFullscreen changes
|
|
10
12
|
*/
|
|
11
13
|
export declare class FullscreenButton extends BaseComponent {
|
|
12
14
|
private changeHandler;
|
|
15
|
+
private videoEl;
|
|
16
|
+
private videoFullscreenBeginHandler;
|
|
17
|
+
private videoFullscreenEndHandler;
|
|
18
|
+
private useVideoFallback;
|
|
13
19
|
protected onConnect(): void;
|
|
20
|
+
/**
|
|
21
|
+
* On mobile browsers the Fullscreen API may not work on arbitrary elements,
|
|
22
|
+
* but the <video> element itself supports fullscreen via webkitEnterFullscreen
|
|
23
|
+
* (iOS Safari) or video.requestFullscreen() (Android Chrome).
|
|
24
|
+
*/
|
|
25
|
+
private initVideoFallback;
|
|
26
|
+
private handleDocFullscreenChange;
|
|
14
27
|
private handleClick;
|
|
15
28
|
protected template(): TemplateResult;
|
|
16
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullscreen-button.d.ts","sourceRoot":"","sources":["../../../../../src/skin/controls/fullscreen-button.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"fullscreen-button.d.ts","sourceRoot":"","sources":["../../../../../src/skin/controls/fullscreen-button.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAajD;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,2BAA2B,CAA4B;IAC/D,OAAO,CAAC,yBAAyB,CAA4B;IAC7D,OAAO,CAAC,gBAAgB,CAAQ;IAEhC,SAAS,CAAC,SAAS,IAAI,IAAI;IAsB3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA4CzB,OAAO,CAAC,yBAAyB,CAIhC;IAED,OAAO,CAAC,WAAW;IA0BnB,SAAS,CAAC,QAAQ,IAAI,cAAc;CAqBrC"}
|
|
@@ -23,17 +23,22 @@ export declare class Seekbar extends BaseComponent {
|
|
|
23
23
|
private tooltipX;
|
|
24
24
|
private previewVideoEl;
|
|
25
25
|
private snapshotTake;
|
|
26
|
+
private trackEl;
|
|
27
|
+
private boundDocPointerMove;
|
|
26
28
|
protected onConnect(): void;
|
|
29
|
+
disconnect(): void;
|
|
27
30
|
private scheduleRender;
|
|
28
31
|
/**
|
|
29
32
|
* Converts a PointerEvent clientX to a time value, accounting for RTL mode.
|
|
30
33
|
* Clamps result to [0, duration].
|
|
31
34
|
*/
|
|
32
35
|
private eventToTime;
|
|
36
|
+
private startDocumentTracking;
|
|
37
|
+
private stopDocumentTracking;
|
|
38
|
+
private onDocPointerMove;
|
|
33
39
|
private handlePointerDown;
|
|
34
40
|
private handlePointerMove;
|
|
35
41
|
private handlePointerUp;
|
|
36
|
-
private handlePointerLeave;
|
|
37
42
|
private updateTooltip;
|
|
38
43
|
private findActiveChapter;
|
|
39
44
|
private findSkippableChapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seekbar.d.ts","sourceRoot":"","sources":["../../../../../src/skin/controls/seekbar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAMjD;;;;;;;;;;;;;GAaG;AACH,qBAAa,OAAQ,SAAQ,aAAa;IACxC,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,YAAY,CAAwC;
|
|
1
|
+
{"version":3,"file":"seekbar.d.ts","sourceRoot":"","sources":["../../../../../src/skin/controls/seekbar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAMjD;;;;;;;;;;;;;GAaG;AACH,qBAAa,OAAQ,SAAQ,aAAa;IACxC,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,mBAAmB,CAA+C;IAE1E,SAAS,CAAC,SAAS,IAAI,IAAI;IAsBlB,UAAU,IAAI,IAAI;IAO3B,OAAO,CAAC,cAAc;IAWtB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,aAAa;IA6BrB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,iBAAiB;IA6BzB,SAAS,CAAC,QAAQ,IAAI,cAAc;CAyFrC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var EBPlayerBundle = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var __EB_PLAYER_VERSION__ = "2.0.
|
|
4
|
+
var __EB_PLAYER_VERSION__ = "2.0.6";
|
|
5
5
|
|
|
6
6
|
function styleInject(css, ref) {
|
|
7
7
|
if ( ref === void 0 ) ref = {};
|
|
@@ -51,7 +51,7 @@ var EBPlayerBundle = (function (exports) {
|
|
|
51
51
|
var css_248z$1 = "/**\n * V2 theme — based on snrtlive.ma (Aloula) player styling\n *\n * Applied when the container has [data-theme=\"v2\"].\n * Dark UI with orange accent (#ff841f), Inter font, rounded container,\n * backdrop-blur panels, expandable volume, two-row bottom bar\n * (seekbar on top, buttons below), gradient overlays, centered\n * frosted-glass transport circles, and refined slide/fade animations.\n */\n\n/* ============================================================\n Google Fonts (Inter 300-700)\n ============================================================ */\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');\n\n/* ============================================================\n Root vars & container\n ============================================================ */\n[data-theme=\"v2\"] .eb-player {\n --eb-color-primary: #ff841f;\n --eb-color-progress: #ff841f;\n --eb-color-background: rgba(10, 10, 20, 0.85);\n --eb-accent: #ff841f;\n --eb-color-text: #fff;\n --eb-font-family: 'Inter', -apple-system, sans-serif;\n --eb-font-size-base: 14px;\n --eb-radius-control: 8px;\n --eb-duration-transition: 200ms;\n font-family: 'Inter', -apple-system, sans-serif;\n border-radius: 14px;\n box-shadow: 0 40px 80px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.06);\n color: #fff;\n}\n\n/* ============================================================\n Icons: bolder stroke weight to match filled-style target\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-icon {\n stroke-width: 2.5;\n}\n\n/* Fullscreen: fill viewport, drop card styling */\n[data-theme=\"v2\"] .eb-player:fullscreen,\n[data-theme=\"v2\"] .eb-player:-webkit-full-screen {\n border-radius: 0;\n box-shadow: none;\n}\n\n/* ============================================================\n Gradients (top & bottom)\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-top-bar {\n background: linear-gradient(to bottom, rgba(0,0,0,.72), transparent);\n height: 110px;\n padding: 14px 16px;\n gap: 6px;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-bottom-bar__gradient {\n height: 150px;\n background: linear-gradient(to top, rgba(0,0,0,.9), transparent);\n}\n\n/* ============================================================\n Top bar: slide-in from above\n ============================================================ */\n[data-theme=\"v2\"] .eb-player.eb-controls-visible .eb-top-bar {\n opacity: 1;\n transform: translateY(0);\n transition: opacity .3s, transform .3s;\n}\n\n[data-theme=\"v2\"] .eb-player.eb-controls-hidden .eb-top-bar {\n opacity: 0;\n transform: translateY(-6px);\n transition: opacity .3s, transform .3s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-top-bar__actions {\n gap: 6px;\n}\n\n/* Logo */\n[data-theme=\"v2\"] .eb-player .eb-top-bar__logo {\n max-height: 32px;\n max-width: 120px;\n opacity: .85;\n}\n\n/* ============================================================\n Bottom bar: slide-up animation + spacing\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-bottom-bar__controls-row {\n padding: 0 14px 12px;\n gap: 8px;\n}\n\n[data-theme=\"v2\"] .eb-player.eb-controls-visible .eb-bottom-bar {\n opacity: 1;\n transform: translateY(0);\n transition: opacity .3s, transform .3s;\n}\n\n[data-theme=\"v2\"] .eb-player.eb-controls-hidden .eb-bottom-bar {\n opacity: 0;\n transform: translateY(8px);\n transition: opacity .3s, transform .3s;\n}\n\n/* ============================================================\n Bottom bar: single-row layout\n play | live | time | ——seekbar—— | settings | volume | fullscreen\n PiP / Cast are in the top bar (via THEME_LAYOUTS.v2 in config.ts)\n ============================================================ */\n\n/* ============================================================\n Middle bar: glassmorphism transport circles\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-middle-bar {\n gap: 28px;\n}\n\n[data-theme=\"v2\"] .eb-player.eb-controls-visible .eb-middle-bar {\n opacity: 1;\n transition: opacity .3s;\n}\n\n[data-theme=\"v2\"] .eb-player.eb-controls-hidden .eb-middle-bar {\n opacity: 0;\n transition: opacity .3s;\n}\n\n/* Central play/pause — large frosted circle */\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__play-btn {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255,255,255,.15);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n border: 2px solid rgba(255,255,255,.25);\n color: #fff;\n padding: 0;\n transition: background .15s, transform .25s, opacity .25s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__play-btn:hover {\n background: rgba(255,255,255,.25);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__play-btn:active {\n transform: scale(.92);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__play-btn .eb-icon {\n width: 32px;\n height: 32px;\n stroke-width: 2.5;\n}\n\n/* Seek buttons — smaller frosted circles, same style as play button */\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__seek-btn {\n width: 56px;\n height: 56px;\n border-radius: 50%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: rgba(255,255,255,.15);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n border: 2px solid rgba(255,255,255,.25);\n color: #fff;\n gap: 1px;\n padding: 0;\n transition: background .15s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__seek-btn:hover {\n background: rgba(255,255,255,.25);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-seek-circle {\n width: 24px;\n height: 24px;\n color: rgba(255,255,255,.85);\n fill: currentColor;\n stroke: none;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-seek-label {\n font-size: .75em;\n font-weight: 700;\n color: rgba(255,255,255,.9);\n line-height: 1;\n}\n\n/* ============================================================\n Buttons: rounded, soft color, scale on press\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-button:not(.eb-middle-bar__seek-btn):not(.eb-middle-bar__play-btn),\n[data-theme=\"v2\"] .eb-player .eb-play-pause,\n[data-theme=\"v2\"] .eb-player .eb-fullscreen,\n[data-theme=\"v2\"] .eb-player .eb-pip,\n[data-theme=\"v2\"] .eb-player .eb-cast,\n[data-theme=\"v2\"] .eb-player .eb-volume-mute,\n[data-theme=\"v2\"] .eb-player .eb-live-sync {\n color: rgba(255,255,255,.82);\n border-radius: 8px;\n width: 38px;\n height: 38px;\n transition: background .15s, color .15s, transform .1s;\n flex-shrink: 0;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-button:not(.eb-middle-bar__seek-btn):not(.eb-middle-bar__play-btn):hover,\n[data-theme=\"v2\"] .eb-player .eb-play-pause:hover,\n[data-theme=\"v2\"] .eb-player .eb-fullscreen:hover,\n[data-theme=\"v2\"] .eb-player .eb-pip:hover,\n[data-theme=\"v2\"] .eb-player .eb-cast:hover,\n[data-theme=\"v2\"] .eb-player .eb-volume-mute:hover,\n[data-theme=\"v2\"] .eb-player .eb-live-sync:hover {\n background: rgba(255,255,255,.12);\n color: #fff;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-button:not(.eb-middle-bar__seek-btn):not(.eb-middle-bar__play-btn):active,\n[data-theme=\"v2\"] .eb-player .eb-play-pause:active,\n[data-theme=\"v2\"] .eb-player .eb-fullscreen:active,\n[data-theme=\"v2\"] .eb-player .eb-pip:active,\n[data-theme=\"v2\"] .eb-player .eb-cast:active,\n[data-theme=\"v2\"] .eb-player .eb-volume-mute:active,\n[data-theme=\"v2\"] .eb-player .eb-live-sync:active {\n transform: scale(.88);\n}\n\n/* Icon size inside buttons (not middle bar transport) */\n[data-theme=\"v2\"] .eb-player .eb-button:not(.eb-middle-bar__seek-btn):not(.eb-middle-bar__play-btn) .eb-icon,\n[data-theme=\"v2\"] .eb-player .eb-play-pause .eb-icon,\n[data-theme=\"v2\"] .eb-player .eb-fullscreen .eb-icon,\n[data-theme=\"v2\"] .eb-player .eb-pip .eb-icon,\n[data-theme=\"v2\"] .eb-player .eb-cast .eb-icon,\n[data-theme=\"v2\"] .eb-player .eb-volume-mute .eb-icon {\n width: 22px;\n height: 22px;\n}\n\n/* Top bar icons slightly larger */\n[data-theme=\"v2\"] .eb-player .eb-top-bar .eb-icon {\n width: 24px;\n height: 24px;\n}\n\n/* Play/pause icons should be filled (solid), not stroke outlines */\n[data-theme=\"v2\"] .eb-player .eb-play-pause .eb-icon,\n[data-theme=\"v2\"] .eb-player .eb-middle-bar__play-btn .eb-icon {\n fill: currentColor;\n stroke: none;\n}\n\n/* Volume icon: fill the speaker body, keep stroke for sound waves */\n[data-theme=\"v2\"] .eb-player .eb-volume-mute .eb-icon path:first-child {\n fill: currentColor;\n}\n\n/* Cast button active state — cyan */\n[data-theme=\"v2\"] .eb-player .eb-cast-active {\n color: #1eb6d4 !important;\n background: rgba(30, 182, 212, .15) !important;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-cast-active .eb-icon {\n filter: drop-shadow(0 0 4px rgba(30, 182, 212, .6));\n}\n\n/* ============================================================\n Seekbar\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-seekbar-track {\n height: 3px;\n background: rgba(255,255,255,.22);\n border-radius: 3px;\n transition: height .15s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-seekbar:hover .eb-seekbar-track {\n height: 5px;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-seekbar-buffered {\n background: rgba(255,255,255,.28);\n border-radius: 3px;\n transition: height .15s;\n}\n\n/* Orange gradient fill */\n[data-theme=\"v2\"] .eb-player .eb-seekbar-progress {\n background: linear-gradient(90deg, #ff841f, color-mix(in srgb, #ff841f 70%, #fff));\n border-radius: 3px;\n transition: height .15s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-seekbar-thumb {\n width: 14px;\n height: 14px;\n right: -7px;\n background: #fff;\n box-shadow: 0 0 0 3px rgba(255,132,31,.45);\n}\n\n/* ============================================================\n Seekbar tooltip & preview\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-seekbar-tooltip {\n bottom: 28px;\n background: rgba(0,0,0,.88);\n border: 1px solid rgba(255,255,255,.12);\n border-radius: 7px;\n font-size: 11px;\n font-weight: 500;\n padding: 0;\n overflow: hidden;\n box-shadow: 0 4px 16px rgba(0,0,0,.5);\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-seekbar-preview {\n width: 160px;\n height: 90px;\n background: #111;\n border: none;\n border-radius: 0;\n margin: 0;\n}\n\n/* ============================================================\n Chapter markers\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-chapter-marker {\n width: 2px;\n height: 7px;\n background: rgba(0,0,0,.45);\n border-radius: 1px;\n top: 50%;\n transform: translate(-50%, -50%);\n}\n\n/* ============================================================\n Volume: expandable slider, white fill\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-volume-control {\n flex-direction: row;\n gap: 0;\n margin-right: 0;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-volume-track {\n width: 0;\n height: 3px;\n background: rgba(255,255,255,.22);\n border-radius: 3px;\n overflow: hidden;\n transition: width .25s ease, margin .25s ease;\n margin: 0;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-volume-control:hover .eb-volume-track,\n[data-theme=\"v2\"] .eb-player .eb-volume-control:focus-within .eb-volume-track {\n width: 66px;\n margin: 0 6px 0 2px;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-volume-fill {\n background: var(--eb-color-primary, #ff841f);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-volume-thumb {\n width: 11px;\n height: 11px;\n background: #fff;\n box-shadow: 0 0 0 2px rgba(255,255,255,.35);\n transform: translate(-50%, -50%) scale(0);\n transition: transform .15s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-volume-control:hover .eb-volume-thumb {\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* ============================================================\n Time display\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-time-display {\n font-size: 13px;\n color: rgba(255,255,255,.85);\n font-weight: 500;\n letter-spacing: .02em;\n}\n\n/* ============================================================\n Live badge — text badge with blinking dot (not icon)\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-live-sync {\n width: auto;\n height: auto;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: .08em;\n text-transform: uppercase;\n gap: 5px;\n}\n\n/* Hide icon, show dot + label */\n[data-theme=\"v2\"] .eb-player .eb-live-sync__icon {\n display: none;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-live-sync__dot {\n display: block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #fff;\n flex-shrink: 0;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-live-sync__label {\n display: block;\n}\n\n/* Synced state — red background with blinking dot */\n[data-theme=\"v2\"] .eb-player .eb-live-synced {\n background: rgba(220,38,38,.9);\n color: #fff;\n box-shadow: 0 2px 8px rgba(220,38,38,.4);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-live-synced .eb-live-sync__dot {\n animation: eb-v2-blink 1.2s ease infinite;\n}\n\n/* Delayed / not-at-live-edge */\n[data-theme=\"v2\"] .eb-player .eb-live-sync:not(.eb-live-synced) {\n background: rgba(60,60,80,.75);\n color: rgba(255,255,255,.7);\n box-shadow: none;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-live-sync:not(.eb-live-synced) .eb-live-sync__dot {\n background: rgba(255,255,255,.5);\n animation: none;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-live-sync:not(.eb-live-synced):hover {\n background: rgba(220,38,38,.7);\n color: #fff;\n}\n\n@keyframes eb-v2-blink {\n 0%, 100% { opacity: 1; }\n 50% { opacity: .15; }\n}\n\n/* ============================================================\n Settings panel: glassmorphism dropdown\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-settings-panel {\n background: rgba(10,10,20,.55);\n backdrop-filter: blur(18px) saturate(160%);\n -webkit-backdrop-filter: blur(18px) saturate(160%);\n border-radius: 12px;\n min-width: 300px;\n box-shadow: 0 16px 48px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.1);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-settings-menu {\n padding: 0;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-settings-category,\n[data-theme=\"v2\"] .eb-player .eb-settings-item,\n[data-theme=\"v2\"] .eb-player .eb-settings-back {\n padding: 15px 20px;\n font-size: 13px;\n color: rgba(255,255,255,.9);\n border-bottom: 1px solid rgba(255,255,255,.06);\n transition: background .12s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-settings-category:last-child,\n[data-theme=\"v2\"] .eb-player .eb-settings-item:last-child {\n border-bottom: none;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-settings-category:hover,\n[data-theme=\"v2\"] .eb-player .eb-settings-item:hover,\n[data-theme=\"v2\"] .eb-player .eb-settings-back:hover {\n background: rgba(255,255,255,.05);\n}\n\n/* Selected item text */\n[data-theme=\"v2\"] .eb-player .eb-settings-item--selected {\n color: #fff;\n font-weight: 500;\n}\n\n/* Active selection dot (filled orange) */\n[data-theme=\"v2\"] .eb-player .eb-settings-item--selected::after {\n content: '';\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--eb-accent, #ff841f);\n box-shadow: 0 0 0 3px rgba(255,132,31,.25);\n flex-shrink: 0;\n}\n\n/* Non-selected items: hollow dot */\n[data-theme=\"v2\"] .eb-player .eb-settings-item:not(.eb-settings-item--selected)::after {\n content: '';\n width: 10px;\n height: 10px;\n border-radius: 50%;\n border: 2px solid rgba(255,255,255,.2);\n flex-shrink: 0;\n}\n\n/* Back button */\n[data-theme=\"v2\"] .eb-player .eb-settings-back {\n gap: 14px;\n font-weight: 600;\n}\n\n/* ============================================================\n Loading spinner\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-loading .eb-icon {\n width: 52px;\n height: 52px;\n color: rgba(255,255,255,.7);\n filter: drop-shadow(0 1px 6px rgba(0,0,0,.5));\n animation: eb-spin .75s linear infinite;\n}\n\n/* ============================================================\n Error overlay\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-error {\n background: rgba(10,10,20,.85);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-error-message {\n font-weight: 400;\n letter-spacing: .01em;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-error-retry {\n border-radius: 8px;\n background: rgba(255,255,255,.1);\n border-color: rgba(255,255,255,.15);\n transition: background .2s, color .2s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-error-retry:hover {\n background: rgba(255,255,255,.18);\n}\n\n/* ============================================================\n Toast (keyboard hints, status messages)\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-toast {\n background: rgba(0,0,0,.72);\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: 10px;\n font-size: 13px;\n padding: 8px 16px;\n}\n\n/* ============================================================\n Info & socials overlays\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-info-overlay,\n[data-theme=\"v2\"] .eb-player .eb-socials-overlay {\n background: rgba(10,10,20,.85);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-info-close,\n[data-theme=\"v2\"] .eb-player .eb-socials-close {\n border-radius: 8px;\n background: rgba(255,255,255,.07);\n border-color: rgba(255,255,255,.08);\n transition: background .2s, color .2s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-info-close:hover,\n[data-theme=\"v2\"] .eb-player .eb-socials-close:hover {\n background: rgba(255,255,255,.13);\n color: #fff;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-socials-link {\n background: rgba(255,255,255,.07);\n border: 1px solid rgba(255,255,255,.08);\n border-radius: 8px;\n transition: background .2s, color .2s, border-color .2s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-socials-link:hover {\n background: rgba(255,132,31,.15);\n border-color: rgba(255,132,31,.35);\n color: #ffb980;\n}\n\n/* ============================================================\n Poster\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-poster {\n background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);\n}\n\n/* ============================================================\n Radio overlay\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-radio-overlay {\n background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);\n}\n\n[data-theme=\"v2\"] .eb-player .eb-radio-bar {\n background: rgba(255,132,31,.8);\n}\n\n/* ============================================================\n Chapter skip button\n ============================================================ */\n[data-theme=\"v2\"] .eb-player .eb-chapter-skip {\n background: rgba(10,10,20,.55);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border: 1px solid rgba(255,255,255,.15);\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n transition: background .15s;\n}\n\n[data-theme=\"v2\"] .eb-player .eb-chapter-skip:hover {\n background: rgba(255,255,255,.12);\n}\n";
|
|
52
52
|
styleInject(css_248z$1);
|
|
53
53
|
|
|
54
|
-
var css_248z = "/* eb-player skin CSS — BEM-prefixed structural styles */\n/* All class names use the eb- prefix to avoid collisions with consumer CSS */\n\n/* ============================================================\n Root container\n ============================================================ */\n.eb-player {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n font-family: sans-serif;\n background: #000;\n color: #fff;\n box-sizing: border-box;\n user-select: none;\n}\n\n/* Video element fills the container */\n.eb-player video.eb-video {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: block;\n object-fit: contain;\n z-index: 1;\n}\n\n/* ============================================================\n Overlay zone (poster, radio, loading, error, socials, info)\n ============================================================ */\n.eb-overlay-zone {\n position: absolute;\n inset: 0;\n pointer-events: none;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n}\n\n/* Poster image */\n.eb-poster {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: contain;\n pointer-events: none;\n background: #000;\n padding: 15%;\n box-sizing: border-box;\n}\n\n/* Ads container (for IMA SDK) */\n.eb-ads-container {\n position: absolute;\n inset: 0;\n z-index: 20;\n pointer-events: none;\n}\n\n/* ============================================================\n Top bar\n ============================================================ */\n.eb-top-bar {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background: linear-gradient(to bottom, rgba(0,0,0,0.6), transparent);\n z-index: 30;\n pointer-events: auto;\n}\n\n.eb-top-bar__logo {\n height: 28px;\n width: auto;\n display: block;\n}\n\n.eb-top-bar__logo-link {\n display: inline-flex;\n text-decoration: none;\n}\n\n.eb-top-bar__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n}\n\n/* ============================================================\n Bottom bar\n ============================================================ */\n.eb-bottom-bar {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n display: flex;\n flex-direction: column;\n z-index: 30;\n pointer-events: auto;\n}\n\n.eb-bottom-bar__gradient {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n height: 100px;\n background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);\n pointer-events: none;\n z-index: -1;\n}\n\n.eb-bottom-bar__controls-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 4px;\n padding: 4px 8px 8px;\n}\n\n.eb-bottom-bar__seekbar-zone {\n flex: 1;\n min-width: 0;\n}\n\n/* ============================================================\n Middle bar\n ============================================================ */\n.eb-middle-bar {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n pointer-events: auto;\n z-index: 25;\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.eb-middle-bar__play-btn {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: rgba(0,0,0,0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.eb-middle-bar__seek-btn {\n flex-direction: column;\n gap: 2px;\n background: none;\n padding: 4px;\n}\n\n.eb-middle-bar__seek-btn:hover {\n background: rgba(255,255,255,0.1);\n border-radius: 8px;\n}\n\n.eb-seek-circle {\n width: 32px;\n height: 32px;\n display: block;\n pointer-events: none;\n fill: currentColor;\n}\n\n.eb-seek-label {\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n opacity: 0.85;\n}\n\n/* ============================================================\n Extension zones\n ============================================================ */\n.eb-extension-top-extra,\n.eb-extension-bottom-extra,\n.eb-extension-overlay,\n.eb-extension-controls-extra {\n position: absolute;\n pointer-events: none;\n z-index: 35;\n}\n\n.eb-extension-top-extra > *,\n.eb-extension-bottom-extra > *,\n.eb-extension-overlay > *,\n.eb-extension-controls-extra > * {\n pointer-events: auto;\n}\n\n.eb-extension-top-extra {\n top: 0;\n left: 0;\n right: 0;\n}\n\n.eb-extension-bottom-extra {\n bottom: 0;\n left: 0;\n right: 0;\n}\n\n.eb-extension-overlay {\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.eb-extension-controls-extra {\n bottom: 0;\n right: 0;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px 8px;\n}\n\n/* ============================================================\n Time display\n ============================================================ */\n.eb-time-display {\n font-size: 13px;\n line-height: 1;\n white-space: nowrap;\n padding: 0 4px;\n color: #fff;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================================\n Volume control\n ============================================================ */\n.eb-volume-control {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n}\n\n.eb-volume-track {\n position: relative;\n width: 60px;\n height: 4px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n cursor: pointer;\n}\n\n.eb-volume-fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--eb-color-volume, var(--eb-color-primary, #fff));\n border-radius: 2px;\n pointer-events: none;\n}\n\n.eb-volume-thumb {\n position: absolute;\n top: 50%;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--eb-color-volume, var(--eb-color-primary, #fff));\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ============================================================\n Settings panel\n ============================================================ */\n.eb-settings-wrapper {\n position: relative;\n}\n\n.eb-settings-panel {\n position: absolute;\n background: rgba(0, 0, 0, 0.85);\n border-radius: 6px;\n min-width: 160px;\n max-width: 220px;\n overflow: hidden;\n font-size: 12px;\n z-index: 40;\n}\n\n/* Vertical direction: up (default) or down */\n.eb-settings-panel--up {\n bottom: calc(100% + 8px);\n}\n\n.eb-settings-panel--down {\n top: calc(100% + 8px);\n}\n\n/* Horizontal alignment: right (default) or left */\n.eb-settings-panel--right {\n right: 0;\n}\n\n.eb-settings-panel--left {\n left: 0;\n}\n\n.eb-settings-menu {\n list-style: none;\n margin: 0;\n padding: 4px 0;\n}\n\n.eb-settings-submenu .eb-settings-menu {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.eb-settings-submenu .eb-settings-menu::-webkit-scrollbar {\n width: 4px;\n}\n\n.eb-settings-submenu .eb-settings-menu::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n}\n\n.eb-settings-category,\n.eb-settings-item,\n.eb-settings-back {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 5px 12px;\n border: none;\n background: none;\n color: #fff;\n cursor: pointer;\n font-size: 12px;\n text-align: left;\n}\n\n.eb-settings-category:hover,\n.eb-settings-item:hover,\n.eb-settings-back:hover {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.eb-settings-item--selected {\n color: var(--eb-accent, var(--eb-color-primary, #e53935));\n}\n\n/* ============================================================\n Seekbar\n ============================================================ */\n.eb-seekbar {\n position: relative;\n width: 100%;\n padding: 8px 0;\n cursor: pointer;\n}\n\n.eb-seekbar-disabled {\n pointer-events: none;\n opacity: 0.4;\n}\n\n.eb-seekbar-track {\n position: relative;\n height: 4px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n}\n\n.eb-seekbar-buffered {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.4);\n border-radius: 2px;\n pointer-events: none;\n}\n\n.eb-seekbar-progress {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--eb-color-progress, var(--eb-color-primary, #e53935));\n border-radius: 2px;\n pointer-events: none;\n}\n\n.eb-seekbar-thumb {\n position: absolute;\n right: -6px;\n top: 50%;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--eb-color-progress, var(--eb-color-primary, #e53935));\n transform: translateY(-50%) scale(0);\n transition: transform 0.15s;\n pointer-events: none;\n}\n\n.eb-seekbar:hover .eb-seekbar-thumb {\n transform: translateY(-50%) scale(1);\n}\n\n.eb-seekbar:hover .eb-seekbar-track {\n height: 6px;\n}\n\n.eb-seekbar-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n font-size: 12px;\n padding: 4px 8px;\n border-radius: 3px;\n white-space: nowrap;\n pointer-events: none;\n text-align: center;\n}\n\n.eb-seekbar-preview {\n width: 120px;\n height: auto;\n display: block;\n margin-bottom: 4px;\n}\n\n.eb-chapter-marker {\n position: absolute;\n top: 0;\n width: 3px;\n height: 100%;\n background: rgba(255, 255, 255, 0.6);\n transform: translateX(-50%);\n pointer-events: none;\n}\n\n.eb-chapter-marker.eb-chapter-active {\n background: #fff;\n}\n\n.eb-chapter-skip {\n position: absolute;\n right: 0;\n bottom: calc(100% + 4px);\n background: rgba(0, 0, 0, 0.7);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.4);\n border-radius: 4px;\n padding: 6px 16px;\n font-size: 13px;\n cursor: pointer;\n}\n\n.eb-chapter-skip:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n\n.eb-epg-segment {\n position: absolute;\n top: 0;\n height: 100%;\n border-right: 1px solid rgba(255, 255, 255, 0.3);\n pointer-events: none;\n}\n\n.eb-epg-segment.eb-epg-current {\n background: rgba(255, 255, 255, 0.1);\n}\n\n/* ============================================================\n Icons\n ============================================================ */\n.eb-icon {\n width: 20px;\n height: 20px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n display: block;\n pointer-events: none;\n flex-shrink: 0;\n}\n\n/* ============================================================\n Buttons (base style)\n ============================================================ */\n.eb-button,\n.eb-play-pause,\n.eb-fullscreen,\n.eb-pip,\n.eb-cast,\n.eb-volume-mute,\n.eb-live-sync {\n cursor: pointer;\n background: none;\n border: none;\n padding: 6px;\n color: var(--eb-color-icon, inherit);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background 0.15s;\n -webkit-tap-highlight-color: transparent;\n}\n\n.eb-button:hover,\n.eb-play-pause:hover,\n.eb-fullscreen:hover,\n.eb-pip:hover,\n.eb-cast:hover,\n.eb-volume-mute:hover,\n.eb-live-sync:hover {\n background: rgba(255,255,255,0.15);\n}\n\n.eb-button:active,\n.eb-play-pause:active,\n.eb-fullscreen:active,\n.eb-pip:active,\n.eb-cast:active,\n.eb-volume-mute:active,\n.eb-live-sync:active {\n background: rgba(255,255,255,0.25);\n}\n\n/* ============================================================\n Radio overlay\n ============================================================ */\n.eb-radio-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #000;\n z-index: 15;\n}\n\n.eb-radio-bars {\n display: flex;\n align-items: flex-end;\n gap: 4px;\n height: 40px;\n}\n\n.eb-radio-bar {\n display: block;\n width: 6px;\n background: #fff;\n border-radius: 3px;\n animation: eb-radio-bar-bounce 0.8s ease-in-out infinite;\n}\n\n.eb-radio-bar:nth-child(1) { animation-delay: 0s; height: 20px; }\n.eb-radio-bar:nth-child(2) { animation-delay: 0.1s; height: 32px; }\n.eb-radio-bar:nth-child(3) { animation-delay: 0.2s; height: 40px; }\n.eb-radio-bar:nth-child(4) { animation-delay: 0.3s; height: 28px; }\n.eb-radio-bar:nth-child(5) { animation-delay: 0.4s; height: 16px; }\n\n@keyframes eb-radio-bar-bounce {\n 0%, 100% { transform: scaleY(0.4); opacity: 0.7; }\n 50% { transform: scaleY(1); opacity: 1; }\n}\n\n/* Volume mute button — base styles shared via .eb-button group above */\n\n/* ============================================================\n Live sync button\n ============================================================ */\n.eb-live-sync[hidden] {\n display: none;\n}\n\n.eb-live-synced {\n color: var(--eb-accent, var(--eb-color-primary, #e53935));\n}\n\n/* Default theme: show icon only, hide text badge elements */\n.eb-live-sync__dot,\n.eb-live-sync__label {\n display: none;\n}\n\n/* ============================================================\n Overlay panels (error, info, socials — mounted in .eb-player)\n ============================================================ */\n.eb-error-slot,\n.eb-info-slot,\n.eb-socials-slot {\n position: absolute;\n inset: 0;\n z-index: 50;\n pointer-events: none;\n}\n\n.eb-toast-slot {\n position: absolute;\n bottom: 60px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 50;\n pointer-events: none;\n}\n\n.eb-toast {\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n padding: 8px 20px;\n border-radius: 4px;\n font-size: 13px;\n white-space: nowrap;\n pointer-events: auto;\n}\n\n.eb-error,\n.eb-info-overlay,\n.eb-socials-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n z-index: 50;\n pointer-events: auto;\n padding: 24px;\n text-align: center;\n}\n\n.eb-error[hidden],\n.eb-info-overlay[hidden],\n.eb-socials-overlay[hidden] {\n display: none;\n}\n\n.eb-error-message {\n font-size: 16px;\n margin: 0 0 16px;\n}\n\n.eb-error-retry {\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 4px;\n padding: 8px 24px;\n font-size: 14px;\n cursor: pointer;\n}\n\n.eb-error-retry:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n.eb-info-content {\n font-size: 14px;\n line-height: 1.5;\n max-width: 400px;\n margin-bottom: 16px;\n}\n\n.eb-info-close,\n.eb-socials-close {\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 4px;\n padding: 8px 24px;\n font-size: 14px;\n cursor: pointer;\n}\n\n.eb-info-close:hover,\n.eb-socials-close:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n.eb-socials-links {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n justify-content: center;\n margin-bottom: 16px;\n}\n\n.eb-socials-link {\n color: #fff;\n text-decoration: none;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n padding: 8px 16px;\n font-size: 14px;\n text-transform: capitalize;\n}\n\n.eb-socials-link:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* ============================================================\n Loading spinner\n ============================================================ */\n.eb-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n color: #fff;\n pointer-events: none;\n}\n\n.eb-loading[hidden] {\n display: none;\n}\n\n.eb-loading .eb-icon {\n width: 40px;\n height: 40px;\n animation: eb-spin 1s linear infinite;\n}\n\n.eb-loading-text {\n font-size: 14px;\n}\n\n@keyframes eb-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n/* ============================================================\n Controls visibility\n ============================================================ */\n.eb-controls-visible .eb-top-bar,\n.eb-controls-visible .eb-bottom-bar,\n.eb-controls-visible .eb-middle-bar {\n opacity: 1;\n transition: opacity 0.3s;\n}\n\n.eb-controls-hidden .eb-top-bar,\n.eb-controls-hidden .eb-bottom-bar,\n.eb-controls-hidden .eb-middle-bar {\n opacity: 0;\n transition: opacity 0.3s;\n pointer-events: none;\n}\n\n/* ============================================================\n iOS native controls fallback\n ============================================================ */\n.eb-ios-native .eb-top-bar,\n.eb-ios-native .eb-bottom-bar,\n.eb-ios-native .eb-middle-bar,\n.eb-ios-native .eb-overlay-zone,\n.eb-ios-native .eb-error-slot,\n.eb-ios-native .eb-info-slot,\n.eb-ios-native .eb-socials-slot,\n.eb-ios-native .eb-toast-slot {\n display: none;\n}\n\n/* ============================================================\n RTL support\n ============================================================ */\n[dir=\"rtl\"] .eb-bottom-bar__controls-row {\n flex-direction: row-reverse;\n}\n\n[dir=\"rtl\"] .eb-top-bar {\n flex-direction: row-reverse;\n}\n\n/* ============================================================\n Responsive: ensure container fills parent\n ============================================================ */\n.eb-player,\n.eb-player video {\n max-width: 100%;\n max-height: 100%;\n}\n";
|
|
54
|
+
var css_248z = "/* eb-player skin CSS — BEM-prefixed structural styles */\n/* All class names use the eb- prefix to avoid collisions with consumer CSS */\n\n/* ============================================================\n Root container\n ============================================================ */\n.eb-player {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n font-family: sans-serif;\n background: #000;\n color: #fff;\n box-sizing: border-box;\n user-select: none;\n}\n\n/* Video element fills the container.\n filter: brightness(1) is visually identical to no filter but forces Chrome to\n composite the video through the GPU filter pipeline instead of using a hardware\n overlay plane. Without this, DRM-protected video (Widevine) renders on a separate\n hardware overlay that sits above ALL HTML layers — making seekbar snapshot preview\n and other overlay elements invisible behind the main video. */\n.eb-player video.eb-video {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: block;\n object-fit: contain;\n z-index: 1;\n filter: brightness(1);\n}\n\n/* ============================================================\n Overlay zone (poster, radio, loading, error, socials, info)\n ============================================================ */\n.eb-overlay-zone {\n position: absolute;\n inset: 0;\n pointer-events: none;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n}\n\n/* Poster image */\n.eb-poster {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: contain;\n pointer-events: none;\n background: #000;\n padding: 15%;\n box-sizing: border-box;\n}\n\n/* Ads container (for IMA SDK) */\n.eb-ads-container {\n position: absolute;\n inset: 0;\n z-index: 20;\n pointer-events: none;\n}\n\n/* ============================================================\n Top bar\n ============================================================ */\n.eb-top-bar {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background: linear-gradient(to bottom, rgba(0,0,0,0.6), transparent);\n z-index: 30;\n pointer-events: auto;\n}\n\n.eb-top-bar__logo {\n height: 28px;\n width: auto;\n display: block;\n}\n\n.eb-top-bar__logo-link {\n display: inline-flex;\n text-decoration: none;\n}\n\n.eb-top-bar__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n}\n\n/* ============================================================\n Bottom bar\n ============================================================ */\n.eb-bottom-bar {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n display: flex;\n flex-direction: column;\n z-index: 30;\n pointer-events: auto;\n}\n\n.eb-bottom-bar__gradient {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n height: 100px;\n background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);\n pointer-events: none;\n z-index: -1;\n}\n\n.eb-bottom-bar__controls-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 4px;\n padding: 4px 8px 8px;\n}\n\n.eb-bottom-bar__seekbar-zone {\n flex: 1;\n min-width: 0;\n}\n\n/* ============================================================\n Middle bar\n ============================================================ */\n.eb-middle-bar {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n pointer-events: auto;\n z-index: 25;\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.eb-middle-bar__play-btn {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: rgba(0,0,0,0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.eb-middle-bar__seek-btn {\n flex-direction: column;\n gap: 2px;\n background: none;\n padding: 4px;\n}\n\n.eb-middle-bar__seek-btn:hover {\n background: rgba(255,255,255,0.1);\n border-radius: 8px;\n}\n\n.eb-seek-circle {\n width: 32px;\n height: 32px;\n display: block;\n pointer-events: none;\n fill: currentColor;\n}\n\n.eb-seek-label {\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n opacity: 0.85;\n}\n\n/* ============================================================\n Extension zones\n ============================================================ */\n.eb-extension-top-extra,\n.eb-extension-bottom-extra,\n.eb-extension-overlay,\n.eb-extension-controls-extra {\n position: absolute;\n pointer-events: none;\n z-index: 35;\n}\n\n.eb-extension-top-extra > *,\n.eb-extension-bottom-extra > *,\n.eb-extension-overlay > *,\n.eb-extension-controls-extra > * {\n pointer-events: auto;\n}\n\n.eb-extension-top-extra {\n top: 0;\n left: 0;\n right: 0;\n}\n\n.eb-extension-bottom-extra {\n bottom: 0;\n left: 0;\n right: 0;\n}\n\n.eb-extension-overlay {\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.eb-extension-controls-extra {\n bottom: 0;\n right: 0;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px 8px;\n}\n\n/* ============================================================\n Time display\n ============================================================ */\n.eb-time-display {\n font-size: 13px;\n line-height: 1;\n white-space: nowrap;\n padding: 0 4px;\n color: #fff;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================================\n Volume control\n ============================================================ */\n.eb-volume-control {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n}\n\n.eb-volume-track {\n position: relative;\n width: 60px;\n height: 4px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n cursor: pointer;\n}\n\n.eb-volume-fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--eb-color-volume, var(--eb-color-primary, #fff));\n border-radius: 2px;\n pointer-events: none;\n}\n\n.eb-volume-thumb {\n position: absolute;\n top: 50%;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--eb-color-volume, var(--eb-color-primary, #fff));\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ============================================================\n Settings panel\n ============================================================ */\n.eb-settings-wrapper {\n position: relative;\n}\n\n.eb-settings-panel {\n position: absolute;\n background: rgba(0, 0, 0, 0.85);\n border-radius: 6px;\n min-width: 160px;\n max-width: 220px;\n overflow: hidden;\n font-size: 12px;\n z-index: 40;\n}\n\n/* Vertical direction: up (default) or down */\n.eb-settings-panel--up {\n bottom: calc(100% + 8px);\n}\n\n.eb-settings-panel--down {\n top: calc(100% + 8px);\n}\n\n/* Horizontal alignment: right (default) or left */\n.eb-settings-panel--right {\n right: 0;\n}\n\n.eb-settings-panel--left {\n left: 0;\n}\n\n.eb-settings-menu {\n list-style: none;\n margin: 0;\n padding: 4px 0;\n}\n\n.eb-settings-submenu {\n max-height: 200px;\n overflow-y: auto;\n}\n\n.eb-settings-submenu::-webkit-scrollbar {\n width: 4px;\n}\n\n.eb-settings-submenu::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n}\n\n.eb-settings-header {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 12px;\n}\n\n.eb-settings-category,\n.eb-settings-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 5px 12px;\n border: none;\n background: none;\n color: #fff;\n cursor: pointer;\n font-size: 12px;\n text-align: left;\n}\n\n.eb-settings-back {\n display: flex;\n align-items: center;\n border: none;\n background: none;\n color: #fff;\n cursor: pointer;\n padding: 0;\n}\n\n.eb-settings-category:hover,\n.eb-settings-item:hover {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.eb-settings-item--selected {\n color: var(--eb-accent, var(--eb-color-primary, #e53935));\n}\n\n/* ============================================================\n Seekbar\n ============================================================ */\n.eb-seekbar {\n position: relative;\n width: 100%;\n padding: 8px 0;\n cursor: pointer;\n}\n\n.eb-seekbar-disabled {\n pointer-events: none;\n opacity: 0.4;\n}\n\n.eb-seekbar-track {\n position: relative;\n height: 4px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n}\n\n.eb-seekbar-buffered {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.4);\n border-radius: 2px;\n pointer-events: none;\n}\n\n.eb-seekbar-progress {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--eb-color-progress, var(--eb-color-primary, #e53935));\n border-radius: 2px;\n pointer-events: none;\n}\n\n.eb-seekbar-thumb {\n position: absolute;\n right: -6px;\n top: 50%;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--eb-color-progress, var(--eb-color-primary, #e53935));\n transform: translateY(-50%) scale(0);\n transition: transform 0.15s;\n pointer-events: none;\n}\n\n.eb-seekbar:hover .eb-seekbar-thumb {\n transform: translateY(-50%) scale(1);\n}\n\n.eb-seekbar:hover .eb-seekbar-track {\n height: 6px;\n}\n\n.eb-seekbar-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n font-size: 12px;\n padding: 4px 8px;\n border-radius: 3px;\n white-space: nowrap;\n pointer-events: none;\n text-align: center;\n z-index: 50;\n overflow: hidden;\n}\n\n.eb-seekbar-preview {\n position: static !important;\n width: 120px;\n height: 68px;\n min-width: 0 !important;\n min-height: 0 !important;\n max-width: none !important;\n max-height: none !important;\n display: block !important;\n object-fit: contain;\n background: #000;\n margin: 0 !important;\n padding: 0 !important;\n border: none !important;\n inset: auto !important;\n transform: none !important;\n z-index: auto !important;\n}\n\n.eb-chapter-marker {\n position: absolute;\n top: 0;\n width: 3px;\n height: 100%;\n background: rgba(255, 255, 255, 0.6);\n transform: translateX(-50%);\n pointer-events: none;\n}\n\n.eb-chapter-marker.eb-chapter-active {\n background: #fff;\n}\n\n.eb-chapter-skip {\n position: absolute;\n right: 0;\n bottom: calc(100% + 4px);\n background: rgba(0, 0, 0, 0.7);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.4);\n border-radius: 4px;\n padding: 6px 16px;\n font-size: 13px;\n cursor: pointer;\n}\n\n.eb-chapter-skip:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n\n.eb-epg-segment {\n position: absolute;\n top: 0;\n height: 100%;\n border-right: 1px solid rgba(255, 255, 255, 0.3);\n pointer-events: none;\n}\n\n.eb-epg-segment.eb-epg-current {\n background: rgba(255, 255, 255, 0.1);\n}\n\n/* ============================================================\n Icons\n ============================================================ */\n.eb-icon {\n width: 20px;\n height: 20px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n display: block;\n pointer-events: none;\n flex-shrink: 0;\n}\n\n/* ============================================================\n Buttons (base style)\n ============================================================ */\n.eb-button,\n.eb-play-pause,\n.eb-fullscreen,\n.eb-pip,\n.eb-cast,\n.eb-volume-mute,\n.eb-live-sync {\n cursor: pointer;\n background: none;\n border: none;\n padding: 6px;\n color: var(--eb-color-icon, inherit);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background 0.15s;\n -webkit-tap-highlight-color: transparent;\n}\n\n.eb-button:hover,\n.eb-play-pause:hover,\n.eb-fullscreen:hover,\n.eb-pip:hover,\n.eb-cast:hover,\n.eb-volume-mute:hover,\n.eb-live-sync:hover {\n background: rgba(255,255,255,0.15);\n}\n\n.eb-button:active,\n.eb-play-pause:active,\n.eb-fullscreen:active,\n.eb-pip:active,\n.eb-cast:active,\n.eb-volume-mute:active,\n.eb-live-sync:active {\n background: rgba(255,255,255,0.25);\n}\n\n/* ============================================================\n Radio overlay\n ============================================================ */\n.eb-radio-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #000;\n z-index: 15;\n}\n\n.eb-radio-bars {\n display: flex;\n align-items: flex-end;\n gap: 4px;\n height: 40px;\n}\n\n.eb-radio-bar {\n display: block;\n width: 6px;\n background: #fff;\n border-radius: 3px;\n animation: eb-radio-bar-bounce 0.8s ease-in-out infinite;\n}\n\n.eb-radio-bar:nth-child(1) { animation-delay: 0s; height: 20px; }\n.eb-radio-bar:nth-child(2) { animation-delay: 0.1s; height: 32px; }\n.eb-radio-bar:nth-child(3) { animation-delay: 0.2s; height: 40px; }\n.eb-radio-bar:nth-child(4) { animation-delay: 0.3s; height: 28px; }\n.eb-radio-bar:nth-child(5) { animation-delay: 0.4s; height: 16px; }\n\n@keyframes eb-radio-bar-bounce {\n 0%, 100% { transform: scaleY(0.4); opacity: 0.7; }\n 50% { transform: scaleY(1); opacity: 1; }\n}\n\n/* Volume mute button — base styles shared via .eb-button group above */\n\n/* ============================================================\n Live sync button\n ============================================================ */\n.eb-live-sync[hidden] {\n display: none;\n}\n\n.eb-live-synced {\n color: var(--eb-accent, var(--eb-color-primary, #e53935));\n}\n\n/* Default theme: show icon only, hide text badge elements */\n.eb-live-sync__dot,\n.eb-live-sync__label {\n display: none;\n}\n\n/* ============================================================\n Overlay panels (error, info, socials — mounted in .eb-player)\n ============================================================ */\n.eb-error-slot,\n.eb-info-slot,\n.eb-socials-slot {\n position: absolute;\n inset: 0;\n z-index: 50;\n pointer-events: none;\n}\n\n.eb-toast-slot {\n position: absolute;\n bottom: 60px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 50;\n pointer-events: none;\n}\n\n.eb-toast {\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n padding: 8px 20px;\n border-radius: 4px;\n font-size: 13px;\n white-space: nowrap;\n pointer-events: auto;\n}\n\n.eb-error,\n.eb-info-overlay,\n.eb-socials-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n z-index: 50;\n pointer-events: auto;\n padding: 24px;\n text-align: center;\n}\n\n.eb-error[hidden],\n.eb-info-overlay[hidden],\n.eb-socials-overlay[hidden] {\n display: none;\n}\n\n.eb-error-message {\n font-size: 16px;\n margin: 0 0 16px;\n}\n\n.eb-error-retry {\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 4px;\n padding: 8px 24px;\n font-size: 14px;\n cursor: pointer;\n}\n\n.eb-error-retry:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n.eb-info-content {\n font-size: 14px;\n line-height: 1.5;\n max-width: 400px;\n margin-bottom: 16px;\n}\n\n.eb-info-close,\n.eb-socials-close {\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 4px;\n padding: 8px 24px;\n font-size: 14px;\n cursor: pointer;\n}\n\n.eb-info-close:hover,\n.eb-socials-close:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n.eb-socials-links {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n justify-content: center;\n margin-bottom: 16px;\n}\n\n.eb-socials-link {\n color: #fff;\n text-decoration: none;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n padding: 8px 16px;\n font-size: 14px;\n text-transform: capitalize;\n}\n\n.eb-socials-link:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* ============================================================\n Loading spinner\n ============================================================ */\n.eb-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n color: #fff;\n pointer-events: none;\n}\n\n.eb-loading[hidden] {\n display: none;\n}\n\n.eb-loading .eb-icon {\n width: 40px;\n height: 40px;\n animation: eb-spin 1s linear infinite;\n}\n\n.eb-loading-text {\n font-size: 14px;\n}\n\n@keyframes eb-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n/* ============================================================\n Controls visibility\n ============================================================ */\n.eb-controls-visible .eb-top-bar,\n.eb-controls-visible .eb-bottom-bar,\n.eb-controls-visible .eb-middle-bar {\n opacity: 1;\n transition: opacity 0.3s;\n}\n\n.eb-controls-hidden .eb-top-bar,\n.eb-controls-hidden .eb-bottom-bar,\n.eb-controls-hidden .eb-middle-bar {\n opacity: 0;\n transition: opacity 0.3s;\n pointer-events: none;\n}\n\n/* ============================================================\n iOS native controls fallback\n ============================================================ */\n.eb-ios-native .eb-top-bar,\n.eb-ios-native .eb-bottom-bar,\n.eb-ios-native .eb-middle-bar,\n.eb-ios-native .eb-overlay-zone,\n.eb-ios-native .eb-error-slot,\n.eb-ios-native .eb-info-slot,\n.eb-ios-native .eb-socials-slot,\n.eb-ios-native .eb-toast-slot {\n display: none;\n}\n\n/* ============================================================\n RTL support\n ============================================================ */\n[dir=\"rtl\"] .eb-bottom-bar__controls-row {\n flex-direction: row-reverse;\n}\n\n[dir=\"rtl\"] .eb-top-bar {\n flex-direction: row-reverse;\n}\n\n/* ============================================================\n Responsive: ensure container fills parent\n ============================================================ */\n.eb-player,\n.eb-player video.eb-video {\n max-width: 100%;\n max-height: 100%;\n}\n";
|
|
55
55
|
styleInject(css_248z);
|
|
56
56
|
|
|
57
57
|
/**
|
|
@@ -1360,6 +1360,8 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1360
1360
|
this.tooltipX = 0;
|
|
1361
1361
|
this.previewVideoEl = null;
|
|
1362
1362
|
this.snapshotTake = null;
|
|
1363
|
+
this.trackEl = null;
|
|
1364
|
+
this.boundDocPointerMove = null;
|
|
1363
1365
|
}
|
|
1364
1366
|
onConnect() {
|
|
1365
1367
|
// Subscribe to snapshot handler readiness (emitted by eb-player.ts)
|
|
@@ -1380,6 +1382,10 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1380
1382
|
this.state.on('epgPrograms', () => this.scheduleRender(), { signal: this.signal });
|
|
1381
1383
|
this.render();
|
|
1382
1384
|
}
|
|
1385
|
+
disconnect() {
|
|
1386
|
+
this.stopDocumentTracking();
|
|
1387
|
+
super.disconnect();
|
|
1388
|
+
}
|
|
1383
1389
|
// ---- rAF batching ----
|
|
1384
1390
|
scheduleRender() {
|
|
1385
1391
|
if (this.rafPending)
|
|
@@ -1402,11 +1408,47 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1402
1408
|
const clamped = Math.min(1, Math.max(0, percent));
|
|
1403
1409
|
return clamped * this.state.duration;
|
|
1404
1410
|
}
|
|
1411
|
+
// ---- Document-level pointer tracking ----
|
|
1412
|
+
// pointerleave/mouseleave on the track are unreliable when the tooltip (a DOM child)
|
|
1413
|
+
// is absolutely positioned above the track — some browsers consider the pointer still
|
|
1414
|
+
// "inside" the track's subtree. Instead, we track pointer position at the document level
|
|
1415
|
+
// and hide the tooltip when the pointer moves outside the track's bounding rect.
|
|
1416
|
+
startDocumentTracking() {
|
|
1417
|
+
if (this.boundDocPointerMove)
|
|
1418
|
+
return;
|
|
1419
|
+
this.boundDocPointerMove = (event) => this.onDocPointerMove(event);
|
|
1420
|
+
document.addEventListener('pointermove', this.boundDocPointerMove);
|
|
1421
|
+
document.addEventListener('mouseleave', this.boundDocPointerMove);
|
|
1422
|
+
}
|
|
1423
|
+
stopDocumentTracking() {
|
|
1424
|
+
if (!this.boundDocPointerMove)
|
|
1425
|
+
return;
|
|
1426
|
+
document.removeEventListener('pointermove', this.boundDocPointerMove);
|
|
1427
|
+
document.removeEventListener('mouseleave', this.boundDocPointerMove);
|
|
1428
|
+
this.boundDocPointerMove = null;
|
|
1429
|
+
}
|
|
1430
|
+
onDocPointerMove(event) {
|
|
1431
|
+
if (this.isDragging)
|
|
1432
|
+
return;
|
|
1433
|
+
if (!this.trackEl)
|
|
1434
|
+
return;
|
|
1435
|
+
const rect = this.trackEl.getBoundingClientRect();
|
|
1436
|
+
const inBounds = event.clientX >= rect.left
|
|
1437
|
+
&& event.clientX <= rect.right
|
|
1438
|
+
&& event.clientY >= rect.top
|
|
1439
|
+
&& event.clientY <= rect.bottom;
|
|
1440
|
+
if (!inBounds) {
|
|
1441
|
+
this.tooltipVisible = false;
|
|
1442
|
+
this.stopDocumentTracking();
|
|
1443
|
+
this.render();
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1405
1446
|
// ---- Drag handlers ----
|
|
1406
1447
|
handlePointerDown(event) {
|
|
1407
1448
|
if (this.state.adPlaying)
|
|
1408
1449
|
return;
|
|
1409
1450
|
const trackEl = event.currentTarget;
|
|
1451
|
+
this.trackEl = trackEl;
|
|
1410
1452
|
// setPointerCapture ensures events continue firing even if pointer leaves the element
|
|
1411
1453
|
if (typeof trackEl.setPointerCapture === 'function') {
|
|
1412
1454
|
trackEl.setPointerCapture(event.pointerId);
|
|
@@ -1437,20 +1479,16 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1437
1479
|
const seekTime = this.eventToTime(event, trackEl);
|
|
1438
1480
|
this.isDragging = false;
|
|
1439
1481
|
this.bus.emit('seek', { time: seekTime });
|
|
1440
|
-
//
|
|
1441
|
-
|
|
1442
|
-
if (event.clientX < rect.left || event.clientX > rect.right) {
|
|
1443
|
-
this.tooltipVisible = false;
|
|
1444
|
-
}
|
|
1445
|
-
this.render();
|
|
1446
|
-
}
|
|
1447
|
-
handlePointerLeave() {
|
|
1482
|
+
// Always hide tooltip on pointer up — it reappears naturally via pointermove
|
|
1483
|
+
// if the pointer is still over the track.
|
|
1448
1484
|
this.tooltipVisible = false;
|
|
1485
|
+
this.stopDocumentTracking();
|
|
1449
1486
|
this.render();
|
|
1450
1487
|
}
|
|
1451
1488
|
// ---- Tooltip ----
|
|
1452
1489
|
updateTooltip(event) {
|
|
1453
1490
|
const trackEl = event.currentTarget;
|
|
1491
|
+
this.trackEl = trackEl;
|
|
1454
1492
|
const rect = trackEl.getBoundingClientRect();
|
|
1455
1493
|
// Compute hover time (use LTR calculation for tooltip position regardless of RTL)
|
|
1456
1494
|
const rawPercent = (event.clientX - rect.left) / rect.width;
|
|
@@ -1461,6 +1499,8 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1461
1499
|
// Position tooltip at pointer X relative to track, clamped to track edges
|
|
1462
1500
|
this.tooltipX = Math.min(rect.width, Math.max(0, event.clientX - rect.left));
|
|
1463
1501
|
this.tooltipVisible = true;
|
|
1502
|
+
// Start document-level tracking to detect when pointer leaves the track
|
|
1503
|
+
this.startDocumentTracking();
|
|
1464
1504
|
// Request snapshot frame for seekbar preview thumbnail
|
|
1465
1505
|
if (this.snapshotTake !== null) {
|
|
1466
1506
|
this.snapshotTake(this.tooltipTime);
|
|
@@ -1553,11 +1593,10 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1553
1593
|
const tooltip = b `
|
|
1554
1594
|
<div
|
|
1555
1595
|
class="eb-seekbar-tooltip"
|
|
1556
|
-
style="left: ${this.tooltipX}px"
|
|
1557
|
-
?hidden="${!this.tooltipVisible}"
|
|
1596
|
+
style="left: ${this.tooltipX}px; visibility: ${this.tooltipVisible ? 'visible' : 'hidden'}"
|
|
1558
1597
|
>
|
|
1559
|
-
${tooltipTimeText}
|
|
1560
1598
|
${this.previewVideoEl !== null ? this.previewVideoEl : b ``}
|
|
1599
|
+
${tooltipTimeText}
|
|
1561
1600
|
</div>
|
|
1562
1601
|
`;
|
|
1563
1602
|
return b `
|
|
@@ -1570,7 +1609,6 @@ var EBPlayerBundle = (function (exports) {
|
|
|
1570
1609
|
@pointerdown="${(event) => this.handlePointerDown(event)}"
|
|
1571
1610
|
@pointermove="${(event) => this.handlePointerMove(event)}"
|
|
1572
1611
|
@pointerup="${(event) => this.handlePointerUp(event)}"
|
|
1573
|
-
@pointerleave="${() => this.handlePointerLeave()}"
|
|
1574
1612
|
>
|
|
1575
1613
|
<div class="eb-seekbar-buffered" style="width: ${bufferedPercent.toFixed(2)}%"></div>
|
|
1576
1614
|
<div class="eb-seekbar-progress" style="width: ${progressPercent.toFixed(2)}%">
|
|
@@ -2268,13 +2306,24 @@ var EBPlayerBundle = (function (exports) {
|
|
|
2268
2306
|
*
|
|
2269
2307
|
* - Calls screenfull.toggle() with the closest .eb-player ancestor on click
|
|
2270
2308
|
* - Subscribes to screenfull 'change' event to update state.isFullscreen
|
|
2271
|
-
* -
|
|
2309
|
+
* - Falls back to video-element fullscreen on mobile (iOS Safari webkitEnterFullscreen,
|
|
2310
|
+
* Android Chrome video.requestFullscreen) when the Fullscreen API is not available
|
|
2311
|
+
* for arbitrary elements
|
|
2272
2312
|
* - Re-renders when state.isFullscreen changes
|
|
2273
2313
|
*/
|
|
2274
2314
|
class FullscreenButton extends BaseComponent {
|
|
2275
2315
|
constructor() {
|
|
2276
2316
|
super(...arguments);
|
|
2277
2317
|
this.changeHandler = null;
|
|
2318
|
+
this.videoEl = null;
|
|
2319
|
+
this.videoFullscreenBeginHandler = null;
|
|
2320
|
+
this.videoFullscreenEndHandler = null;
|
|
2321
|
+
this.useVideoFallback = false;
|
|
2322
|
+
this.handleDocFullscreenChange = () => {
|
|
2323
|
+
const isFullscreen = document.fullscreenElement === this.videoEl;
|
|
2324
|
+
this.state.isFullscreen = isFullscreen;
|
|
2325
|
+
this.render();
|
|
2326
|
+
};
|
|
2278
2327
|
}
|
|
2279
2328
|
onConnect() {
|
|
2280
2329
|
this.state.on('isFullscreen', () => this.render(), { signal: this.signal });
|
|
@@ -2284,25 +2333,90 @@ var EBPlayerBundle = (function (exports) {
|
|
|
2284
2333
|
this.render();
|
|
2285
2334
|
};
|
|
2286
2335
|
screenfull$1.on('change', this.changeHandler);
|
|
2287
|
-
// Unsubscribe when signal aborts (on disconnect)
|
|
2288
2336
|
this.signal.addEventListener('abort', () => {
|
|
2289
2337
|
screenfull$1.off('change', this.changeHandler);
|
|
2290
2338
|
this.changeHandler = null;
|
|
2291
2339
|
});
|
|
2292
2340
|
}
|
|
2341
|
+
else {
|
|
2342
|
+
// Fullscreen API not available for elements — try video-element fallback (mobile)
|
|
2343
|
+
this.initVideoFallback();
|
|
2344
|
+
}
|
|
2293
2345
|
this.render();
|
|
2294
2346
|
}
|
|
2347
|
+
/**
|
|
2348
|
+
* On mobile browsers the Fullscreen API may not work on arbitrary elements,
|
|
2349
|
+
* but the <video> element itself supports fullscreen via webkitEnterFullscreen
|
|
2350
|
+
* (iOS Safari) or video.requestFullscreen() (Android Chrome).
|
|
2351
|
+
*/
|
|
2352
|
+
initVideoFallback() {
|
|
2353
|
+
const playerRoot = this.el?.closest('.eb-player');
|
|
2354
|
+
if (!playerRoot)
|
|
2355
|
+
return;
|
|
2356
|
+
const video = playerRoot.querySelector('video.eb-video');
|
|
2357
|
+
if (!video)
|
|
2358
|
+
return;
|
|
2359
|
+
// iOS Safari: webkitSupportsFullscreen + webkitEnterFullscreen
|
|
2360
|
+
const hasWebkitFullscreen = typeof video.webkitEnterFullscreen === 'function';
|
|
2361
|
+
// Android Chrome: standard requestFullscreen on the video element
|
|
2362
|
+
const hasRequestFullscreen = typeof video.requestFullscreen === 'function';
|
|
2363
|
+
if (!hasWebkitFullscreen && !hasRequestFullscreen)
|
|
2364
|
+
return;
|
|
2365
|
+
this.videoEl = video;
|
|
2366
|
+
this.useVideoFallback = true;
|
|
2367
|
+
// Track fullscreen state changes on the video element
|
|
2368
|
+
this.videoFullscreenBeginHandler = () => {
|
|
2369
|
+
this.state.isFullscreen = true;
|
|
2370
|
+
this.render();
|
|
2371
|
+
};
|
|
2372
|
+
this.videoFullscreenEndHandler = () => {
|
|
2373
|
+
this.state.isFullscreen = false;
|
|
2374
|
+
this.render();
|
|
2375
|
+
};
|
|
2376
|
+
// iOS Safari fires these events on the video element
|
|
2377
|
+
video.addEventListener('webkitbeginfullscreen', this.videoFullscreenBeginHandler);
|
|
2378
|
+
video.addEventListener('webkitendfullscreen', this.videoFullscreenEndHandler);
|
|
2379
|
+
// Android Chrome fires standard fullscreenchange on the document
|
|
2380
|
+
document.addEventListener('fullscreenchange', this.handleDocFullscreenChange);
|
|
2381
|
+
this.signal.addEventListener('abort', () => {
|
|
2382
|
+
video.removeEventListener('webkitbeginfullscreen', this.videoFullscreenBeginHandler);
|
|
2383
|
+
video.removeEventListener('webkitendfullscreen', this.videoFullscreenEndHandler);
|
|
2384
|
+
document.removeEventListener('fullscreenchange', this.handleDocFullscreenChange);
|
|
2385
|
+
this.videoFullscreenBeginHandler = null;
|
|
2386
|
+
this.videoFullscreenEndHandler = null;
|
|
2387
|
+
this.videoEl = null;
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2295
2390
|
handleClick() {
|
|
2296
|
-
if (
|
|
2391
|
+
if (screenfull$1.isEnabled) {
|
|
2392
|
+
const container = (this.el.closest('.eb-player') ?? this.el);
|
|
2393
|
+
screenfull$1.toggle(container);
|
|
2297
2394
|
return;
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2395
|
+
}
|
|
2396
|
+
if (this.useVideoFallback && this.videoEl) {
|
|
2397
|
+
if (this.state.isFullscreen) {
|
|
2398
|
+
// Exit fullscreen
|
|
2399
|
+
if (typeof this.videoEl.webkitExitFullscreen === 'function') {
|
|
2400
|
+
this.videoEl.webkitExitFullscreen();
|
|
2401
|
+
}
|
|
2402
|
+
else if (document.exitFullscreen) {
|
|
2403
|
+
document.exitFullscreen();
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
else {
|
|
2407
|
+
// Enter fullscreen
|
|
2408
|
+
if (typeof this.videoEl.webkitEnterFullscreen === 'function') {
|
|
2409
|
+
this.videoEl.webkitEnterFullscreen();
|
|
2410
|
+
}
|
|
2411
|
+
else if (typeof this.videoEl.requestFullscreen === 'function') {
|
|
2412
|
+
this.videoEl.requestFullscreen();
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2303
2416
|
}
|
|
2304
2417
|
template() {
|
|
2305
|
-
|
|
2418
|
+
const canFullscreen = screenfull$1.isEnabled || this.useVideoFallback;
|
|
2419
|
+
if (!canFullscreen) {
|
|
2306
2420
|
return b `<button class="eb-fullscreen" hidden aria-hidden="true">${icon('fullscreen')}</button>`;
|
|
2307
2421
|
}
|
|
2308
2422
|
const isFullscreen = this.state.isFullscreen;
|
|
@@ -5928,7 +6042,7 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5928
6042
|
init(HlsConstructor) {
|
|
5929
6043
|
// Create an off-screen video element for the snapshot player
|
|
5930
6044
|
const offscreenVideo = document.createElement('video');
|
|
5931
|
-
offscreenVideo.preload = '
|
|
6045
|
+
offscreenVideo.preload = 'metadata';
|
|
5932
6046
|
this.offscreenVideo = offscreenVideo;
|
|
5933
6047
|
// Capture tokenManager via closure (Pitfall 6)
|
|
5934
6048
|
const tokenManager = this.tokenManager;
|
|
@@ -5959,11 +6073,17 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5959
6073
|
}
|
|
5960
6074
|
PLoader = SnapshotPLoader;
|
|
5961
6075
|
}
|
|
6076
|
+
// Strip player-specific keys that are NOT hls.js config options — they contain
|
|
6077
|
+
// non-serializable functions that cause DataCloneError when hls.js posts config to its worker.
|
|
6078
|
+
const rawSettings = { ...(this.config.engineSettings ?? {}) };
|
|
6079
|
+
delete rawSettings['extraParamsCallback'];
|
|
6080
|
+
delete rawSettings['onCDNTokenError'];
|
|
5962
6081
|
const driverConfig = {
|
|
5963
6082
|
startLevel: 0,
|
|
5964
6083
|
enableWebVTT: false,
|
|
6084
|
+
enableWorker: false,
|
|
5965
6085
|
maxBufferLength: 1,
|
|
5966
|
-
...
|
|
6086
|
+
...rawSettings,
|
|
5967
6087
|
...(PLoader ? { pLoader: PLoader } : {})
|
|
5968
6088
|
};
|
|
5969
6089
|
const driver = new HlsConstructor(driverConfig);
|
|
@@ -6294,8 +6414,30 @@ var EBPlayerBundle = (function (exports) {
|
|
|
6294
6414
|
else {
|
|
6295
6415
|
const win = window;
|
|
6296
6416
|
if (win.Hls) {
|
|
6297
|
-
|
|
6298
|
-
|
|
6417
|
+
// Create a dedicated token manager for the snapshot handler (DRM license + manifest tokens)
|
|
6418
|
+
let snapshotTokenManager = null;
|
|
6419
|
+
if (mergedConfig.token) {
|
|
6420
|
+
snapshotTokenManager = new CDNTokenManager({
|
|
6421
|
+
token: mergedConfig.token,
|
|
6422
|
+
tokenType: mergedConfig.tokenType,
|
|
6423
|
+
srcInTokenRequest: mergedConfig.srcInTokenRequest,
|
|
6424
|
+
extraParamsCallback: (mergedConfig.engineSettings.extraParamsCallback ?? mergedConfig.extraParamsCallback),
|
|
6425
|
+
onCDNTokenError: mergedConfig.engineSettings.onCDNTokenError
|
|
6426
|
+
});
|
|
6427
|
+
}
|
|
6428
|
+
// Build DRM config (emeEnabled, drmSystems, licenseXhrSetup) for the snapshot hls.js instance
|
|
6429
|
+
const snapshotDrmConfigurator = new DrmConfigurator(snapshotTokenManager);
|
|
6430
|
+
const snapshotDrmConfig = snapshotDrmConfigurator.buildHlsConfig(mergedConfig.engineSettings);
|
|
6431
|
+
const handler = new HlsSnapshotHandler({ src, engineSettings: { ...mergedConfig.engineSettings, ...snapshotDrmConfig } }, snapshotTokenManager);
|
|
6432
|
+
// Fetch initial token before init (needed for manifest request)
|
|
6433
|
+
const tokenReady = snapshotTokenManager && src
|
|
6434
|
+
? snapshotTokenManager.fetchToken({ src }).catch((error) => {
|
|
6435
|
+
console.warn('EBPlayer: Snapshot token fetch failed:', error);
|
|
6436
|
+
})
|
|
6437
|
+
: Promise.resolve();
|
|
6438
|
+
tokenReady.then(() => {
|
|
6439
|
+
return handler.init(win.Hls);
|
|
6440
|
+
})
|
|
6299
6441
|
.then(() => {
|
|
6300
6442
|
activeSnapshotDestroy = () => handler.destroy();
|
|
6301
6443
|
const snapshotVideo = handler.getVideo();
|