eb-player 2.0.8 → 2.0.10
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/ebplayer.bundle.js +86 -24
- 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/cdn-token-manager.d.ts +1 -0
- package/dist/build/types/engines/cdn-token-manager.d.ts.map +1 -1
- package/dist/build/types/engines/hls.d.ts.map +1 -1
- package/dist/build/types/engines/snapshot/hls.d.ts +10 -0
- package/dist/build/types/engines/snapshot/hls.d.ts.map +1 -1
- package/dist/dev/default.js +445 -98
- package/dist/dev/default.js.map +1 -1
- package/dist/dev/easybroadcast.js +125 -49
- package/dist/dev/easybroadcast.js.map +1 -1
- package/dist/dev/equipe.js +424 -83
- package/dist/dev/equipe.js.map +1 -1
- package/dist/players/equipe/EB_lequipe-preprod.js +6 -6
- package/package.json +1 -1
|
@@ -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.9";
|
|
5
5
|
|
|
6
6
|
function styleInject(css, ref) {
|
|
7
7
|
if ( ref === void 0 ) ref = {};
|
|
@@ -4332,6 +4332,15 @@ var EBPlayerBundle = (function (exports) {
|
|
|
4332
4332
|
video.addEventListener('ended', () => {
|
|
4333
4333
|
state.playbackState = 'ended';
|
|
4334
4334
|
}, { signal });
|
|
4335
|
+
// Safety net: clear stale 'buffering' state when playback is clearly advancing.
|
|
4336
|
+
// In some edge cases (live stream segment boundaries), the browser fires 'waiting'
|
|
4337
|
+
// but never fires 'playing' even though video resumes from buffer. The timeupdate
|
|
4338
|
+
// event fires reliably while time advances, so we use it to recover.
|
|
4339
|
+
video.addEventListener('timeupdate', () => {
|
|
4340
|
+
if (state.playbackState === 'buffering' && !video.paused && video.readyState >= 3) {
|
|
4341
|
+
state.playbackState = 'playing';
|
|
4342
|
+
}
|
|
4343
|
+
}, { signal });
|
|
4335
4344
|
}
|
|
4336
4345
|
/**
|
|
4337
4346
|
* Seek to a specific time. Default implementation sets video.currentTime.
|
|
@@ -4526,6 +4535,7 @@ var EBPlayerBundle = (function (exports) {
|
|
|
4526
4535
|
this.expirationMarginInSeconds = expirationMarginInSeconds;
|
|
4527
4536
|
this.lastTokenResponse = null;
|
|
4528
4537
|
this.resetAttemptCounterTimeout = null;
|
|
4538
|
+
this.inFlightFetch = null;
|
|
4529
4539
|
}
|
|
4530
4540
|
resetAttemptCounter() {
|
|
4531
4541
|
if (this.resetAttemptCounterTimeout) {
|
|
@@ -4769,21 +4779,35 @@ var EBPlayerBundle = (function (exports) {
|
|
|
4769
4779
|
console.warn('CDNToken: Missing src to tokenize');
|
|
4770
4780
|
return null;
|
|
4771
4781
|
}
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
break;
|
|
4779
|
-
case TOKEN_TYPES.VENOM:
|
|
4780
|
-
case TOKEN_TYPES.EASY_B:
|
|
4781
|
-
this.lastTokenResponse = await this._fetchEasyBToken(src);
|
|
4782
|
-
break;
|
|
4783
|
-
default:
|
|
4784
|
-
this.lastTokenResponse = await this._fetchDefaultToken(src);
|
|
4782
|
+
// Deduplicate concurrent fetches: if a fetch is already in flight,
|
|
4783
|
+
// return the same promise instead of firing a second network request.
|
|
4784
|
+
// This prevents the main player and snapshot handler from both triggering
|
|
4785
|
+
// separate generate calls when their manifest refreshes overlap.
|
|
4786
|
+
if (this.inFlightFetch) {
|
|
4787
|
+
return this.inFlightFetch;
|
|
4785
4788
|
}
|
|
4786
|
-
|
|
4789
|
+
const doFetch = async () => {
|
|
4790
|
+
switch (this.tokenType) {
|
|
4791
|
+
case TOKEN_TYPES.BUNNY:
|
|
4792
|
+
return this._fetchBunnyToken(src);
|
|
4793
|
+
case TOKEN_TYPES.AKAMAI:
|
|
4794
|
+
return this._fetchAkamaiToken(src);
|
|
4795
|
+
case TOKEN_TYPES.VENOM:
|
|
4796
|
+
case TOKEN_TYPES.EASY_B:
|
|
4797
|
+
return this._fetchEasyBToken(src);
|
|
4798
|
+
default:
|
|
4799
|
+
return this._fetchDefaultToken(src);
|
|
4800
|
+
}
|
|
4801
|
+
};
|
|
4802
|
+
this.inFlightFetch = doFetch().then((response) => {
|
|
4803
|
+
this.lastTokenResponse = response;
|
|
4804
|
+
this.inFlightFetch = null;
|
|
4805
|
+
return response;
|
|
4806
|
+
}).catch((error) => {
|
|
4807
|
+
this.inFlightFetch = null;
|
|
4808
|
+
throw error;
|
|
4809
|
+
});
|
|
4810
|
+
return this.inFlightFetch;
|
|
4787
4811
|
}
|
|
4788
4812
|
// -------------------------------------------------------------------------
|
|
4789
4813
|
// Public: updateUrlWithTokenParams
|
|
@@ -4886,6 +4910,7 @@ var EBPlayerBundle = (function (exports) {
|
|
|
4886
4910
|
}
|
|
4887
4911
|
this.attempt = 0;
|
|
4888
4912
|
this.lastTokenResponse = null;
|
|
4913
|
+
this.inFlightFetch = null;
|
|
4889
4914
|
console.log('CDNTokenManager: destroyed');
|
|
4890
4915
|
}
|
|
4891
4916
|
// -------------------------------------------------------------------------
|
|
@@ -5160,6 +5185,14 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5160
5185
|
getDriver() {
|
|
5161
5186
|
return this.driver;
|
|
5162
5187
|
}
|
|
5188
|
+
/**
|
|
5189
|
+
* Returns the CDN token manager used by this engine.
|
|
5190
|
+
* Allows the snapshot handler to share the same manager (avoids duplicate token requests).
|
|
5191
|
+
* Returns null when no token URL is configured or before init().
|
|
5192
|
+
*/
|
|
5193
|
+
getTokenManager() {
|
|
5194
|
+
return this.tokenManager;
|
|
5195
|
+
}
|
|
5163
5196
|
// -------------------------------------------------------------------------
|
|
5164
5197
|
// BaseEngine hooks
|
|
5165
5198
|
// -------------------------------------------------------------------------
|
|
@@ -5275,7 +5308,9 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5275
5308
|
if (!hlsjsUrl) {
|
|
5276
5309
|
throw new Error('HlsEngine: config.hlsjs URL is required');
|
|
5277
5310
|
}
|
|
5278
|
-
// Create token manager if a token URL is configured
|
|
5311
|
+
// Create token manager if a token URL is configured.
|
|
5312
|
+
// No initial fetchToken() here — updateUrlWithTokenParams() below handles it
|
|
5313
|
+
// and populates lastTokenResponse (used lazily by DRM licenseXhrSetup).
|
|
5279
5314
|
if (config.token) {
|
|
5280
5315
|
this.tokenManager = new CDNTokenManager({
|
|
5281
5316
|
token: config.token,
|
|
@@ -5284,13 +5319,6 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5284
5319
|
extraParamsCallback: (config.engineSettings.extraParamsCallback ?? config.extraParamsCallback),
|
|
5285
5320
|
onCDNTokenError: config.engineSettings.onCDNTokenError
|
|
5286
5321
|
});
|
|
5287
|
-
// Fetch initial token
|
|
5288
|
-
if (config.src) {
|
|
5289
|
-
await this.tokenManager.fetchToken({ src: config.src });
|
|
5290
|
-
}
|
|
5291
|
-
// Guard: abort if detached during token fetch
|
|
5292
|
-
if (this.detached)
|
|
5293
|
-
return;
|
|
5294
5322
|
}
|
|
5295
5323
|
// console.info('HlsEngine: loading hls.js from', hlsjsUrl)
|
|
5296
5324
|
const Hls = await loadScript(hlsjsUrl, 'Hls');
|
|
@@ -5373,7 +5401,6 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5373
5401
|
// Create the driver (NEVER stored in state)
|
|
5374
5402
|
const driver = new Hls(driverConfig);
|
|
5375
5403
|
this.driver = driver;
|
|
5376
|
-
this.resolveDriverReady();
|
|
5377
5404
|
// Pitfall 4: apply discontinuity workaround BEFORE attachMedia/loadSource
|
|
5378
5405
|
applyDiscontinuityWorkaround(driver, Hls.Events);
|
|
5379
5406
|
// Wire retry handler
|
|
@@ -5396,8 +5423,27 @@ var EBPlayerBundle = (function (exports) {
|
|
|
5396
5423
|
}
|
|
5397
5424
|
}
|
|
5398
5425
|
driver.loadSource(src);
|
|
5426
|
+
// Resolve driverReady AFTER loadSource so consumers (P2P, snapshot handler)
|
|
5427
|
+
// don't start making token requests before the main engine's initial token
|
|
5428
|
+
// fetch completes and populates the cache.
|
|
5429
|
+
this.resolveDriverReady();
|
|
5399
5430
|
// Register driver event handlers
|
|
5400
5431
|
this.registerDriverEvents(Hls, state);
|
|
5432
|
+
// Pause/resume loading on video pause/play to stop manifest refreshes
|
|
5433
|
+
// (and thus CDN token requests) while the player is paused.
|
|
5434
|
+
// Only applies to live streams where hls.js continuously refreshes the manifest.
|
|
5435
|
+
const driverRef = driver;
|
|
5436
|
+
video.addEventListener('pause', () => {
|
|
5437
|
+
if (this.state?.isLive) {
|
|
5438
|
+
driverRef.stopLoad();
|
|
5439
|
+
}
|
|
5440
|
+
}, { signal });
|
|
5441
|
+
video.addEventListener('play', () => {
|
|
5442
|
+
if (this.state?.isLive) {
|
|
5443
|
+
// Defer startLoad to avoid re-entrancy (Pitfall 3)
|
|
5444
|
+
setTimeout(() => driverRef.startLoad(-1), 0);
|
|
5445
|
+
}
|
|
5446
|
+
}, { signal });
|
|
5401
5447
|
// Start stall watchdog
|
|
5402
5448
|
this.startWatchdog();
|
|
5403
5449
|
}
|
|
@@ -6131,6 +6177,24 @@ var EBPlayerBundle = (function (exports) {
|
|
|
6131
6177
|
getVideo() {
|
|
6132
6178
|
return this.offscreenVideo;
|
|
6133
6179
|
}
|
|
6180
|
+
/**
|
|
6181
|
+
* Stop manifest refreshes (and thus CDN token requests) while the main player is paused.
|
|
6182
|
+
* For live streams, the snapshot hls.js instance continuously refreshes the manifest
|
|
6183
|
+
* on the playlist interval — this prevents unnecessary generate calls during pause.
|
|
6184
|
+
*/
|
|
6185
|
+
stopLoad() {
|
|
6186
|
+
if (this.driver && typeof this.driver['stopLoad'] === 'function') {
|
|
6187
|
+
this.driver['stopLoad']();
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6190
|
+
/**
|
|
6191
|
+
* Resume manifest refreshes when the main player resumes playback.
|
|
6192
|
+
*/
|
|
6193
|
+
startLoad() {
|
|
6194
|
+
if (this.driver && typeof this.driver['startLoad'] === 'function') {
|
|
6195
|
+
this.driver['startLoad'](-1);
|
|
6196
|
+
}
|
|
6197
|
+
}
|
|
6134
6198
|
/**
|
|
6135
6199
|
* Destroy the snapshot Hls instance and clean up resources.
|
|
6136
6200
|
*/
|
|
@@ -6414,36 +6478,35 @@ var EBPlayerBundle = (function (exports) {
|
|
|
6414
6478
|
else {
|
|
6415
6479
|
const win = window;
|
|
6416
6480
|
if (win.Hls) {
|
|
6417
|
-
//
|
|
6418
|
-
|
|
6419
|
-
|
|
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
|
-
}
|
|
6481
|
+
// Share the main engine's token manager with the snapshot handler
|
|
6482
|
+
// to avoid duplicate token requests (one CDNTokenManager per player instance)
|
|
6483
|
+
const sharedTokenManager = engine.getTokenManager();
|
|
6428
6484
|
// Build DRM config (emeEnabled, drmSystems, licenseXhrSetup) for the snapshot hls.js instance
|
|
6429
|
-
const snapshotDrmConfigurator = new DrmConfigurator(
|
|
6485
|
+
const snapshotDrmConfigurator = new DrmConfigurator(sharedTokenManager);
|
|
6430
6486
|
const snapshotDrmConfig = snapshotDrmConfigurator.buildHlsConfig(mergedConfig.engineSettings);
|
|
6431
|
-
const handler = new HlsSnapshotHandler({ src, engineSettings: { ...mergedConfig.engineSettings, ...snapshotDrmConfig } },
|
|
6432
|
-
|
|
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
|
-
})
|
|
6487
|
+
const handler = new HlsSnapshotHandler({ src, engineSettings: { ...mergedConfig.engineSettings, ...snapshotDrmConfig } }, sharedTokenManager);
|
|
6488
|
+
handler.init(win.Hls)
|
|
6441
6489
|
.then(() => {
|
|
6442
6490
|
activeSnapshotDestroy = () => handler.destroy();
|
|
6443
6491
|
const snapshotVideo = handler.getVideo();
|
|
6444
6492
|
if (snapshotVideo !== null) {
|
|
6445
6493
|
controller.bus.emit('snapshot-handler-ready', { take: (time) => handler.take(time), video: snapshotVideo });
|
|
6446
6494
|
}
|
|
6495
|
+
// Stop/start snapshot manifest refreshes on pause/play to prevent
|
|
6496
|
+
// CDN token generate calls while the player is paused (live streams only).
|
|
6497
|
+
// Mirrors the same logic in hls.ts for the main engine.
|
|
6498
|
+
if (video) {
|
|
6499
|
+
video.addEventListener('pause', () => {
|
|
6500
|
+
if (controller.state?.isLive) {
|
|
6501
|
+
handler.stopLoad();
|
|
6502
|
+
}
|
|
6503
|
+
}, { signal: controller.signal });
|
|
6504
|
+
video.addEventListener('play', () => {
|
|
6505
|
+
if (controller.state?.isLive) {
|
|
6506
|
+
setTimeout(() => handler.startLoad(), 0);
|
|
6507
|
+
}
|
|
6508
|
+
}, { signal: controller.signal });
|
|
6509
|
+
}
|
|
6447
6510
|
})
|
|
6448
6511
|
.catch((error) => {
|
|
6449
6512
|
console.warn('EBPlayer: HlsSnapshotHandler init failed:', error);
|
|
@@ -6494,9 +6557,22 @@ var EBPlayerBundle = (function (exports) {
|
|
|
6494
6557
|
}, 100);
|
|
6495
6558
|
});
|
|
6496
6559
|
// Auto-open the stream if src is provided in config (matches legacy player behaviour
|
|
6497
|
-
// where consumers call start({ src: '...' }) and expect playback to begin immediately)
|
|
6560
|
+
// where consumers call start({ src: '...' }) and expect playback to begin immediately).
|
|
6561
|
+
// When autoplay is false, defer open() until the user requests play — this avoids
|
|
6562
|
+
// fetching CDN tokens and loading manifests before playback is actually needed.
|
|
6498
6563
|
if (mergedConfig.src) {
|
|
6499
|
-
|
|
6564
|
+
if (mergedConfig.autoplay) {
|
|
6565
|
+
reference.open(mergedConfig.src);
|
|
6566
|
+
}
|
|
6567
|
+
else {
|
|
6568
|
+
let deferredOpen = true;
|
|
6569
|
+
controller.bus.on('play', () => {
|
|
6570
|
+
if (deferredOpen) {
|
|
6571
|
+
deferredOpen = false;
|
|
6572
|
+
reference.open(mergedConfig.src);
|
|
6573
|
+
}
|
|
6574
|
+
}, { signal: controller.signal });
|
|
6575
|
+
}
|
|
6500
6576
|
}
|
|
6501
6577
|
return reference;
|
|
6502
6578
|
}
|
|
@@ -6538,7 +6614,7 @@ var EBPlayerBundle = (function (exports) {
|
|
|
6538
6614
|
window.EBPlayer = { start: start$1, stop, destroy, AVAILABLE_THEMES, THEME_LAYOUTS, version: VERSION };
|
|
6539
6615
|
}
|
|
6540
6616
|
|
|
6541
|
-
var brandConfig = {"
|
|
6617
|
+
var brandConfig = {"start":true,"autoplay":true,"muted":true,"statsOrigin":"easybroadcast.fr","prerollLink":false,"socialMediaList":{"facebook":"https://www.facebook.com/sharer/sharer.php?u=https://www.easybroadcast.fr","twitter":"https://twitter.com/Easy_Broadcast","pinterest":"http://pinterest.com/pin/create/link/?url=https://www.easybroadcast.fr","blogger":"https://www.blogger.com/blog_this.pyra?t&u=https://www.easybroadcast.fr","tumblr":"http://www.tumblr.com/share/link?url=https://www.easybroadcast.fr","reddit":"http://reddit.com/submit?url=https://www.easybroadcast.fr"},"srcInTokenRequest":true,"manager":"wss://manager.kube.easybroadcast.fr/easybroadcast/Lyf4JVGAmWJpTyN","src":"https://cdn.live.easybroadcast.io/abr_corp/73_aloula_w1dqfwm/playlist_dvr.m3u8","token":"https://token.easybroadcast.io/all","tokenType":"easy_b","lib":"https://libs.easybroadcast.io/assets/js/eblib/hls1/latest/eblib.bundle.js","aboutText":"\n\n <img src=\"https://www.easybroadcast.fr/img/logo_blue.svg\" width=\"40px\"/>\n <p> Copyright 2019 EasyBroadcast </p>\n \n\n <a style=\"color:white\" href=\"http://www.easybroadcast.fr\" target=\"_blank\">\n easybroadcast.fr\n </a>\n ","template":"/Volumes/Dev-ext/dev/players/web/player-master/configs/videos/easybroadcast/demo-token/index.ejs","content":"_99999"};
|
|
6542
6618
|
|
|
6543
6619
|
/**
|
|
6544
6620
|
* Standalone entry point — used for the generated player bundle (not the npm UMD build).
|