eb-player 2.0.7 → 2.0.9

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.
@@ -1,7 +1,7 @@
1
1
  var EBPlayerBundle = (function (exports) {
2
2
  'use strict';
3
3
 
4
- var __EB_PLAYER_VERSION__ = "2.0.6";
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.
@@ -5160,6 +5169,14 @@ var EBPlayerBundle = (function (exports) {
5160
5169
  getDriver() {
5161
5170
  return this.driver;
5162
5171
  }
5172
+ /**
5173
+ * Returns the CDN token manager used by this engine.
5174
+ * Allows the snapshot handler to share the same manager (avoids duplicate token requests).
5175
+ * Returns null when no token URL is configured or before init().
5176
+ */
5177
+ getTokenManager() {
5178
+ return this.tokenManager;
5179
+ }
5163
5180
  // -------------------------------------------------------------------------
5164
5181
  // BaseEngine hooks
5165
5182
  // -------------------------------------------------------------------------
@@ -5275,7 +5292,9 @@ var EBPlayerBundle = (function (exports) {
5275
5292
  if (!hlsjsUrl) {
5276
5293
  throw new Error('HlsEngine: config.hlsjs URL is required');
5277
5294
  }
5278
- // Create token manager if a token URL is configured
5295
+ // Create token manager if a token URL is configured.
5296
+ // No initial fetchToken() here — updateUrlWithTokenParams() below handles it
5297
+ // and populates lastTokenResponse (used lazily by DRM licenseXhrSetup).
5279
5298
  if (config.token) {
5280
5299
  this.tokenManager = new CDNTokenManager({
5281
5300
  token: config.token,
@@ -5284,13 +5303,6 @@ var EBPlayerBundle = (function (exports) {
5284
5303
  extraParamsCallback: (config.engineSettings.extraParamsCallback ?? config.extraParamsCallback),
5285
5304
  onCDNTokenError: config.engineSettings.onCDNTokenError
5286
5305
  });
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
5306
  }
5295
5307
  // console.info('HlsEngine: loading hls.js from', hlsjsUrl)
5296
5308
  const Hls = await loadScript(hlsjsUrl, 'Hls');
@@ -5373,7 +5385,6 @@ var EBPlayerBundle = (function (exports) {
5373
5385
  // Create the driver (NEVER stored in state)
5374
5386
  const driver = new Hls(driverConfig);
5375
5387
  this.driver = driver;
5376
- this.resolveDriverReady();
5377
5388
  // Pitfall 4: apply discontinuity workaround BEFORE attachMedia/loadSource
5378
5389
  applyDiscontinuityWorkaround(driver, Hls.Events);
5379
5390
  // Wire retry handler
@@ -5396,8 +5407,27 @@ var EBPlayerBundle = (function (exports) {
5396
5407
  }
5397
5408
  }
5398
5409
  driver.loadSource(src);
5410
+ // Resolve driverReady AFTER loadSource so consumers (P2P, snapshot handler)
5411
+ // don't start making token requests before the main engine's initial token
5412
+ // fetch completes and populates the cache.
5413
+ this.resolveDriverReady();
5399
5414
  // Register driver event handlers
5400
5415
  this.registerDriverEvents(Hls, state);
5416
+ // Pause/resume loading on video pause/play to stop manifest refreshes
5417
+ // (and thus CDN token requests) while the player is paused.
5418
+ // Only applies to live streams where hls.js continuously refreshes the manifest.
5419
+ const driverRef = driver;
5420
+ video.addEventListener('pause', () => {
5421
+ if (this.state?.isLive) {
5422
+ driverRef.stopLoad();
5423
+ }
5424
+ }, { signal });
5425
+ video.addEventListener('play', () => {
5426
+ if (this.state?.isLive) {
5427
+ // Defer startLoad to avoid re-entrancy (Pitfall 3)
5428
+ setTimeout(() => driverRef.startLoad(-1), 0);
5429
+ }
5430
+ }, { signal });
5401
5431
  // Start stall watchdog
5402
5432
  this.startWatchdog();
5403
5433
  }
@@ -6414,30 +6444,14 @@ var EBPlayerBundle = (function (exports) {
6414
6444
  else {
6415
6445
  const win = window;
6416
6446
  if (win.Hls) {
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
- }
6447
+ // Share the main engine's token manager with the snapshot handler
6448
+ // to avoid duplicate token requests (one CDNTokenManager per player instance)
6449
+ const sharedTokenManager = engine.getTokenManager();
6428
6450
  // Build DRM config (emeEnabled, drmSystems, licenseXhrSetup) for the snapshot hls.js instance
6429
- const snapshotDrmConfigurator = new DrmConfigurator(snapshotTokenManager);
6451
+ const snapshotDrmConfigurator = new DrmConfigurator(sharedTokenManager);
6430
6452
  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
- })
6453
+ const handler = new HlsSnapshotHandler({ src, engineSettings: { ...mergedConfig.engineSettings, ...snapshotDrmConfig } }, sharedTokenManager);
6454
+ handler.init(win.Hls)
6441
6455
  .then(() => {
6442
6456
  activeSnapshotDestroy = () => handler.destroy();
6443
6457
  const snapshotVideo = handler.getVideo();
@@ -6494,9 +6508,22 @@ var EBPlayerBundle = (function (exports) {
6494
6508
  }, 100);
6495
6509
  });
6496
6510
  // 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)
6511
+ // where consumers call start({ src: '...' }) and expect playback to begin immediately).
6512
+ // When autoplay is false, defer open() until the user requests play — this avoids
6513
+ // fetching CDN tokens and loading manifests before playback is actually needed.
6498
6514
  if (mergedConfig.src) {
6499
- reference.open(mergedConfig.src);
6515
+ if (mergedConfig.autoplay) {
6516
+ reference.open(mergedConfig.src);
6517
+ }
6518
+ else {
6519
+ let deferredOpen = true;
6520
+ controller.bus.on('play', () => {
6521
+ if (deferredOpen) {
6522
+ deferredOpen = false;
6523
+ reference.open(mergedConfig.src);
6524
+ }
6525
+ }, { signal: controller.signal });
6526
+ }
6500
6527
  }
6501
6528
  return reference;
6502
6529
  }