bigscreen-player 10.15.5 → 10.17.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.
@@ -1,5 +1,5 @@
1
1
  import { fromXML, generateISD, renderHTML } from 'smp-imsc';
2
- import { U as Utils, a as DebugTool, P as Plugins, D as DOMHelpers } from './main-b8ed400c.js';
2
+ import { U as Utils, a as DebugTool, P as Plugins, D as DOMHelpers } from './main-e3834c42.js';
3
3
  import 'tslib';
4
4
 
5
5
  function EmbeddedSubtitles(mediaPlayer, parentElement, { autoStart = false, defaultStyleOpts = {} } = {}) {
@@ -1,5 +1,5 @@
1
1
  import { fromXML, generateISD, renderHTML } from 'smp-imsc';
2
- import { f as findSegmentTemplate, L as LoadUrl, a as DebugTool, P as Plugins, U as Utils, D as DOMHelpers } from './main-b8ed400c.js';
2
+ import { f as findSegmentTemplate, L as LoadUrl, a as DebugTool, P as Plugins, U as Utils, D as DOMHelpers } from './main-e3834c42.js';
3
3
  import 'tslib';
4
4
 
5
5
  const SEGMENTS_BUFFER_SIZE = 3;
@@ -1,4 +1,4 @@
1
- import { D as DOMHelpers, a as DebugTool, P as Plugins, L as LoadUrl, T as TransportControlPosition } from './main-b8ed400c.js';
1
+ import { D as DOMHelpers, a as DebugTool, P as Plugins, L as LoadUrl, T as TransportControlPosition } from './main-e3834c42.js';
2
2
  import 'tslib';
3
3
 
4
4
  /**
@@ -799,7 +799,7 @@ function createDebugTool() {
799
799
  toggleVisibility,
800
800
  };
801
801
  }
802
- const DebugTool = createDebugTool();
802
+ const DebugTool$1 = createDebugTool();
803
803
 
804
804
  const ManifestType = {
805
805
  STATIC: "static",
@@ -979,7 +979,7 @@ function LegacyPlayerAdapter(mediaSources, playbackElement, isUHD, player) {
979
979
  if (Object.prototype.hasOwnProperty.call(handleEvent, event.type)) {
980
980
  handleEvent[event.type].call(this, event);
981
981
  } else {
982
- DebugTool.info(`${getSelection()} Event:${event.type}`);
982
+ DebugTool$1.info(`${getSelection()} Event:${event.type}`);
983
983
  }
984
984
  }
985
985
 
@@ -1005,7 +1005,7 @@ function LegacyPlayerAdapter(mediaSources, playbackElement, isUHD, player) {
1005
1005
  }
1006
1006
 
1007
1007
  function onTimeUpdate(event) {
1008
- DebugTool.updateElementTime(event.currentTime);
1008
+ DebugTool$1.updateElementTime(event.currentTime);
1009
1009
 
1010
1010
  isPaused = false;
1011
1011
 
@@ -1772,7 +1772,7 @@ function Cehtml() {
1772
1772
  const clampedTime = getClampedTime(seconds);
1773
1773
 
1774
1774
  if (clampedTime !== seconds) {
1775
- DebugTool.info(
1775
+ DebugTool$1.info(
1776
1776
  "playFrom " +
1777
1777
  seconds +
1778
1778
  " clamped to " +
@@ -1814,7 +1814,7 @@ function Cehtml() {
1814
1814
  }
1815
1815
 
1816
1816
  function reportError(errorMessage) {
1817
- DebugTool.info(errorMessage);
1817
+ DebugTool$1.info(errorMessage);
1818
1818
  emitEvent(MediaPlayerBase.EVENT.ERROR, { errorMessage: errorMessage });
1819
1819
  }
1820
1820
 
@@ -2312,7 +2312,7 @@ function Html5() {
2312
2312
  }
2313
2313
 
2314
2314
  function reportError(errorString, mediaError) {
2315
- DebugTool.info("HTML5 Media Player error: " + errorString);
2315
+ DebugTool$1.info("HTML5 Media Player error: " + errorString);
2316
2316
  emitEvent(MediaPlayerBase.EVENT.ERROR, mediaError);
2317
2317
  }
2318
2318
 
@@ -3260,7 +3260,7 @@ function SamsungMaple() {
3260
3260
  const clampedTime = getClampedTime(seconds);
3261
3261
 
3262
3262
  if (clampedTime !== seconds) {
3263
- DebugTool.info(
3263
+ DebugTool$1.info(
3264
3264
  "playFrom " +
3265
3265
  seconds +
3266
3266
  " clamped to " +
@@ -3396,7 +3396,7 @@ function SamsungMaple() {
3396
3396
  }
3397
3397
 
3398
3398
  function _reportError(errorMessage) {
3399
- DebugTool.info(errorMessage);
3399
+ DebugTool$1.info(errorMessage);
3400
3400
  _emitEvent(MediaPlayerBase.EVENT.ERROR, { errorMessage: errorMessage });
3401
3401
  }
3402
3402
 
@@ -4062,7 +4062,7 @@ function SamsungStreaming() {
4062
4062
  const clampedTime = _getClampedTime(seconds);
4063
4063
 
4064
4064
  if (clampedTime !== seconds) {
4065
- DebugTool.info(
4065
+ DebugTool$1.info(
4066
4066
  "playFrom " +
4067
4067
  seconds +
4068
4068
  " clamped to " +
@@ -4246,7 +4246,7 @@ function SamsungStreaming() {
4246
4246
  }
4247
4247
 
4248
4248
  function _reportError(errorMessage) {
4249
- DebugTool.info(errorMessage);
4249
+ DebugTool$1.info(errorMessage);
4250
4250
  _emitEvent(MediaPlayerBase.EVENT.ERROR, { errorMessage: errorMessage });
4251
4251
  }
4252
4252
 
@@ -4851,7 +4851,7 @@ function SamsungStreaming2015() {
4851
4851
  const clampedTime = _getClampedTime(seconds);
4852
4852
 
4853
4853
  if (clampedTime !== seconds) {
4854
- DebugTool.info(
4854
+ DebugTool$1.info(
4855
4855
  "playFrom " +
4856
4856
  seconds +
4857
4857
  " clamped to " +
@@ -5034,7 +5034,7 @@ function SamsungStreaming2015() {
5034
5034
  }
5035
5035
 
5036
5036
  function _reportError(errorMessage) {
5037
- DebugTool.info(errorMessage);
5037
+ DebugTool$1.info(errorMessage);
5038
5038
  _emitEvent(MediaPlayerBase.EVENT.ERROR, { errorMessage: errorMessage });
5039
5039
  }
5040
5040
 
@@ -5197,7 +5197,7 @@ function autoResumeAtStartOfRange(currentTime, seekableRange, addEventCallback,
5197
5197
  const duration = end - start;
5198
5198
  const windowLengthInSeconds = timeShiftBufferDepthInSeconds && duration < timeShiftBufferDepthInSeconds ? timeShiftBufferDepthInSeconds : duration;
5199
5199
  const resumeTimeOut = Math.max(0, windowLengthInSeconds - (end - currentTime) - AUTO_RESUME_WINDOW_START_CUSHION_SECONDS);
5200
- DebugTool.dynamicMetric("auto-resume", resumeTimeOut);
5200
+ DebugTool$1.dynamicMetric("auto-resume", resumeTimeOut);
5201
5201
  const autoResumeTimer = setTimeout(() => {
5202
5202
  removeEventCallback(undefined, detectIfUnpaused);
5203
5203
  resume();
@@ -5530,7 +5530,7 @@ function BasicStrategy(mediaSources, mediaKind, playbackElement) {
5530
5530
  }
5531
5531
 
5532
5532
  function onTimeUpdate() {
5533
- DebugTool.updateElementTime(mediaElement.currentTime);
5533
+ DebugTool$1.updateElementTime(mediaElement.currentTime);
5534
5534
 
5535
5535
  publishTimeUpdate();
5536
5536
  }
@@ -5710,7 +5710,7 @@ BasicStrategy.getLiveSupport = () => LiveSupport.SEEKABLE;
5710
5710
  function StrategyPicker() {
5711
5711
  return new Promise((resolve, reject) => {
5712
5712
  if (window.bigscreenPlayer.playbackStrategy === PlaybackStrategy.MSE) {
5713
- return import('./msestrategy-65b9aef1.js')
5713
+ return import('./msestrategy-57d05400.js')
5714
5714
  .then(({ default: MSEStrategy }) => resolve(MSEStrategy))
5715
5715
  .catch((reason) => {
5716
5716
  const error = new Error(isError(reason) ? reason.message : undefined);
@@ -5967,6 +5967,7 @@ function CallCallbacks(callbacks, data) {
5967
5967
  }
5968
5968
 
5969
5969
  let plugins = [];
5970
+ const pluginContext = {};
5970
5971
 
5971
5972
  function callOnAllPlugins(funcKey, evt) {
5972
5973
  const clonedEvent = Utils.deepClone(evt);
@@ -5978,8 +5979,37 @@ function callOnAllPlugins(funcKey, evt) {
5978
5979
  }
5979
5980
 
5980
5981
  var Plugins = {
5982
+ /**
5983
+ * @param {function (*): *} updater - a function which accepts the current context, and returns a new context
5984
+ */
5985
+ updateContext: (updater) => {
5986
+ const newContext = updater(Utils.deepClone(pluginContext));
5987
+
5988
+ if (typeof newContext !== "object") {
5989
+ throw new TypeError("context must be an object")
5990
+ }
5991
+
5992
+ // update object (preserving reference)
5993
+ for (const prop of Object.keys(pluginContext)) {
5994
+ delete pluginContext[prop];
5995
+ }
5996
+
5997
+ Object.assign(pluginContext, newContext);
5998
+
5999
+ // call context update handlers
6000
+ for (const plugin of plugins) {
6001
+ plugin.onContextUpdated?.(pluginContext);
6002
+ }
6003
+ },
6004
+
6005
+ /**
6006
+ * @param {*} plugin - an object
6007
+ */
5981
6008
  registerPlugin: (plugin) => {
5982
6009
  plugins.push(plugin);
6010
+
6011
+ // provide initial context
6012
+ plugin.onContextUpdated?.(pluginContext);
5983
6013
  },
5984
6014
 
5985
6015
  unregisterPlugin: (plugin) => {
@@ -6005,8 +6035,9 @@ var Plugins = {
6005
6035
  onPlayerInfoUpdated: (evt) => callOnAllPlugins("onPlayerInfoUpdated", evt),
6006
6036
  onManifestLoaded: (manifest) => callOnAllPlugins("onManifestLoaded", manifest),
6007
6037
  onManifestParseError: (evt) => callOnAllPlugins("onManifestParseError", evt),
6038
+ onDownloadQualityChange: (evt) => callOnAllPlugins("onDownloadQualityChange", evt),
6008
6039
  onQualityChangeRequested: (evt) => callOnAllPlugins("onQualityChangeRequested", evt),
6009
- onQualityChangedRendered: (evt) => callOnAllPlugins("onQualityChangedRendered", evt),
6040
+ onQualityChangeRendered: (evt) => callOnAllPlugins("onQualityChangeRendered", evt),
6010
6041
  onSubtitlesLoadError: (evt) => callOnAllPlugins("onSubtitlesLoadError", evt),
6011
6042
  onSubtitlesTimeout: (evt) => callOnAllPlugins("onSubtitlesTimeout", evt),
6012
6043
  onSubtitlesXMLError: (evt) => callOnAllPlugins("onSubtitlesXMLError", evt),
@@ -6015,6 +6046,7 @@ var Plugins = {
6015
6046
  onSubtitlesDynamicLoadError: (evt) => callOnAllPlugins("onSubtitlesDynamicLoadError", evt),
6016
6047
  onFragmentContentLengthMismatch: (evt) => callOnAllPlugins("onFragmentContentLengthMismatch", evt),
6017
6048
  onQuotaExceeded: (evt) => callOnAllPlugins("onQuotaExceeded", evt),
6049
+ onPlaybackQualityChange: (evt) => callOnAllPlugins("onPlaybackQualityChange", evt),
6018
6050
  onPlaybackRateChanged: (evt) => callOnAllPlugins("onPlaybackRateChanged", evt),
6019
6051
  onPlaybackFrozen: (evt) => callOnAllPlugins("onPlaybackFrozen", evt),
6020
6052
  },
@@ -6347,6 +6379,9 @@ function PlayerComponent(
6347
6379
  });
6348
6380
  }
6349
6381
 
6382
+ // Not an ideal place for this, but I've been warned of a possible playercomponent rewrite
6383
+ Plugins.updateContext((context) => ({ ...context, attemptCdnFailover }));
6384
+
6350
6385
  function clearFatalErrorTimeout() {
6351
6386
  if (fatalErrorTimeout !== null) {
6352
6387
  clearTimeout(fatalErrorTimeout);
@@ -6444,10 +6479,10 @@ function PlayerComponent(
6444
6479
 
6445
6480
  if (mediaSources.isAudioDescribedEnabled()) {
6446
6481
  audioDescribedCallback(true);
6447
- DebugTool.info("Source changed. Audio Described on.");
6482
+ DebugTool$1.info("Source changed. Audio Described on.");
6448
6483
  } else if (mediaSources.isAudioDescribedAvailable()) {
6449
6484
  audioDescribedCallback(false);
6450
- DebugTool.info("Source changed. Audio Described off.");
6485
+ DebugTool$1.info("Source changed. Audio Described off.");
6451
6486
  }
6452
6487
  }
6453
6488
 
@@ -6509,7 +6544,7 @@ const PauseTriggers = {
6509
6544
  DEVICE: 3,
6510
6545
  };
6511
6546
 
6512
- var Version = "10.15.5";
6547
+ var Version = "10.17.0";
6513
6548
 
6514
6549
  /* eslint-disable no-use-before-define */
6515
6550
 
@@ -7174,7 +7209,7 @@ function parse({ body, type }) {
7174
7209
  }
7175
7210
  })
7176
7211
  .catch((error) => {
7177
- DebugTool.error(error);
7212
+ DebugTool$1.error(error);
7178
7213
  Plugins.interface.onManifestParseError({ code: error.code, message: error.message });
7179
7214
  return {
7180
7215
  manifestType: ManifestType.STATIC,
@@ -7433,7 +7468,7 @@ function MediaSources() {
7433
7468
  function isFailoverInfoValid(failoverParams) {
7434
7469
  const infoValid = typeof failoverParams === "object" && typeof failoverParams.isBufferingTimeoutError === "boolean";
7435
7470
  if (!infoValid) {
7436
- DebugTool.error("failoverInfo is not valid");
7471
+ DebugTool$1.error("failoverInfo is not valid");
7437
7472
  }
7438
7473
  return infoValid;
7439
7474
  }
@@ -7463,10 +7498,10 @@ function MediaSources() {
7463
7498
  .then(({ time: newTime, transferFormat: newTransferFormat }) => {
7464
7499
  time = newTime;
7465
7500
  transferFormat = newTransferFormat;
7466
- DebugTool.sourceLoaded(Object.assign(Object.assign({}, time), { transferFormat }));
7501
+ DebugTool$1.sourceLoaded(Object.assign(Object.assign({}, time), { transferFormat }));
7467
7502
  })
7468
7503
  .catch((reason) => {
7469
- DebugTool.error(`Failed to load manifest: ${isError(reason) ? reason.message : "cause n/a"}`);
7504
+ DebugTool$1.error(`Failed to load manifest: ${isError(reason) ? reason.message : "cause n/a"}`);
7470
7505
  return failover({
7471
7506
  isBufferingTimeoutError: false,
7472
7507
  code: PluginEnums.ERROR_CODES.MANIFEST_LOAD,
@@ -7513,7 +7548,7 @@ function MediaSources() {
7513
7548
  const failoverResetToken = setTimeout(() => {
7514
7549
  if (mediaSource == null || sources[currentSources].length === 0)
7515
7550
  return;
7516
- DebugTool.info(`${mediaSource.cdn} has been added back in to available CDNs`);
7551
+ DebugTool$1.info(`${mediaSource.cdn} has been added back in to available CDNs`);
7517
7552
  sources[currentSources].push(mediaSource);
7518
7553
  updateDebugOutput();
7519
7554
  }, failoverResetTimeMs);
@@ -7562,10 +7597,10 @@ function MediaSources() {
7562
7597
  return subtitlesSources.map((subtitleSource) => subtitleSource.cdn);
7563
7598
  }
7564
7599
  function updateDebugOutput() {
7565
- DebugTool.dynamicMetric("cdns-available", availableCdns());
7566
- DebugTool.dynamicMetric("current-url", stripQueryParamsAndHash(getCurrentUrl()));
7567
- DebugTool.dynamicMetric("subtitle-cdns-available", availableSubtitlesCdns());
7568
- DebugTool.dynamicMetric("subtitle-current-url", stripQueryParamsAndHash(getCurrentSubtitlesUrl()));
7600
+ DebugTool$1.dynamicMetric("cdns-available", availableCdns());
7601
+ DebugTool$1.dynamicMetric("current-url", stripQueryParamsAndHash(getCurrentUrl()));
7602
+ DebugTool$1.dynamicMetric("subtitle-cdns-available", availableSubtitlesCdns());
7603
+ DebugTool$1.dynamicMetric("subtitle-current-url", stripQueryParamsAndHash(getCurrentSubtitlesUrl()));
7569
7604
  }
7570
7605
  function tearDown() {
7571
7606
  failoverResetTokens.forEach((token) => clearTimeout(token));
@@ -7701,7 +7736,7 @@ function Subtitles(
7701
7736
 
7702
7737
  if (available()) {
7703
7738
  if (useLegacySubs) {
7704
- import('./legacysubtitles-df133753.js')
7739
+ import('./legacysubtitles-77573f88.js')
7705
7740
  .then(({ default: LegacySubtitles }) => {
7706
7741
  subtitlesContainer = LegacySubtitles(mediaPlayer, playbackElement, mediaSources, {
7707
7742
  alwaysOnTop,
@@ -7715,7 +7750,7 @@ function Subtitles(
7715
7750
  Plugins.interface.onSubtitlesDynamicLoadError();
7716
7751
  });
7717
7752
  } else if (embeddedSubs) {
7718
- import('./embeddedsubtitles-a9a29366.js')
7753
+ import('./embeddedsubtitles-d03e3c93.js')
7719
7754
  .then(({ default: EmbeddedSubtitles }) => {
7720
7755
  subtitlesContainer = EmbeddedSubtitles(mediaPlayer, playbackElement, {
7721
7756
  autoStart,
@@ -7728,7 +7763,7 @@ function Subtitles(
7728
7763
  Plugins.interface.onSubtitlesDynamicLoadError();
7729
7764
  });
7730
7765
  } else {
7731
- import('./imscsubtitles-33e1c869.js')
7766
+ import('./imscsubtitles-2ecda44e.js')
7732
7767
  .then(({ default: IMSCSubtitles }) => {
7733
7768
  subtitlesContainer = IMSCSubtitles(mediaPlayer, playbackElement, mediaSources, {
7734
7769
  alwaysOnTop,
@@ -7815,6 +7850,16 @@ function Subtitles(
7815
7850
  subtitlesContainer?.tearDown();
7816
7851
  }
7817
7852
 
7853
+ function attemptSubtitleCdnFailover(opts) {
7854
+ hide();
7855
+ mediaSources
7856
+ .failoverSubtitles(opts)
7857
+ .then(() => show())
7858
+ .catch(() => DebugTool.info("No more CDNs available for subtitle failover"));
7859
+ }
7860
+
7861
+ Plugins.updateContext((context) => ({ ...context, attemptSubtitleCdnFailover }));
7862
+
7818
7863
  return {
7819
7864
  enable,
7820
7865
  disable,
@@ -7922,7 +7967,7 @@ function BigscreenPlayer() {
7922
7967
  }
7923
7968
 
7924
7969
  stateObject.endOfStream = endOfStream;
7925
- DebugTool.statechange(evt.data.state);
7970
+ DebugTool$1.statechange(evt.data.state);
7926
7971
 
7927
7972
  CallCallbacks(_callbacks.stateChange, stateObject);
7928
7973
  }
@@ -7932,11 +7977,11 @@ function BigscreenPlayer() {
7932
7977
  typeof evt.data.seekableRange.start === "number" &&
7933
7978
  typeof evt.data.seekableRange.end === "number"
7934
7979
  ) {
7935
- DebugTool.staticMetric("seekable-range", [evt.data.seekableRange.start, evt.data.seekableRange.end]);
7980
+ DebugTool$1.staticMetric("seekable-range", [evt.data.seekableRange.start, evt.data.seekableRange.end]);
7936
7981
  }
7937
7982
 
7938
7983
  if (evt.data.duration) {
7939
- DebugTool.staticMetric("duration", evt.data.duration);
7984
+ DebugTool$1.staticMetric("duration", evt.data.duration);
7940
7985
  }
7941
7986
 
7942
7987
  if (playerComponent && readyHelper) {
@@ -8060,7 +8105,7 @@ function BigscreenPlayer() {
8060
8105
 
8061
8106
  function toggleDebug() {
8062
8107
  if (playerComponent) {
8063
- DebugTool.toggleVisibility();
8108
+ DebugTool$1.toggleVisibility();
8064
8109
  }
8065
8110
  }
8066
8111
 
@@ -8108,8 +8153,8 @@ function BigscreenPlayer() {
8108
8153
  */
8109
8154
  init: (newPlaybackElement, bigscreenPlayerData, callbacks = {}) => {
8110
8155
  playbackElement = newPlaybackElement;
8111
- DebugTool.init();
8112
- DebugTool.setRootElement(playbackElement);
8156
+ DebugTool$1.init();
8157
+ DebugTool$1.setRootElement(playbackElement);
8113
8158
  resizer = Resizer();
8114
8159
 
8115
8160
  mediaKind = bigscreenPlayerData.media.kind;
@@ -8118,15 +8163,15 @@ function BigscreenPlayer() {
8118
8163
  initialPlaybackTime = createPlaybackTime(bigscreenPlayerData.initialPlaybackTime);
8119
8164
  }
8120
8165
 
8121
- DebugTool.staticMetric("version", Version);
8166
+ DebugTool$1.staticMetric("version", Version);
8122
8167
 
8123
8168
  if (initialPlaybackTime) {
8124
8169
  const { seconds, timeline } = initialPlaybackTime;
8125
- DebugTool.staticMetric("initial-playback-time", [seconds, timeline]);
8170
+ DebugTool$1.staticMetric("initial-playback-time", [seconds, timeline]);
8126
8171
  }
8127
8172
 
8128
8173
  if (typeof window.bigscreenPlayer?.playbackStrategy === "string") {
8129
- DebugTool.staticMetric("strategy", window.bigscreenPlayer && window.bigscreenPlayer.playbackStrategy);
8174
+ DebugTool$1.staticMetric("strategy", window.bigscreenPlayer && window.bigscreenPlayer.playbackStrategy);
8130
8175
  }
8131
8176
 
8132
8177
  _callbacks.playerReady = callbacks.onSuccess;
@@ -8142,6 +8187,8 @@ function BigscreenPlayer() {
8142
8187
  callbacks.onError(reason);
8143
8188
  }
8144
8189
  });
8190
+
8191
+ Plugins.updateContext((context) => ({ ...context, mediaSources }));
8145
8192
  },
8146
8193
 
8147
8194
  /**
@@ -8176,7 +8223,7 @@ function BigscreenPlayer() {
8176
8223
  pauseTrigger = undefined;
8177
8224
  resizer = undefined;
8178
8225
  this.unregisterPlugin();
8179
- DebugTool.tearDown();
8226
+ DebugTool$1.tearDown();
8180
8227
  },
8181
8228
 
8182
8229
  /**
@@ -8277,7 +8324,7 @@ function BigscreenPlayer() {
8277
8324
  setCurrentTime(seconds, timeline) {
8278
8325
  const playbackTime = createPlaybackTime({ seconds, timeline });
8279
8326
 
8280
- DebugTool.apicall("setCurrentTime", [playbackTime.seconds.toFixed(3), playbackTime.timeline]);
8327
+ DebugTool$1.apicall("setCurrentTime", [playbackTime.seconds.toFixed(3), playbackTime.timeline]);
8281
8328
 
8282
8329
  if (playerComponent) {
8283
8330
  // this flag must be set before calling into playerComponent.setCurrentTime - as this synchronously fires a WAITING event (when native strategy).
@@ -8386,7 +8433,7 @@ function BigscreenPlayer() {
8386
8433
  * @function
8387
8434
  */
8388
8435
  play: () => {
8389
- DebugTool.apicall("play");
8436
+ DebugTool$1.apicall("play");
8390
8437
 
8391
8438
  playerComponent.play();
8392
8439
  },
@@ -8397,7 +8444,7 @@ function BigscreenPlayer() {
8397
8444
  * @param {boolean} opts.userPause
8398
8445
  */
8399
8446
  pause: (opts) => {
8400
- DebugTool.apicall("pause");
8447
+ DebugTool$1.apicall("pause");
8401
8448
 
8402
8449
  pauseTrigger = opts?.userPause || opts?.userPause == null ? PauseTriggers.USER : PauseTriggers.APP;
8403
8450
 
@@ -8572,7 +8619,7 @@ function BigscreenPlayer() {
8572
8619
  },
8573
8620
 
8574
8621
  /**
8575
- * Register a plugin for extended events.
8622
+ * Register a plugin for extended events & custom functionality.
8576
8623
  * @function
8577
8624
  * @param {*} plugin
8578
8625
  */
@@ -8614,14 +8661,14 @@ function BigscreenPlayer() {
8614
8661
  * @function
8615
8662
  * @return {Object} - Key value pairs of available log levels
8616
8663
  */
8617
- getLogLevels: () => DebugTool.logLevels,
8664
+ getLogLevels: () => DebugTool$1.logLevels,
8618
8665
 
8619
8666
  /**
8620
8667
  * @function
8621
8668
  * @param logLevel - log level to display @see getLogLevels
8622
8669
  */
8623
- setLogLevel: (level) => DebugTool.setLogLevel(level),
8624
- getDebugLogs: () => DebugTool.getDebugLogs(),
8670
+ setLogLevel: (level) => DebugTool$1.setLogLevel(level),
8671
+ getDebugLogs: () => DebugTool$1.getDebugLogs(),
8625
8672
  convertPresentationTimeToMediaSampleTimeInSeconds,
8626
8673
  convertMediaSampleTimeToPresentationTimeInSeconds,
8627
8674
  convertPresentationTimeToAvailabilityTimeInMilliseconds,
@@ -8672,4 +8719,4 @@ const WindowTypes = {
8672
8719
  SLIDING: "slidingWindow",
8673
8720
  };
8674
8721
 
8675
- export { BigscreenPlayer as B, DOMHelpers as D, EntryCategory as E, LoadUrl as L, MediaKinds as M, Plugins as P, TransportControlPosition as T, Utils as U, WindowTypes as W, DebugTool as a, LiveSupport as b, ManifestType as c, MediaState as d, autoResumeAtStartOfRange as e, findSegmentTemplate as f, MockBigscreenPlayer as g, PauseTriggers as h, PlaybackStrategy as i, TransferFormat as j, Timeline as k, isMessage as l, isMetric as m, isTrace as n };
8722
+ export { BigscreenPlayer as B, DOMHelpers as D, EntryCategory as E, LoadUrl as L, MediaKinds as M, Plugins as P, TransportControlPosition as T, Utils as U, WindowTypes as W, DebugTool$1 as a, LiveSupport as b, ManifestType as c, MediaState as d, autoResumeAtStartOfRange as e, findSegmentTemplate as f, MockBigscreenPlayer as g, PauseTriggers as h, PlaybackStrategy as i, TransferFormat as j, Timeline as k, isMessage as l, isMetric as m, isTrace as n };
@@ -262,7 +262,7 @@ declare function BigscreenPlayer(): {
262
262
  */
263
263
  mockJasmine(opts: any): void;
264
264
  /**
265
- * Register a plugin for extended events.
265
+ * Register a plugin for extended events & custom functionality.
266
266
  * @function
267
267
  * @param {*} plugin
268
268
  */
package/dist/esm/main.js CHANGED
@@ -1,2 +1,2 @@
1
- export { B as BigscreenPlayer, a as DebugTool, E as EntryCategory, b as LiveSupport, c as ManifestType, M as MediaKinds, d as MediaState, g as MockBigscreenPlayer, h as PauseTriggers, i as PlaybackStrategy, k as Timeline, j as TransferFormat, T as TransportControlPosition, W as WindowTypes, l as isMessage, m as isMetric, n as isTrace } from './main-b8ed400c.js';
1
+ export { B as BigscreenPlayer, a as DebugTool, E as EntryCategory, b as LiveSupport, c as ManifestType, M as MediaKinds, d as MediaState, g as MockBigscreenPlayer, h as PauseTriggers, i as PlaybackStrategy, k as Timeline, j as TransferFormat, T as TransportControlPosition, W as WindowTypes, l as isMessage, m as isMetric, n as isTrace } from './main-e3834c42.js';
2
2
  import 'tslib';
@@ -1,5 +1,5 @@
1
1
  import { MediaPlayer } from 'dashjs/index';
2
- import { U as Utils, M as MediaKinds, b as LiveSupport, a as DebugTool, c as ManifestType, P as Plugins, d as MediaState, e as autoResumeAtStartOfRange, D as DOMHelpers } from './main-b8ed400c.js';
2
+ import { U as Utils, M as MediaKinds, b as LiveSupport, a as DebugTool, c as ManifestType, P as Plugins, d as MediaState, e as autoResumeAtStartOfRange, D as DOMHelpers } from './main-e3834c42.js';
3
3
  import 'tslib';
4
4
 
5
5
  function filter(manifest, representationOptions) {
@@ -119,6 +119,31 @@ function convertTimeRangesToArray(ranges) {
119
119
  return array;
120
120
  }
121
121
 
122
+ function setPropertyPath(target, path, value) {
123
+ if (target == null || (typeof target !== "object" && typeof target !== "function")) {
124
+ throw new TypeError(`Target must be an object. (got ${target})`);
125
+ }
126
+ const keysDesc = typeof path === "string" ? path.split(".") : path;
127
+ if (keysDesc.length === 0) {
128
+ throw new TypeError("Empty path provided. (got [])");
129
+ }
130
+ const key = keysDesc.shift();
131
+ if (key == null) {
132
+ throw new TypeError(`Cannot index object with key. (got key '${key}')`);
133
+ }
134
+ if (keysDesc.length === 0) {
135
+ target[key] = value;
136
+ return;
137
+ }
138
+ let next = target[key];
139
+ if (next != null && typeof next !== "object" && typeof next !== "function") {
140
+ throw new TypeError(`Cannot assign to primitive value. (got '${next}')`);
141
+ }
142
+ next !== null && next !== void 0 ? next : (next = {});
143
+ target[key] = next;
144
+ setPropertyPath(next, keysDesc, value);
145
+ }
146
+
122
147
  const DEFAULT_SETTINGS = {
123
148
  liveDelay: 0,
124
149
  seekDurationPadding: 1.1,
@@ -193,6 +218,10 @@ function MSEStrategy(
193
218
  [MediaKinds.AUDIO]: undefined,
194
219
  [MediaKinds.VIDEO]: undefined,
195
220
  },
221
+ playbackQuality: {
222
+ [MediaKinds.AUDIO]: undefined,
223
+ [MediaKinds.VIDEO]: undefined,
224
+ },
196
225
  playbackBitrate: undefined,
197
226
  bufferLength: undefined,
198
227
  latency: undefined,
@@ -438,6 +467,8 @@ function MSEStrategy(
438
467
  mediaPlayer.setMediaDuration(Number.MAX_SAFE_INTEGER);
439
468
  }
440
469
 
470
+ DebugTool.info("Stream initialised");
471
+
441
472
  if (mediaPlayer.getActiveStream()?.getHasVideoTrack()) {
442
473
  dispatchDownloadQualityChangeForKind(MediaKinds.VIDEO);
443
474
  dispatchMaxQualityChangeForKind(MediaKinds.VIDEO);
@@ -486,6 +517,43 @@ function MSEStrategy(
486
517
  const switchToPart = ` to ${qualityIndex} (${(bitrateInBps / 1000).toFixed(0)} kbps)`;
487
518
 
488
519
  DebugTool.info(`${abrChangePart}${switchFromPart}${switchToPart}`);
520
+
521
+ Plugins.interface.onDownloadQualityChange({
522
+ type: "downloadqualitychange",
523
+ detail: {
524
+ mediaType: kind,
525
+ currentBitrateInBps: bitrateInBps,
526
+ currentQualityIndex: qualityIndex,
527
+ previousBitrateInBps: prevBitrateInBps,
528
+ previousQualityIndex: prevQualityIndex,
529
+ },
530
+ });
531
+ }
532
+
533
+ function dispatchPlaybackQualityChangeForKind(kind, { qualityIndex } = {}) {
534
+ const { qualityIndex: previousQualityIndex, bitrateInBps: previousBitrateInBps } =
535
+ playerMetadata.playbackQuality[kind] ?? {};
536
+
537
+ if (previousQualityIndex === qualityIndex) {
538
+ return
539
+ }
540
+
541
+ const bitrateInBps = playbackBitrateForRepresentationIndex(qualityIndex, kind);
542
+
543
+ playerMetadata.playbackQuality[kind] = { bitrateInBps, qualityIndex };
544
+
545
+ DebugTool.dynamicMetric(`${kind}-playback-quality`, [qualityIndex, bitrateInBps]);
546
+
547
+ Plugins.interface.onPlaybackQualityChange({
548
+ type: "playbackqualitychange",
549
+ detail: {
550
+ mediaType: kind,
551
+ previousBitrateInBps,
552
+ previousQualityIndex,
553
+ currentBitrateInBps: bitrateInBps,
554
+ currentQualityIndex: qualityIndex,
555
+ },
556
+ });
489
557
  }
490
558
 
491
559
  function dispatchMaxQualityChangeForKind(kind) {
@@ -536,23 +604,16 @@ function MSEStrategy(
536
604
  }
537
605
 
538
606
  function onQualityChangeRendered(event) {
539
- if (
540
- event.newQuality !== undefined &&
541
- (event.mediaType === MediaKinds.AUDIO || event.mediaType === MediaKinds.VIDEO)
542
- ) {
543
- const { mediaType, newQuality } = event;
544
-
545
- DebugTool.dynamicMetric(`${mediaType}-playback-quality`, [
546
- newQuality,
547
- playbackBitrateForRepresentationIndex(newQuality, mediaType),
548
- ]);
607
+ const { mediaType, newQuality } = event;
549
608
 
609
+ if (newQuality !== undefined && (mediaType === MediaKinds.AUDIO || mediaType === MediaKinds.VIDEO)) {
610
+ dispatchPlaybackQualityChangeForKind(mediaType, { qualityIndex: newQuality });
550
611
  dispatchMaxQualityChangeForKind(mediaType);
551
612
  }
552
613
 
553
614
  emitPlayerInfo();
554
615
 
555
- Plugins.interface.onQualityChangedRendered(event);
616
+ Plugins.interface.onQualityChangeRendered(event);
556
617
  }
557
618
 
558
619
  /**
@@ -1129,17 +1190,22 @@ function MSEStrategy(
1129
1190
  * Set constrained audio or video bitrate
1130
1191
  */
1131
1192
  function setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps) {
1193
+ if (mediaKind !== MediaKinds.AUDIO && mediaKind !== MediaKinds.VIDEO) {
1194
+ throw new TypeError(`Bitrate constraint not supported for this media kind. (got ${mediaKind})`)
1195
+ }
1196
+
1197
+ if (mediaPlayer == null) {
1198
+ setPropertyPath(playerSettings, ["streaming", "abr", "minBitrate", mediaKind], minBitrateKbps);
1199
+ setPropertyPath(playerSettings, ["streaming", "abr", "maxBitrate", mediaKind], maxBitrateKbps);
1200
+
1201
+ return
1202
+ }
1203
+
1132
1204
  mediaPlayer.updateSettings({
1133
1205
  streaming: {
1134
1206
  abr: {
1135
- minBitrate: {
1136
- audio: mediaKind === MediaKinds.AUDIO ? minBitratKbps : -1,
1137
- video: mediaKind === MediaKinds.VIDEO ? minBitrateKbps : -1,
1138
- },
1139
- maxBitrate: {
1140
- audio: mediaKind === MediaKinds.AUDIO ? maxBitrateKbps : -1,
1141
- video: mediaKind === MediaKinds.VIDEO ? maxBitrateKbps : -1,
1142
- },
1207
+ minBitrate: { [mediaKind]: minBitrateKbps },
1208
+ maxBitrate: { [mediaKind]: maxBitrateKbps },
1143
1209
  },
1144
1210
  },
1145
1211
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigscreen-player",
3
- "version": "10.15.5",
3
+ "version": "10.17.0",
4
4
  "type": "module",
5
5
  "description": "Simplified media playback for bigscreen devices.",
6
6
  "main": "dist/esm/main.js",