@guardvideo/player-sdk 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -243
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.esm.js +700 -58
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +699 -57
- package/dist/index.js.map +1 -1
- package/dist/react/GuardVideoPlayer.d.ts.map +1 -1
- package/dist/vanilla/core/types.d.ts.map +1 -1
- package/dist/vanilla/guardvideo-player.js +651 -25
- package/dist/vanilla/guardvideo-player.js.map +1 -1
- package/dist/vanilla/guardvideo-player.min.js +1 -37321
- package/dist/vanilla/guardvideo-player.min.js.map +1 -1
- package/dist/vanilla/react/GuardVideoPlayer.d.ts.map +1 -1
- package/dist/vanilla/vanilla/index.d.ts +115 -6
- package/dist/vanilla/vanilla/index.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -36688,7 +36688,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))} pos: ${this.timeline
|
|
|
36688
36688
|
security: { ...DEFAULT_SECURITY, ...config.security },
|
|
36689
36689
|
viewerName: config.viewerName || '',
|
|
36690
36690
|
viewerEmail: config.viewerEmail || '',
|
|
36691
|
-
forensicWatermark: config.forensicWatermark
|
|
36691
|
+
forensicWatermark: config.forensicWatermark !== false,
|
|
36692
36692
|
onReady: config.onReady || (() => { }),
|
|
36693
36693
|
onError: config.onError || (() => { }),
|
|
36694
36694
|
onQualityChange: config.onQualityChange || (() => { }),
|
|
@@ -37083,7 +37083,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))} pos: ${this.timeline
|
|
|
37083
37083
|
maxViews: null,
|
|
37084
37084
|
...(this.config.viewerName ? { viewerName: this.config.viewerName } : {}),
|
|
37085
37085
|
...(this.config.viewerEmail ? { viewerEmail: this.config.viewerEmail } : {}),
|
|
37086
|
-
|
|
37086
|
+
forensicWatermark: this.config.forensicWatermark,
|
|
37087
37087
|
}),
|
|
37088
37088
|
});
|
|
37089
37089
|
if (!response.ok) {
|
|
@@ -37281,33 +37281,659 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))} pos: ${this.timeline
|
|
|
37281
37281
|
}
|
|
37282
37282
|
};
|
|
37283
37283
|
|
|
37284
|
-
|
|
37285
|
-
|
|
37286
|
-
|
|
37287
|
-
|
|
37288
|
-
|
|
37289
|
-
|
|
37290
|
-
|
|
37291
|
-
|
|
37292
|
-
|
|
37293
|
-
|
|
37294
|
-
|
|
37295
|
-
|
|
37284
|
+
function formatTime(seconds) {
|
|
37285
|
+
if (!isFinite(seconds) || isNaN(seconds))
|
|
37286
|
+
return '0:00';
|
|
37287
|
+
const h = Math.floor(seconds / 3600);
|
|
37288
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
37289
|
+
const s = Math.floor(seconds % 60);
|
|
37290
|
+
const mm = String(m).padStart(h > 0 ? 2 : 1, '0');
|
|
37291
|
+
const ss = String(s).padStart(2, '0');
|
|
37292
|
+
return h > 0 ? `${h}:${mm}:${ss}` : `${mm}:${ss}`;
|
|
37293
|
+
}
|
|
37294
|
+
function el(tag, cls, attrs) {
|
|
37295
|
+
const e = document.createElement(tag);
|
|
37296
|
+
if (cls)
|
|
37297
|
+
e.className = cls;
|
|
37298
|
+
if (attrs)
|
|
37299
|
+
Object.entries(attrs).forEach(([k, v]) => e.setAttribute(k, v));
|
|
37300
|
+
return e;
|
|
37301
|
+
}
|
|
37302
|
+
function svg(path, w = 20, h = 20) {
|
|
37303
|
+
const s = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
37304
|
+
s.setAttribute('width', String(w));
|
|
37305
|
+
s.setAttribute('height', String(h));
|
|
37306
|
+
s.setAttribute('viewBox', '0 0 24 24');
|
|
37307
|
+
s.setAttribute('fill', 'currentColor');
|
|
37308
|
+
s.innerHTML = path;
|
|
37309
|
+
return s;
|
|
37310
|
+
}
|
|
37311
|
+
const ICON = {
|
|
37312
|
+
play: '<polygon points="5,3 19,12 5,21"/>',
|
|
37313
|
+
pause: '<rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/>',
|
|
37314
|
+
replay: '<path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/>',
|
|
37315
|
+
volHigh: '<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>',
|
|
37316
|
+
volMute: '<path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/>',
|
|
37317
|
+
fsEnter: '<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>',
|
|
37318
|
+
fsExit: '<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>',
|
|
37319
|
+
settings: '<path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94zM12,15.6c-1.98,0-3.6-1.62-3.6-3.6s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"/>',
|
|
37320
|
+
shield: '<path fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>',
|
|
37321
|
+
};
|
|
37322
|
+
let _stylesInjected = false;
|
|
37323
|
+
function injectStyles(accent) {
|
|
37324
|
+
if (_stylesInjected)
|
|
37325
|
+
return;
|
|
37326
|
+
_stylesInjected = true;
|
|
37327
|
+
const css = `
|
|
37328
|
+
/* ── GuardVideo Custom Player ─────────────── */
|
|
37329
|
+
.gvp-root{position:relative;background:#000;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;border-radius:10px;overflow:hidden;-webkit-user-select:none;user-select:none;outline:none;}
|
|
37330
|
+
.gvp-root:focus-visible{box-shadow:0 0 0 3px ${accent}66;}
|
|
37331
|
+
.gvp-video{display:block;width:100%;height:100%;object-fit:contain;border-radius:10px;}
|
|
37332
|
+
|
|
37333
|
+
/* Spinner */
|
|
37334
|
+
.gvp-spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;background:rgba(0,0,0,.55);border-radius:10px;}
|
|
37335
|
+
.gvp-spinner-ring{width:48px;height:48px;border:3px solid rgba(255,255,255,.15);border-top-color:${accent};border-radius:50%;animation:gvp-spin .8s linear infinite;}
|
|
37336
|
+
@keyframes gvp-spin{to{transform:rotate(360deg);}}
|
|
37337
|
+
.gvp-spinner-hidden{display:none;}
|
|
37338
|
+
|
|
37339
|
+
/* Centre play */
|
|
37340
|
+
.gvp-center-play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;cursor:pointer;background:rgba(0,0,0,.3);transition:background .2s;border-radius:10px;z-index:3;}
|
|
37341
|
+
.gvp-center-play:hover{background:rgba(0,0,0,.45);}
|
|
37342
|
+
.gvp-center-play-btn{width:72px;height:72px;background:rgba(255,255,255,.12);backdrop-filter:blur(8px);border-radius:50%;display:flex;align-items:center;justify-content:center;border:2px solid rgba(255,255,255,.25);transition:background .2s,transform .15s;color:#fff;}
|
|
37343
|
+
.gvp-center-play:hover .gvp-center-play-btn{background:${accent}cc;transform:scale(1.08);}
|
|
37344
|
+
.gvp-center-play-hidden{display:none;}
|
|
37345
|
+
|
|
37346
|
+
/* Click overlay */
|
|
37347
|
+
.gvp-click-area{position:absolute;inset:0;cursor:pointer;z-index:1;}
|
|
37348
|
+
.gvp-click-area-hidden{display:none;}
|
|
37349
|
+
|
|
37350
|
+
/* Ripple */
|
|
37351
|
+
.gvp-ripple{position:absolute;border-radius:50%;transform:scale(0);background:rgba(255,255,255,.25);animation:gvp-ripple-anim .5s ease-out forwards;pointer-events:none;z-index:2;}
|
|
37352
|
+
@keyframes gvp-ripple-anim{to{transform:scale(4);opacity:0;}}
|
|
37353
|
+
|
|
37354
|
+
/* Controls bar */
|
|
37355
|
+
.gvp-controls{position:absolute;bottom:0;left:0;right:0;z-index:10;background:linear-gradient(to top,rgba(0,0,0,.85) 0%,transparent 100%);padding:36px 14px 10px;transition:opacity .3s,transform .3s;border-radius:0 0 10px 10px;}
|
|
37356
|
+
.gvp-controls-hidden{opacity:0;transform:translateY(6px);pointer-events:none;}
|
|
37357
|
+
|
|
37358
|
+
/* Seek bar */
|
|
37359
|
+
.gvp-seek-row{display:flex;align-items:center;gap:8px;margin-bottom:6px;}
|
|
37360
|
+
.gvp-seek-wrap{flex:1;position:relative;height:4px;cursor:pointer;padding:8px 0;margin:-8px 0;box-sizing:content-box;}
|
|
37361
|
+
.gvp-seek-track{height:4px;background:rgba(255,255,255,.2);border-radius:4px;position:relative;overflow:hidden;transition:height .15s;}
|
|
37362
|
+
.gvp-seek-wrap:hover .gvp-seek-track{height:6px;}
|
|
37363
|
+
.gvp-seek-buffered{position:absolute;left:0;top:0;height:100%;background:rgba(255,255,255,.35);border-radius:4px;pointer-events:none;}
|
|
37364
|
+
.gvp-seek-progress{position:absolute;left:0;top:0;height:100%;background:${accent};border-radius:4px;pointer-events:none;transition:width .1s linear;}
|
|
37365
|
+
.gvp-seek-thumb{position:absolute;top:50%;transform:translate(-50%,-50%);width:13px;height:13px;background:#fff;border-radius:50%;box-shadow:0 1px 4px rgba(0,0,0,.5);pointer-events:none;opacity:0;transition:opacity .15s;}
|
|
37366
|
+
.gvp-seek-wrap:hover .gvp-seek-thumb{opacity:1;}
|
|
37367
|
+
.gvp-seek-tooltip{position:absolute;bottom:24px;transform:translateX(-50%);background:rgba(0,0,0,.8);color:#fff;font-size:11px;font-weight:500;padding:3px 7px;border-radius:4px;pointer-events:none;white-space:nowrap;opacity:0;transition:opacity .1s;}
|
|
37368
|
+
.gvp-seek-wrap:hover .gvp-seek-tooltip{opacity:1;}
|
|
37369
|
+
|
|
37370
|
+
/* Button row */
|
|
37371
|
+
.gvp-btn-row{display:flex;align-items:center;gap:4px;}
|
|
37372
|
+
.gvp-btn{background:none;border:none;color:#fff;cursor:pointer;padding:5px;border-radius:6px;display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s;flex-shrink:0;}
|
|
37373
|
+
.gvp-btn:hover{background:rgba(255,255,255,.12);color:${accent};}
|
|
37374
|
+
.gvp-btn:active{background:rgba(255,255,255,.2);}
|
|
37375
|
+
|
|
37376
|
+
/* Volume */
|
|
37377
|
+
.gvp-volume-wrap{display:flex;align-items:center;gap:5px;}
|
|
37378
|
+
.gvp-volume-slider{-webkit-appearance:none;width:70px;height:4px;background:rgba(255,255,255,.25);border-radius:4px;outline:none;cursor:pointer;accent-color:${accent};}
|
|
37379
|
+
.gvp-volume-slider::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;background:#fff;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.4);}
|
|
37380
|
+
.gvp-volume-slider::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#fff;cursor:pointer;border:none;}
|
|
37381
|
+
|
|
37382
|
+
/* Time */
|
|
37383
|
+
.gvp-time{font-size:12px;color:rgba(255,255,255,.85);font-variant-numeric:tabular-nums;white-space:nowrap;letter-spacing:.02em;}
|
|
37384
|
+
.gvp-spacer{flex:1;}
|
|
37385
|
+
|
|
37386
|
+
/* Menus */
|
|
37387
|
+
.gvp-menu-wrap{position:relative;}
|
|
37388
|
+
.gvp-menu{position:absolute;bottom:calc(100% + 8px);right:0;background:rgba(18,18,22,.95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.08);border-radius:8px;min-width:140px;overflow:hidden;box-shadow:0 8px 24px rgba(0,0,0,.5);animation:gvp-menu-in .1s ease-out;z-index:20;}
|
|
37389
|
+
.gvp-menu-hidden{display:none;}
|
|
37390
|
+
@keyframes gvp-menu-in{from{opacity:0;transform:scale(.95) translateY(4px);}to{opacity:1;transform:scale(1) translateY(0);}}
|
|
37391
|
+
.gvp-menu-title{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:rgba(255,255,255,.4);padding:8px 12px 4px;}
|
|
37392
|
+
.gvp-menu-item{display:flex;align-items:center;justify-content:space-between;padding:7px 12px;font-size:13px;color:rgba(255,255,255,.85);cursor:pointer;transition:background .12s;gap:10px;}
|
|
37393
|
+
.gvp-menu-item:hover{background:rgba(255,255,255,.07);}
|
|
37394
|
+
.gvp-menu-item-active{color:${accent};font-weight:600;}
|
|
37395
|
+
.gvp-menu-check{font-size:14px;color:${accent};}
|
|
37396
|
+
.gvp-menu-sep{height:1px;background:rgba(255,255,255,.07);margin:3px 0;}
|
|
37397
|
+
|
|
37398
|
+
/* Error */
|
|
37399
|
+
.gvp-error{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.8);color:#fff;gap:10px;padding:24px;border-radius:10px;text-align:center;}
|
|
37400
|
+
.gvp-error-hidden{display:none;}
|
|
37401
|
+
.gvp-error-icon{font-size:36px;}
|
|
37402
|
+
.gvp-error-code{font-size:11px;font-weight:700;letter-spacing:.1em;color:#f87171;text-transform:uppercase;}
|
|
37403
|
+
.gvp-error-msg{font-size:14px;color:rgba(255,255,255,.7);max-width:320px;line-height:1.5;}
|
|
37404
|
+
|
|
37405
|
+
/* Secure badge */
|
|
37406
|
+
.gvp-badge{position:absolute;top:10px;right:12px;display:flex;align-items:center;gap:5px;background:rgba(0,0,0,.55);backdrop-filter:blur(6px);border-radius:20px;padding:3px 9px 3px 7px;font-size:10px;font-weight:600;color:${accent};pointer-events:none;z-index:5;letter-spacing:.04em;transition:opacity .3s;}
|
|
37407
|
+
.gvp-badge-hidden{opacity:0;}
|
|
37408
|
+
|
|
37409
|
+
/* Watermark */
|
|
37410
|
+
.gvp-watermark{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:6;}
|
|
37411
|
+
.gvp-watermark-text{position:absolute;white-space:nowrap;font-size:13px;font-family:monospace;color:rgba(255,255,255,.065);transform:rotate(-28deg);user-select:none;pointer-events:none;letter-spacing:.05em;}
|
|
37412
|
+
|
|
37413
|
+
/* Speed */
|
|
37414
|
+
.gvp-rate-label{font-size:11px;font-weight:700;color:rgba(255,255,255,.7);min-width:28px;text-align:center;cursor:pointer;padding:5px 4px;border-radius:4px;transition:background .12s;flex-shrink:0;}
|
|
37415
|
+
.gvp-rate-label:hover{background:rgba(255,255,255,.1);}
|
|
37416
|
+
`;
|
|
37417
|
+
const tag = document.createElement('style');
|
|
37418
|
+
tag.setAttribute('data-guardvideo', 'player-ui-styles');
|
|
37419
|
+
tag.textContent = css;
|
|
37420
|
+
document.head.appendChild(tag);
|
|
37421
|
+
}
|
|
37422
|
+
const SPEEDS = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
37423
|
+
class VanillaPlayerUI {
|
|
37424
|
+
constructor(container, videoId, config) {
|
|
37425
|
+
this.playerState = exports.PlayerState.IDLE;
|
|
37426
|
+
this.duration = 0;
|
|
37427
|
+
this.bufferedEnd = 0;
|
|
37428
|
+
this.qualityLevels = [];
|
|
37429
|
+
this.currentQualityIdx = -1;
|
|
37430
|
+
this.playbackRate = 1;
|
|
37431
|
+
this.openMenu = null;
|
|
37432
|
+
this.hideTimer = null;
|
|
37433
|
+
this.watermarkText = null;
|
|
37434
|
+
this.seekDragging = false;
|
|
37435
|
+
this.accent = config.branding?.accentColor ?? '#44c09b';
|
|
37436
|
+
this.brandName = config.branding?.name ?? 'GuardVideo';
|
|
37437
|
+
const forensic = config.forensicWatermark !== false;
|
|
37438
|
+
injectStyles(this.accent);
|
|
37439
|
+
this.buildDOM(container, config.width ?? '100%', config.height ?? 'auto');
|
|
37440
|
+
this.wireEvents(videoId, config, forensic);
|
|
37441
|
+
if (forensic) {
|
|
37442
|
+
const wtxt = config.viewerEmail || config.viewerName || '';
|
|
37443
|
+
if (wtxt) {
|
|
37444
|
+
setTimeout(() => {
|
|
37445
|
+
this.watermarkText = wtxt;
|
|
37446
|
+
this.renderWatermark();
|
|
37447
|
+
}, 1500);
|
|
37448
|
+
}
|
|
37449
|
+
}
|
|
37450
|
+
}
|
|
37451
|
+
buildDOM(container, width, height) {
|
|
37296
37452
|
container.innerHTML = '';
|
|
37297
|
-
|
|
37298
|
-
|
|
37299
|
-
|
|
37300
|
-
|
|
37453
|
+
this.root = el('div', 'gvp-root');
|
|
37454
|
+
this.root.style.width = width;
|
|
37455
|
+
this.root.style.height = height;
|
|
37456
|
+
this.root.setAttribute('tabindex', '0');
|
|
37457
|
+
this.videoEl = el('video', 'gvp-video', { playsinline: '', preload: 'metadata' });
|
|
37458
|
+
this.badge = el('div', 'gvp-badge');
|
|
37459
|
+
const shieldSvg = svg(ICON.shield, 14, 14);
|
|
37460
|
+
shieldSvg.style.color = this.accent;
|
|
37461
|
+
this.badge.appendChild(shieldSvg);
|
|
37462
|
+
this.badge.appendChild(document.createTextNode(this.brandName));
|
|
37463
|
+
this.watermarkDiv = el('div', 'gvp-watermark');
|
|
37464
|
+
this.spinner = el('div', 'gvp-spinner gvp-spinner-hidden');
|
|
37465
|
+
this.spinner.appendChild(el('div', 'gvp-spinner-ring'));
|
|
37466
|
+
this.errorOverlay = el('div', 'gvp-error gvp-error-hidden');
|
|
37467
|
+
const errIcon = el('div', 'gvp-error-icon');
|
|
37468
|
+
errIcon.textContent = '⚠️';
|
|
37469
|
+
const errCode = el('div', 'gvp-error-code');
|
|
37470
|
+
errCode.id = 'gvp-err-code';
|
|
37471
|
+
const errMsg = el('div', 'gvp-error-msg');
|
|
37472
|
+
errMsg.id = 'gvp-err-msg';
|
|
37473
|
+
this.errorOverlay.append(errIcon, errCode, errMsg);
|
|
37474
|
+
this.centerPlay = el('div', 'gvp-center-play');
|
|
37475
|
+
this.centerPlayBtn = el('div', 'gvp-center-play-btn');
|
|
37476
|
+
this.centerPlayBtn.appendChild(svg(ICON.play, 32, 32));
|
|
37477
|
+
this.centerPlay.appendChild(this.centerPlayBtn);
|
|
37478
|
+
this.clickArea = el('div', 'gvp-click-area gvp-click-area-hidden');
|
|
37479
|
+
this.controls = el('div', 'gvp-controls');
|
|
37480
|
+
const seekRow = el('div', 'gvp-seek-row');
|
|
37481
|
+
this.seekWrap = el('div', 'gvp-seek-wrap');
|
|
37482
|
+
const seekTrack = el('div', 'gvp-seek-track');
|
|
37483
|
+
this.seekBuffered = el('div', 'gvp-seek-buffered');
|
|
37484
|
+
this.seekProgress = el('div', 'gvp-seek-progress');
|
|
37485
|
+
this.seekThumb = el('div', 'gvp-seek-thumb');
|
|
37486
|
+
this.seekTooltip = el('div', 'gvp-seek-tooltip');
|
|
37487
|
+
seekTrack.append(this.seekBuffered, this.seekProgress);
|
|
37488
|
+
this.seekWrap.append(seekTrack, this.seekThumb, this.seekTooltip);
|
|
37489
|
+
seekRow.appendChild(this.seekWrap);
|
|
37490
|
+
this.controls.appendChild(seekRow);
|
|
37491
|
+
const btnRow = el('div', 'gvp-btn-row');
|
|
37492
|
+
this.playBtn = el('button', 'gvp-btn');
|
|
37493
|
+
this.playBtn.title = 'Play (k)';
|
|
37494
|
+
this.playBtn.appendChild(svg(ICON.play));
|
|
37495
|
+
const volWrap = el('div', 'gvp-volume-wrap');
|
|
37496
|
+
this.volBtn = el('button', 'gvp-btn');
|
|
37497
|
+
this.volBtn.title = 'Mute (m)';
|
|
37498
|
+
this.volBtn.appendChild(svg(ICON.volHigh, 18, 18));
|
|
37499
|
+
this.volSlider = el('input', 'gvp-volume-slider');
|
|
37500
|
+
this.volSlider.type = 'range';
|
|
37501
|
+
this.volSlider.min = '0';
|
|
37502
|
+
this.volSlider.max = '1';
|
|
37503
|
+
this.volSlider.step = '0.02';
|
|
37504
|
+
this.volSlider.value = '1';
|
|
37505
|
+
this.volSlider.title = 'Volume';
|
|
37506
|
+
volWrap.append(this.volBtn, this.volSlider);
|
|
37507
|
+
this.timeEl = el('span', 'gvp-time');
|
|
37508
|
+
this.timeEl.textContent = '0:00 / 0:00';
|
|
37509
|
+
const spacer = el('div', 'gvp-spacer');
|
|
37510
|
+
const speedWrap = el('div', 'gvp-menu-wrap');
|
|
37511
|
+
this.speedLabel = el('span', 'gvp-rate-label');
|
|
37512
|
+
this.speedLabel.textContent = '1×';
|
|
37513
|
+
this.speedLabel.title = 'Playback speed';
|
|
37514
|
+
this.speedMenu = el('div', 'gvp-menu gvp-menu-hidden');
|
|
37515
|
+
const speedTitle = el('div', 'gvp-menu-title');
|
|
37516
|
+
speedTitle.textContent = 'Speed';
|
|
37517
|
+
this.speedMenu.appendChild(speedTitle);
|
|
37518
|
+
SPEEDS.forEach(r => {
|
|
37519
|
+
const item = el('div', `gvp-menu-item${r === 1 ? ' gvp-menu-item-active' : ''}`);
|
|
37520
|
+
item.textContent = r === 1 ? 'Normal' : `${r}×`;
|
|
37521
|
+
item.dataset['speed'] = String(r);
|
|
37522
|
+
this.speedMenu.appendChild(item);
|
|
37523
|
+
});
|
|
37524
|
+
speedWrap.append(this.speedLabel, this.speedMenu);
|
|
37525
|
+
const qualWrap = el('div', 'gvp-menu-wrap');
|
|
37526
|
+
this.settingsBtn = el('button', 'gvp-btn');
|
|
37527
|
+
this.settingsBtn.title = 'Quality settings';
|
|
37528
|
+
this.settingsBtn.appendChild(svg(ICON.settings, 18, 18));
|
|
37529
|
+
this.settingsBtn.style.display = 'none';
|
|
37530
|
+
this.qualityMenu = el('div', 'gvp-menu gvp-menu-hidden');
|
|
37531
|
+
qualWrap.append(this.settingsBtn, this.qualityMenu);
|
|
37532
|
+
this.fsBtn = el('button', 'gvp-btn');
|
|
37533
|
+
this.fsBtn.title = 'Fullscreen (f)';
|
|
37534
|
+
this.fsBtn.appendChild(svg(ICON.fsEnter, 18, 18));
|
|
37535
|
+
btnRow.append(this.playBtn, volWrap, this.timeEl, spacer, speedWrap, qualWrap, this.fsBtn);
|
|
37536
|
+
this.controls.appendChild(btnRow);
|
|
37537
|
+
this.root.append(this.videoEl, this.badge, this.watermarkDiv, this.spinner, this.errorOverlay, this.centerPlay, this.clickArea, this.controls);
|
|
37538
|
+
container.appendChild(this.root);
|
|
37539
|
+
}
|
|
37540
|
+
wireEvents(videoId, config, forensicWatermark) {
|
|
37541
|
+
const video = this.videoEl;
|
|
37542
|
+
this.corePlayer = new GuardVideoPlayer$1(video, videoId, {
|
|
37543
|
+
...config,
|
|
37544
|
+
controls: false,
|
|
37545
|
+
forensicWatermark,
|
|
37546
|
+
onReady: () => {
|
|
37547
|
+
config.onReady?.();
|
|
37548
|
+
setTimeout(() => {
|
|
37549
|
+
this.qualityLevels = this.corePlayer.getQualityLevels();
|
|
37550
|
+
this.buildQualityMenu();
|
|
37551
|
+
}, 100);
|
|
37552
|
+
},
|
|
37553
|
+
onError: (err) => {
|
|
37554
|
+
this.showError(err);
|
|
37555
|
+
config.onError?.(err);
|
|
37556
|
+
},
|
|
37557
|
+
onQualityChange: (quality) => {
|
|
37558
|
+
const idx = this.qualityLevels.findIndex(l => l.name === quality);
|
|
37559
|
+
this.currentQualityIdx = idx;
|
|
37560
|
+
this.refreshQualityMenu();
|
|
37561
|
+
config.onQualityChange?.(quality);
|
|
37562
|
+
},
|
|
37563
|
+
onStateChange: (state) => {
|
|
37564
|
+
this.onStateChange(state);
|
|
37565
|
+
config.onStateChange?.(state);
|
|
37566
|
+
},
|
|
37567
|
+
});
|
|
37568
|
+
video.addEventListener('timeupdate', () => this.onTimeUpdate());
|
|
37569
|
+
video.addEventListener('loadedmetadata', () => { this.duration = video.duration || 0; this.onTimeUpdate(); });
|
|
37570
|
+
video.addEventListener('durationchange', () => { this.duration = video.duration || 0; });
|
|
37571
|
+
video.addEventListener('progress', () => {
|
|
37572
|
+
if (video.buffered.length > 0) {
|
|
37573
|
+
this.bufferedEnd = video.buffered.end(video.buffered.length - 1);
|
|
37574
|
+
this.updateSeekBar();
|
|
37575
|
+
}
|
|
37576
|
+
});
|
|
37577
|
+
video.addEventListener('volumechange', () => this.onVolumeChange());
|
|
37578
|
+
video.addEventListener('ended', () => {
|
|
37579
|
+
this.showControls(true);
|
|
37580
|
+
this.renderPlayBtn();
|
|
37581
|
+
});
|
|
37582
|
+
video.addEventListener('ratechange', () => {
|
|
37583
|
+
this.playbackRate = video.playbackRate;
|
|
37584
|
+
this.speedLabel.textContent = this.playbackRate === 1 ? '1×' : `${this.playbackRate}×`;
|
|
37585
|
+
});
|
|
37586
|
+
this.playBtn.addEventListener('click', (e) => { e.stopPropagation(); this.togglePlay(); });
|
|
37587
|
+
this.volBtn.addEventListener('click', (e) => { e.stopPropagation(); this.toggleMute(); });
|
|
37588
|
+
this.volSlider.addEventListener('input', () => {
|
|
37589
|
+
video.volume = parseFloat(this.volSlider.value);
|
|
37590
|
+
video.muted = video.volume === 0;
|
|
37591
|
+
});
|
|
37592
|
+
this.seekWrap.addEventListener('click', (e) => {
|
|
37593
|
+
e.stopPropagation();
|
|
37594
|
+
this.seekTo(e);
|
|
37595
|
+
this.resetHideTimer();
|
|
37596
|
+
});
|
|
37597
|
+
this.seekWrap.addEventListener('mousemove', (e) => this.onSeekHover(e));
|
|
37598
|
+
this.seekWrap.addEventListener('mouseleave', () => { this.seekTooltip.style.opacity = '0'; });
|
|
37599
|
+
this.seekWrap.addEventListener('mousedown', (e) => {
|
|
37600
|
+
this.seekDragging = true;
|
|
37601
|
+
this.seekTo(e);
|
|
37602
|
+
const onMove = (ev) => { if (this.seekDragging)
|
|
37603
|
+
this.seekTo(ev); };
|
|
37604
|
+
const onUp = () => { this.seekDragging = false; window.removeEventListener('mousemove', onMove); window.removeEventListener('mouseup', onUp); };
|
|
37605
|
+
window.addEventListener('mousemove', onMove);
|
|
37606
|
+
window.addEventListener('mouseup', onUp);
|
|
37607
|
+
});
|
|
37608
|
+
this.speedLabel.addEventListener('click', (e) => {
|
|
37609
|
+
e.stopPropagation();
|
|
37610
|
+
this.toggleMenu('speed');
|
|
37611
|
+
});
|
|
37612
|
+
this.speedMenu.addEventListener('click', (e) => {
|
|
37613
|
+
e.stopPropagation();
|
|
37614
|
+
const item = e.target.closest('[data-speed]');
|
|
37615
|
+
if (!item)
|
|
37616
|
+
return;
|
|
37617
|
+
const r = parseFloat(item.dataset['speed']);
|
|
37618
|
+
video.playbackRate = r;
|
|
37619
|
+
this.closeMenus();
|
|
37620
|
+
});
|
|
37621
|
+
this.settingsBtn.addEventListener('click', (e) => {
|
|
37622
|
+
e.stopPropagation();
|
|
37623
|
+
this.toggleMenu('quality');
|
|
37624
|
+
});
|
|
37625
|
+
this.qualityMenu.addEventListener('click', (e) => {
|
|
37626
|
+
e.stopPropagation();
|
|
37627
|
+
const item = e.target.closest('[data-quality]');
|
|
37628
|
+
if (!item)
|
|
37629
|
+
return;
|
|
37630
|
+
const idx = parseInt(item.dataset['quality']);
|
|
37631
|
+
this.corePlayer.setQuality(idx);
|
|
37632
|
+
this.currentQualityIdx = idx;
|
|
37633
|
+
this.refreshQualityMenu();
|
|
37634
|
+
this.closeMenus();
|
|
37635
|
+
});
|
|
37636
|
+
this.clickArea.addEventListener('click', (e) => {
|
|
37637
|
+
this.addRipple(e);
|
|
37638
|
+
this.togglePlay();
|
|
37639
|
+
});
|
|
37640
|
+
this.centerPlay.addEventListener('click', (e) => { e.stopPropagation(); this.togglePlay(); });
|
|
37641
|
+
this.fsBtn.addEventListener('click', (e) => { e.stopPropagation(); this.toggleFullscreen(); });
|
|
37642
|
+
document.addEventListener('fullscreenchange', () => this.onFsChange());
|
|
37643
|
+
this.root.addEventListener('mousemove', () => this.resetHideTimer());
|
|
37644
|
+
this.root.addEventListener('mouseleave', () => {
|
|
37645
|
+
if (this.playerState === exports.PlayerState.PLAYING)
|
|
37646
|
+
this.showControls(false);
|
|
37647
|
+
});
|
|
37648
|
+
this.root.addEventListener('click', () => this.closeMenus());
|
|
37649
|
+
this.root.addEventListener('keydown', (e) => {
|
|
37650
|
+
switch (e.code) {
|
|
37651
|
+
case 'Space':
|
|
37652
|
+
case 'KeyK':
|
|
37653
|
+
e.preventDefault();
|
|
37654
|
+
this.togglePlay();
|
|
37655
|
+
break;
|
|
37656
|
+
case 'ArrowLeft':
|
|
37657
|
+
e.preventDefault();
|
|
37658
|
+
this.corePlayer.seek(Math.max(0, video.currentTime - 5));
|
|
37659
|
+
break;
|
|
37660
|
+
case 'ArrowRight':
|
|
37661
|
+
e.preventDefault();
|
|
37662
|
+
this.corePlayer.seek(Math.min(this.duration, video.currentTime + 5));
|
|
37663
|
+
break;
|
|
37664
|
+
case 'ArrowUp':
|
|
37665
|
+
e.preventDefault();
|
|
37666
|
+
video.volume = Math.min(1, video.volume + 0.1);
|
|
37667
|
+
break;
|
|
37668
|
+
case 'ArrowDown':
|
|
37669
|
+
e.preventDefault();
|
|
37670
|
+
video.volume = Math.max(0, video.volume - 0.1);
|
|
37671
|
+
break;
|
|
37672
|
+
case 'KeyM':
|
|
37673
|
+
e.preventDefault();
|
|
37674
|
+
this.toggleMute();
|
|
37675
|
+
break;
|
|
37676
|
+
case 'KeyF':
|
|
37677
|
+
e.preventDefault();
|
|
37678
|
+
this.toggleFullscreen();
|
|
37679
|
+
break;
|
|
37680
|
+
}
|
|
37681
|
+
});
|
|
37682
|
+
}
|
|
37683
|
+
onStateChange(state) {
|
|
37684
|
+
this.playerState = state;
|
|
37685
|
+
const loading = state === exports.PlayerState.LOADING || state === exports.PlayerState.BUFFERING;
|
|
37686
|
+
const idle = state === exports.PlayerState.IDLE;
|
|
37687
|
+
const ended = this.videoEl.ended;
|
|
37688
|
+
this.spinner.classList.toggle('gvp-spinner-hidden', !loading);
|
|
37689
|
+
const showCenter = (idle || ended) && !loading;
|
|
37690
|
+
this.centerPlay.classList.toggle('gvp-center-play-hidden', !showCenter);
|
|
37691
|
+
if (showCenter) {
|
|
37692
|
+
this.centerPlayBtn.innerHTML = '';
|
|
37693
|
+
this.centerPlayBtn.appendChild(svg(ended ? ICON.replay : ICON.play, 32, 32));
|
|
37694
|
+
}
|
|
37695
|
+
this.clickArea.classList.toggle('gvp-click-area-hidden', idle);
|
|
37696
|
+
if (state !== exports.PlayerState.PLAYING) {
|
|
37697
|
+
this.showControls(true);
|
|
37698
|
+
if (this.hideTimer) {
|
|
37699
|
+
clearTimeout(this.hideTimer);
|
|
37700
|
+
this.hideTimer = null;
|
|
37701
|
+
}
|
|
37702
|
+
}
|
|
37703
|
+
else {
|
|
37704
|
+
this.resetHideTimer();
|
|
37705
|
+
}
|
|
37706
|
+
this.renderPlayBtn();
|
|
37707
|
+
}
|
|
37708
|
+
togglePlay() {
|
|
37709
|
+
const video = this.videoEl;
|
|
37710
|
+
if (video.paused || video.ended) {
|
|
37711
|
+
this.corePlayer.play().catch(() => { });
|
|
37712
|
+
}
|
|
37713
|
+
else {
|
|
37714
|
+
this.corePlayer.pause();
|
|
37715
|
+
}
|
|
37716
|
+
this.resetHideTimer();
|
|
37717
|
+
}
|
|
37718
|
+
renderPlayBtn() {
|
|
37719
|
+
const video = this.videoEl;
|
|
37720
|
+
const ended = video.ended;
|
|
37721
|
+
const playing = this.playerState === exports.PlayerState.PLAYING;
|
|
37722
|
+
this.playBtn.innerHTML = '';
|
|
37723
|
+
this.playBtn.appendChild(svg(ended ? ICON.replay : playing ? ICON.pause : ICON.play));
|
|
37724
|
+
this.playBtn.title = playing ? 'Pause (k)' : 'Play (k)';
|
|
37725
|
+
}
|
|
37726
|
+
toggleMute() {
|
|
37727
|
+
this.videoEl.muted = !this.videoEl.muted;
|
|
37728
|
+
}
|
|
37729
|
+
onVolumeChange() {
|
|
37730
|
+
const video = this.videoEl;
|
|
37731
|
+
const muted = video.muted || video.volume === 0;
|
|
37732
|
+
this.volBtn.innerHTML = '';
|
|
37733
|
+
this.volBtn.appendChild(svg(muted ? ICON.volMute : ICON.volHigh, 18, 18));
|
|
37734
|
+
this.volSlider.value = String(muted ? 0 : video.volume);
|
|
37735
|
+
}
|
|
37736
|
+
seekTo(e) {
|
|
37737
|
+
if (!this.duration)
|
|
37738
|
+
return;
|
|
37739
|
+
const rect = this.seekWrap.getBoundingClientRect();
|
|
37740
|
+
const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
37741
|
+
this.corePlayer.seek(pct * this.duration);
|
|
37742
|
+
}
|
|
37743
|
+
onSeekHover(e) {
|
|
37744
|
+
if (!this.duration)
|
|
37745
|
+
return;
|
|
37746
|
+
const rect = this.seekWrap.getBoundingClientRect();
|
|
37747
|
+
const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
37748
|
+
this.seekTooltip.textContent = formatTime(pct * this.duration);
|
|
37749
|
+
this.seekTooltip.style.left = `${pct * 100}%`;
|
|
37750
|
+
this.seekTooltip.style.opacity = '1';
|
|
37751
|
+
}
|
|
37752
|
+
onTimeUpdate() {
|
|
37753
|
+
const video = this.videoEl;
|
|
37754
|
+
const ct = video.currentTime;
|
|
37755
|
+
this.timeEl.textContent = `${formatTime(ct)} / ${formatTime(this.duration)}`;
|
|
37756
|
+
this.updateSeekBar();
|
|
37757
|
+
}
|
|
37758
|
+
updateSeekBar() {
|
|
37759
|
+
const ct = this.videoEl.currentTime;
|
|
37760
|
+
const dur = this.duration;
|
|
37761
|
+
if (!dur)
|
|
37762
|
+
return;
|
|
37763
|
+
const pPct = (ct / dur) * 100;
|
|
37764
|
+
const bPct = (this.bufferedEnd / dur) * 100;
|
|
37765
|
+
this.seekProgress.style.width = `${pPct}%`;
|
|
37766
|
+
this.seekBuffered.style.width = `${bPct}%`;
|
|
37767
|
+
this.seekThumb.style.left = `${pPct}%`;
|
|
37768
|
+
}
|
|
37769
|
+
buildQualityMenu() {
|
|
37770
|
+
if (!this.qualityLevels.length)
|
|
37771
|
+
return;
|
|
37772
|
+
this.settingsBtn.style.display = '';
|
|
37773
|
+
this.qualityMenu.innerHTML = '';
|
|
37774
|
+
const title = el('div', 'gvp-menu-title');
|
|
37775
|
+
title.textContent = 'Quality';
|
|
37776
|
+
const autoItem = el('div', 'gvp-menu-item gvp-menu-item-active');
|
|
37777
|
+
autoItem.dataset['quality'] = '-1';
|
|
37778
|
+
autoItem.textContent = 'Auto';
|
|
37779
|
+
const check = el('span', 'gvp-menu-check');
|
|
37780
|
+
check.textContent = '✓';
|
|
37781
|
+
autoItem.appendChild(check);
|
|
37782
|
+
const sep = el('div', 'gvp-menu-sep');
|
|
37783
|
+
this.qualityMenu.append(title, autoItem, sep);
|
|
37784
|
+
[...this.qualityLevels].reverse().forEach(q => {
|
|
37785
|
+
const item = el('div', 'gvp-menu-item');
|
|
37786
|
+
item.dataset['quality'] = String(q.index);
|
|
37787
|
+
item.textContent = q.name;
|
|
37788
|
+
this.qualityMenu.appendChild(item);
|
|
37789
|
+
});
|
|
37790
|
+
this.currentQualityIdx = -1;
|
|
37791
|
+
}
|
|
37792
|
+
refreshQualityMenu() {
|
|
37793
|
+
this.qualityMenu.querySelectorAll('[data-quality]').forEach(item => {
|
|
37794
|
+
const idx = parseInt(item.dataset['quality']);
|
|
37795
|
+
const active = idx === this.currentQualityIdx;
|
|
37796
|
+
item.className = `gvp-menu-item${active ? ' gvp-menu-item-active' : ''}`;
|
|
37797
|
+
const existing = item.querySelector('.gvp-menu-check');
|
|
37798
|
+
if (active && !existing) {
|
|
37799
|
+
const check = el('span', 'gvp-menu-check');
|
|
37800
|
+
check.textContent = '✓';
|
|
37801
|
+
item.appendChild(check);
|
|
37802
|
+
}
|
|
37803
|
+
else if (!active && existing) {
|
|
37804
|
+
existing.remove();
|
|
37805
|
+
}
|
|
37806
|
+
});
|
|
37301
37807
|
}
|
|
37302
|
-
|
|
37303
|
-
|
|
37304
|
-
|
|
37305
|
-
:
|
|
37306
|
-
|
|
37307
|
-
|
|
37808
|
+
refreshSpeedMenu() {
|
|
37809
|
+
this.speedMenu.querySelectorAll('[data-speed]').forEach(item => {
|
|
37810
|
+
const r = parseFloat(item.dataset['speed']);
|
|
37811
|
+
item.className = `gvp-menu-item${r === this.playbackRate ? ' gvp-menu-item-active' : ''}`;
|
|
37812
|
+
});
|
|
37813
|
+
}
|
|
37814
|
+
toggleMenu(which) {
|
|
37815
|
+
const same = this.openMenu === which;
|
|
37816
|
+
this.closeMenus();
|
|
37817
|
+
if (!same) {
|
|
37818
|
+
this.openMenu = which;
|
|
37819
|
+
if (which === 'speed') {
|
|
37820
|
+
this.refreshSpeedMenu();
|
|
37821
|
+
this.speedMenu.classList.remove('gvp-menu-hidden');
|
|
37822
|
+
}
|
|
37823
|
+
else {
|
|
37824
|
+
this.refreshQualityMenu();
|
|
37825
|
+
this.qualityMenu.classList.remove('gvp-menu-hidden');
|
|
37826
|
+
}
|
|
37308
37827
|
}
|
|
37309
|
-
return new GuardVideoPlayer(element, videoId, config);
|
|
37310
37828
|
}
|
|
37829
|
+
closeMenus() {
|
|
37830
|
+
this.openMenu = null;
|
|
37831
|
+
this.speedMenu.classList.add('gvp-menu-hidden');
|
|
37832
|
+
this.qualityMenu.classList.add('gvp-menu-hidden');
|
|
37833
|
+
}
|
|
37834
|
+
showControls(visible) {
|
|
37835
|
+
this.controls.classList.toggle('gvp-controls-hidden', !visible);
|
|
37836
|
+
this.badge.classList.toggle('gvp-badge-hidden', !visible);
|
|
37837
|
+
}
|
|
37838
|
+
resetHideTimer() {
|
|
37839
|
+
this.showControls(true);
|
|
37840
|
+
if (this.hideTimer)
|
|
37841
|
+
clearTimeout(this.hideTimer);
|
|
37842
|
+
this.hideTimer = setTimeout(() => {
|
|
37843
|
+
if (this.playerState === exports.PlayerState.PLAYING)
|
|
37844
|
+
this.showControls(false);
|
|
37845
|
+
}, 2800);
|
|
37846
|
+
}
|
|
37847
|
+
toggleFullscreen() {
|
|
37848
|
+
if (document.fullscreenElement) {
|
|
37849
|
+
document.exitFullscreen().catch(() => { });
|
|
37850
|
+
}
|
|
37851
|
+
else {
|
|
37852
|
+
this.root.requestFullscreen().catch(() => { });
|
|
37853
|
+
}
|
|
37854
|
+
}
|
|
37855
|
+
onFsChange() {
|
|
37856
|
+
const fs = !!document.fullscreenElement;
|
|
37857
|
+
this.fsBtn.innerHTML = '';
|
|
37858
|
+
this.fsBtn.appendChild(svg(fs ? ICON.fsExit : ICON.fsEnter, 18, 18));
|
|
37859
|
+
this.fsBtn.title = fs ? 'Exit fullscreen (f)' : 'Fullscreen (f)';
|
|
37860
|
+
}
|
|
37861
|
+
showError(err) {
|
|
37862
|
+
const codeEl = this.root.querySelector('#gvp-err-code');
|
|
37863
|
+
const msgEl = this.root.querySelector('#gvp-err-msg');
|
|
37864
|
+
if (codeEl)
|
|
37865
|
+
codeEl.textContent = err.code;
|
|
37866
|
+
if (msgEl)
|
|
37867
|
+
msgEl.textContent = err.message;
|
|
37868
|
+
this.errorOverlay.classList.remove('gvp-error-hidden');
|
|
37869
|
+
this.controls.style.display = 'none';
|
|
37870
|
+
}
|
|
37871
|
+
renderWatermark() {
|
|
37872
|
+
if (!this.watermarkText)
|
|
37873
|
+
return;
|
|
37874
|
+
this.watermarkDiv.innerHTML = '';
|
|
37875
|
+
for (let i = 0; i < 20; i++) {
|
|
37876
|
+
const span = el('span', 'gvp-watermark-text');
|
|
37877
|
+
span.textContent = this.watermarkText;
|
|
37878
|
+
span.style.left = `${(i % 4) * 26 + (Math.floor(i / 4) % 2) * 13}%`;
|
|
37879
|
+
span.style.top = `${Math.floor(i / 4) * 22}%`;
|
|
37880
|
+
this.watermarkDiv.appendChild(span);
|
|
37881
|
+
}
|
|
37882
|
+
}
|
|
37883
|
+
addRipple(e) {
|
|
37884
|
+
const rect = this.root.getBoundingClientRect();
|
|
37885
|
+
const d = document.createElement('div');
|
|
37886
|
+
d.className = 'gvp-ripple';
|
|
37887
|
+
const size = 60;
|
|
37888
|
+
d.style.cssText = `width:${size}px;height:${size}px;left:${e.clientX - rect.left - size / 2}px;top:${e.clientY - rect.top - size / 2}px`;
|
|
37889
|
+
this.root.appendChild(d);
|
|
37890
|
+
setTimeout(() => d.remove(), 600);
|
|
37891
|
+
}
|
|
37892
|
+
play() { return this.corePlayer.play(); }
|
|
37893
|
+
pause() { return this.corePlayer.pause(); }
|
|
37894
|
+
seek(t) { return this.corePlayer.seek(t); }
|
|
37895
|
+
getCurrentTime() { return this.corePlayer.getCurrentTime(); }
|
|
37896
|
+
getDuration() { return this.corePlayer.getDuration(); }
|
|
37897
|
+
getVolume() { return this.corePlayer.getVolume(); }
|
|
37898
|
+
setVolume(v) { return this.corePlayer.setVolume(v); }
|
|
37899
|
+
getQualityLevels() { return this.corePlayer.getQualityLevels(); }
|
|
37900
|
+
getCurrentQuality() { return this.corePlayer.getCurrentQuality(); }
|
|
37901
|
+
setQuality(i) { return this.corePlayer.setQuality(i); }
|
|
37902
|
+
getState() { return this.corePlayer.getState(); }
|
|
37903
|
+
getVideoElement() { return this.videoEl; }
|
|
37904
|
+
destroy() {
|
|
37905
|
+
if (this.hideTimer)
|
|
37906
|
+
clearTimeout(this.hideTimer);
|
|
37907
|
+
this.corePlayer.destroy();
|
|
37908
|
+
this.root.remove();
|
|
37909
|
+
}
|
|
37910
|
+
}
|
|
37911
|
+
class GuardVideoPlayer {
|
|
37912
|
+
constructor(ui) {
|
|
37913
|
+
this.ui = ui;
|
|
37914
|
+
}
|
|
37915
|
+
static create(containerId, videoId, config) {
|
|
37916
|
+
const container = document.getElementById(containerId);
|
|
37917
|
+
if (!container)
|
|
37918
|
+
throw new Error(`Container "#${containerId}" not found`);
|
|
37919
|
+
return new GuardVideoPlayer(new VanillaPlayerUI(container, videoId, config));
|
|
37920
|
+
}
|
|
37921
|
+
static createInElement(container, videoId, config) {
|
|
37922
|
+
return new GuardVideoPlayer(new VanillaPlayerUI(container, videoId, config));
|
|
37923
|
+
}
|
|
37924
|
+
play() { return this.ui.play(); }
|
|
37925
|
+
pause() { return this.ui.pause(); }
|
|
37926
|
+
seek(time) { return this.ui.seek(time); }
|
|
37927
|
+
getCurrentTime() { return this.ui.getCurrentTime(); }
|
|
37928
|
+
getDuration() { return this.ui.getDuration(); }
|
|
37929
|
+
getVolume() { return this.ui.getVolume(); }
|
|
37930
|
+
setVolume(volume) { return this.ui.setVolume(volume); }
|
|
37931
|
+
getQualityLevels() { return this.ui.getQualityLevels(); }
|
|
37932
|
+
getCurrentQuality() { return this.ui.getCurrentQuality(); }
|
|
37933
|
+
setQuality(idx) { return this.ui.setQuality(idx); }
|
|
37934
|
+
getState() { return this.ui.getState(); }
|
|
37935
|
+
getVideoElement() { return this.ui.getVideoElement(); }
|
|
37936
|
+
destroy() { return this.ui.destroy(); }
|
|
37311
37937
|
}
|
|
37312
37938
|
if (typeof window !== 'undefined') {
|
|
37313
37939
|
window.GuardVideoPlayer = GuardVideoPlayer;
|