bigscreen-player 7.1.5 → 7.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.
@@ -1,16 +1,19 @@
1
+ /**
2
+ * Provides an enumeration of possible media states.
3
+ */
1
4
  const MediaState = {
2
- /** Media is stopped and is not attempting to start. */
3
- STOPPED: 0,
4
- /** Media is paused. */
5
- PAUSED: 1,
6
- /** Media is playing successfully. */
7
- PLAYING: 2,
8
- /** Media is waiting for data (buffering). */
9
- WAITING: 4,
10
- /** Media has ended. */
11
- ENDED: 5,
12
- /** Media has thrown a fatal error. */
13
- FATAL_ERROR: 6,
5
+ /** Media is stopped and is not attempting to start. */
6
+ STOPPED: 0,
7
+ /** Media is paused. */
8
+ PAUSED: 1,
9
+ /** Media is playing successfully. */
10
+ PLAYING: 2,
11
+ /** Media is waiting for data (buffering). */
12
+ WAITING: 4,
13
+ /** Media has ended. */
14
+ ENDED: 5,
15
+ /** Media has thrown a fatal error. */
16
+ FATAL_ERROR: 6,
14
17
  };
15
18
 
16
19
  /**
@@ -19,12 +22,12 @@ const MediaState = {
19
22
  * @enum {string}
20
23
  */
21
24
  const WindowTypes = {
22
- /** Media with a duration */
23
- STATIC: "staticWindow",
24
- /** Media with a start time but without a duration until an indeterminate time in the future */
25
- GROWING: "growingWindow",
26
- /** Media with a rewind window that progresses through a media timeline */
27
- SLIDING: "slidingWindow",
25
+ /** Media with a duration */
26
+ STATIC: "staticWindow",
27
+ /** Media with a start time but without a duration until an indeterminate time in the future */
28
+ GROWING: "growingWindow",
29
+ /** Media with a rewind window that progresses through a media timeline */
30
+ SLIDING: "slidingWindow",
28
31
  };
29
32
 
30
33
  function PluginData(args) {
@@ -224,9 +227,9 @@ let plugins = [];
224
227
  function callOnAllPlugins(funcKey, evt) {
225
228
  const clonedEvent = Utils.deepClone(evt);
226
229
 
227
- for (const i in plugins) {
228
- if (plugins[i][funcKey]) {
229
- plugins[i][funcKey](clonedEvent);
230
+ for (const plugin in plugins) {
231
+ if (plugins[plugin][funcKey]) {
232
+ plugins[plugin][funcKey](clonedEvent);
230
233
  }
231
234
  }
232
235
  }
@@ -240,9 +243,9 @@ var Plugins = {
240
243
  if (!plugin && plugins.length > 0) {
241
244
  plugins = [];
242
245
  } else {
243
- for (let i = plugins.length - 1; i >= 0; i--) {
244
- if (plugins[i] === plugin) {
245
- plugins.splice(i, 1);
246
+ for (let index = plugins.length - 1; index >= 0; index--) {
247
+ if (plugins[index] === plugin) {
248
+ plugins.splice(index, 1);
246
249
  }
247
250
  }
248
251
  }
@@ -266,25 +269,26 @@ var Plugins = {
266
269
  onSubtitlesTransformError: (evt) => callOnAllPlugins("onSubtitlesTransformError", evt),
267
270
  onSubtitlesRenderError: (evt) => callOnAllPlugins("onSubtitlesRenderError", evt),
268
271
  onSubtitlesDynamicLoadError: (evt) => callOnAllPlugins("onSubtitlesDynamicLoadError", evt),
272
+ onQuotaExceeded: (evt) => callOnAllPlugins("onQuotaExceeded", evt),
269
273
  },
270
274
  };
271
275
 
272
276
  const TransferFormat = {
273
- DASH: "dash",
274
- HLS: "hls",
277
+ DASH: "dash",
278
+ HLS: "hls",
275
279
  };
276
280
 
277
281
  const LiveSupport = {
278
- NONE: "none",
279
- PLAYABLE: "playable",
280
- RESTARTABLE: "restartable",
281
- SEEKABLE: "seekable",
282
+ NONE: "none",
283
+ PLAYABLE: "playable",
284
+ RESTARTABLE: "restartable",
285
+ SEEKABLE: "seekable",
282
286
  };
283
287
 
284
288
  const PlaybackStrategy = {
285
- MSE: "msestrategy",
286
- NATIVE: "nativestrategy",
287
- BASIC: "basicstrategy",
289
+ MSE: "msestrategy",
290
+ NATIVE: "nativestrategy",
291
+ BASIC: "basicstrategy",
288
292
  };
289
293
 
290
294
  function AllowedMediaTransitions(mediaplayer) {
@@ -334,543 +338,674 @@ function AllowedMediaTransitions(mediaplayer) {
334
338
  }
335
339
  }
336
340
 
337
- const updateCallbacks = [];
338
- let chronicle = [];
339
- let firstTimeElement, compressTime;
340
-
341
- const TYPES = {
342
- APICALL: "apicall",
343
- ERROR: "error",
344
- EVENT: "event",
345
- INFO: "info",
346
- KEYVALUE: "keyvalue",
347
- TIME: "time",
348
- WARNING: "warning",
349
- };
350
-
351
- function init$2() {
352
- clear();
353
- }
354
-
355
- function clear() {
356
- firstTimeElement = true;
357
- compressTime = false;
358
- chronicle = [];
359
- }
360
-
361
- function registerForUpdates(callback) {
362
- updateCallbacks.push(callback);
363
- }
364
-
365
- function unregisterForUpdates(callback) {
366
- const indexOf = updateCallbacks.indexOf(callback);
367
-
368
- if (indexOf !== -1) {
369
- updateCallbacks.splice(indexOf, 1);
370
- }
371
- }
372
-
373
- function info(message) {
374
- pushToChronicle({ type: TYPES.INFO, message });
375
- }
376
-
377
- /** @param {Error} err */
378
- function error(err) {
379
- pushToChronicle({ type: TYPES.ERROR, error: err });
380
- }
381
-
382
- function warn(warning) {
383
- pushToChronicle({ type: TYPES.WARNING, warning });
384
- }
385
-
386
- function event(event) {
387
- pushToChronicle({ type: TYPES.EVENT, event });
388
- }
389
-
390
- function apicall(callType) {
391
- pushToChronicle({ type: TYPES.APICALL, calltype: callType });
392
- }
393
-
394
- function time(time) {
395
- if (firstTimeElement) {
396
- pushToChronicle({ type: TYPES.TIME, currentTime: time });
397
- firstTimeElement = false;
398
- } else if (!compressTime) {
399
- pushToChronicle({ type: TYPES.TIME, currentTime: time });
400
- compressTime = true;
401
- } else {
402
- const lastElement = chronicle.pop();
403
-
404
- lastElement.currentTime = time;
405
- pushToChronicle(lastElement);
406
- }
407
- }
408
-
409
- function keyValue(obj) {
410
- pushToChronicle({ type: TYPES.KEYVALUE, keyvalue: obj });
411
- }
412
-
413
- function retrieve() {
414
- return [...chronicle]
415
- }
416
-
417
- function timestamp(obj) {
418
- obj.timestamp = Date.now();
419
- }
420
-
421
- function pushToChronicle(obj) {
422
- if (obj.type !== TYPES.TIME) {
423
- firstTimeElement = true;
424
- compressTime = false;
425
- }
426
-
427
- timestamp(obj);
428
- chronicle.push(obj);
429
- updates();
430
- }
431
-
432
- function updates() {
433
- updateCallbacks.forEach((callback) => callback(retrieve()));
434
- }
435
-
436
- function tearDown$1() {
437
- clear();
341
+ function getValues(obj) {
342
+ const values = [];
343
+ for (const key in obj) {
344
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) {
345
+ continue;
346
+ }
347
+ values.push(obj[key]);
348
+ }
349
+ return values;
438
350
  }
439
351
 
440
- var Chronicle = {
441
- TYPES,
442
- init: init$2,
443
- clear,
444
- tearDown: tearDown$1,
445
- apicall,
446
- error,
447
- event,
448
- info,
449
- keyValue,
450
- time,
451
- warn,
452
- verbose: info,
453
- retrieve,
454
- registerForUpdates,
455
- unregisterForUpdates,
456
- };
457
-
458
- let view;
459
-
460
- function init$1(newView) {
461
- view = newView;
352
+ var EntryCategory;
353
+ (function (EntryCategory) {
354
+ EntryCategory["METRIC"] = "metric";
355
+ EntryCategory["MESSAGE"] = "message";
356
+ EntryCategory["TRACE"] = "trace";
357
+ })(EntryCategory || (EntryCategory = {}));
358
+ const isMessage = (entry) => entry.category === EntryCategory.MESSAGE;
359
+ const isMetric = (entry) => entry.category === EntryCategory.METRIC;
360
+ const isTrace = (entry) => entry.category === EntryCategory.TRACE;
361
+ function isValid(data) {
362
+ const type = typeof data;
363
+ return (type === "boolean" ||
364
+ type === "number" ||
365
+ type === "string" ||
366
+ (type === "object" && Array.isArray(data) && data.every((element) => isValid(element))));
462
367
  }
463
-
464
- function update(logs) {
465
- view.render({ static: parseStaticFields(logs), dynamic: parseDynamicFields(logs) });
368
+ function isEqual(left, right) {
369
+ if (Array.isArray(left) && Array.isArray(right)) {
370
+ return left.length === right.length && left.every((element, index) => isEqual(element, right[index]));
371
+ }
372
+ return left === right;
466
373
  }
467
-
468
- function isStaticLog(log) {
469
- return log.type === Chronicle.TYPES.KEYVALUE
374
+ function sortEntries(someEntry, otherEntry) {
375
+ return someEntry.sessionTime === otherEntry.sessionTime
376
+ ? someEntry.currentElementTime - otherEntry.currentElementTime
377
+ : someEntry.sessionTime - otherEntry.sessionTime;
470
378
  }
471
-
472
- function parseStaticFields(logs) {
473
- const latestStaticFields = [];
474
- const staticFields = logs.filter((log) => isStaticLog(log));
475
-
476
- const uniqueKeys = findUniqueKeys(staticFields);
477
- uniqueKeys.forEach((key) => {
478
- const matchingStaticLogs = staticFields.filter((log) => log.keyvalue.key === key);
479
-
480
- latestStaticFields.push(matchingStaticLogs.pop());
481
- });
482
-
483
- return latestStaticFields.map((field) => ({
484
- key: sanitiseKeyString(field.keyvalue.key),
485
- value: sanitiseValueString(field.keyvalue.value),
486
- }))
379
+ function concatArrays(someArray, otherArray) {
380
+ return [...someArray, ...otherArray];
487
381
  }
488
-
489
- function parseByType(log) {
490
- const dateString = new Date(log.timestamp).toISOString();
491
-
492
- switch (log.type) {
493
- case Chronicle.TYPES.INFO: {
494
- return `${dateString} - Info: ${log.message}`
495
- }
496
- case Chronicle.TYPES.TIME: {
497
- return `${dateString} - Video time: ${parseFloat(log.currentTime).toFixed(2)}`
382
+ const METRIC_ENTRY_THRESHOLD = 100;
383
+ class Chronicle {
384
+ constructor() {
385
+ this.sessionStartTime = Date.now();
386
+ this.currentElementTime = 0;
387
+ this.messages = [];
388
+ this.metrics = {};
389
+ this.traces = [];
390
+ this.listeners = { update: [], timeupdate: [] };
391
+ }
392
+ triggerUpdate(entry) {
393
+ this.listeners.update.forEach((callback) => callback(entry));
394
+ }
395
+ triggerTimeUpdate(seconds) {
396
+ this.listeners.timeupdate.forEach((callback) => callback(seconds));
397
+ }
398
+ timestamp(entry) {
399
+ return Object.assign(Object.assign({}, entry), { currentElementTime: this.currentElementTime, sessionTime: this.getSessionTime() });
400
+ }
401
+ pushMessage(message) {
402
+ const entry = this.timestamp(message);
403
+ this.messages.push(entry);
404
+ this.triggerUpdate(entry);
405
+ }
406
+ getCurrentElementTime() {
407
+ return this.currentElementTime;
408
+ }
409
+ setCurrentElementTime(seconds) {
410
+ this.currentElementTime = seconds;
411
+ this.triggerTimeUpdate(seconds);
412
+ }
413
+ getSessionTime() {
414
+ return Date.now() - this.sessionStartTime;
415
+ }
416
+ on(type, listener) {
417
+ this.listeners[type].push(listener);
418
+ }
419
+ off(type, listener) {
420
+ const index = this.listeners[type].indexOf(listener);
421
+ if (index === -1) {
422
+ return;
423
+ }
424
+ this.listeners[type].splice(index, 1);
498
425
  }
499
- case Chronicle.TYPES.EVENT: {
500
- return `${dateString} - Event: ${convertToReadableEvent(log.event.state)}`
426
+ retrieve() {
427
+ const metrics = getValues(this.metrics).reduce(concatArrays, []);
428
+ return [...this.traces, ...metrics, ...this.messages].sort(sortEntries);
501
429
  }
502
- case Chronicle.TYPES.ERROR: {
503
- return `${dateString} - ${log.error.name ?? "Error"}: ${log.error.message}`
430
+ size() {
431
+ return (this.messages.length +
432
+ this.traces.length +
433
+ getValues(this.metrics).reduce((sumSoFar, metricsForKey) => sumSoFar + metricsForKey.length, 0));
504
434
  }
505
- case Chronicle.TYPES.APICALL: {
506
- return `${dateString} - Api call: ${log.calltype}`
435
+ appendMetric(kind, data) {
436
+ if (!isValid(data)) {
437
+ throw new TypeError(`A metric value can only be a primitive type, or an array of any depth containing primitive types. Got ${typeof data}`);
438
+ }
439
+ const latest = this.getLatestMetric(kind);
440
+ if (latest && isEqual(latest.data, data)) {
441
+ return;
442
+ }
443
+ if (this.metrics[kind] == null) {
444
+ this.metrics[kind] = [];
445
+ }
446
+ const metricsForKey = this.metrics[kind];
447
+ if (metricsForKey.length + 1 === METRIC_ENTRY_THRESHOLD) {
448
+ this.trace("error", new Error(`Metric ${kind} exceeded ${METRIC_ENTRY_THRESHOLD}. Consider a more selective sample, or not storing history.`));
449
+ }
450
+ const metric = this.timestamp({ kind, data, category: EntryCategory.METRIC });
451
+ metricsForKey.push(metric);
452
+ this.triggerUpdate(metric);
453
+ }
454
+ setMetric(kind, data) {
455
+ this.metrics[kind] = [];
456
+ this.appendMetric(kind, data);
457
+ }
458
+ getLatestMetric(kind) {
459
+ var _a;
460
+ if (!((_a = this.metrics[kind]) === null || _a === void 0 ? void 0 : _a.length)) {
461
+ return null;
462
+ }
463
+ const metricsForKey = this.metrics[kind];
464
+ return metricsForKey[metricsForKey.length - 1];
507
465
  }
508
- case Chronicle.TYPES.WARNING: {
509
- return `${dateString} - Warning: ${log.warning}`
466
+ debug(message) {
467
+ this.pushMessage({ category: EntryCategory.MESSAGE, kind: "debug", data: message });
510
468
  }
511
- default: {
512
- return `${dateString} - Unknown log format`
469
+ info(message) {
470
+ this.pushMessage({ category: EntryCategory.MESSAGE, kind: "info", data: message });
513
471
  }
514
- }
515
- }
516
-
517
- function parseDynamicFields(logs) {
518
- return logs.filter((log) => !isStaticLog(log)).map((log) => parseByType(log))
519
- }
520
-
521
- function findUniqueKeys(logs) {
522
- const uniqueKeys = [];
523
-
524
- logs.forEach((log) => {
525
- if (uniqueKeys.indexOf(log.keyvalue.key) === -1) {
526
- uniqueKeys.push(log.keyvalue.key);
472
+ trace(kind, data) {
473
+ const entry = this.timestamp({ kind, data, category: EntryCategory.TRACE });
474
+ this.traces.push(entry);
475
+ this.triggerUpdate(entry);
527
476
  }
528
- });
529
-
530
- return uniqueKeys
531
- }
532
-
533
- function sanitiseKeyString(key) {
534
- return key.replace(/([A-Z])/g, " $1").toLowerCase()
535
- }
536
-
537
- function sanitiseValueString(value) {
538
- if (value instanceof Date) {
539
- const hours = zeroPadTimeUnits(value.getHours()) + value.getHours();
540
- const mins = zeroPadTimeUnits(value.getMinutes()) + value.getMinutes();
541
- const secs = zeroPadTimeUnits(value.getSeconds()) + value.getSeconds();
542
-
543
- return `${hours}:${mins}:${secs}`
544
- }
545
-
546
- return value
547
- }
548
-
549
- function zeroPadTimeUnits(unit) {
550
- return unit < 10 ? "0" : ""
551
- }
552
-
553
- function convertToReadableEvent(type) {
554
- for (const key in MediaState) {
555
- if (MediaState[key] === type) {
556
- return key
477
+ warn(message) {
478
+ this.pushMessage({ category: EntryCategory.MESSAGE, kind: "warning", data: message });
557
479
  }
558
- }
559
-
560
- return type
561
480
  }
562
481
 
563
- var DebugPresenter = {
564
- init: init$1,
565
- update,
566
- };
567
-
568
482
  function addClass(el, className) {
569
- if (el.classList) {
570
- el.classList.add(className);
571
- } else {
572
- el.className += " " + className;
573
- }
483
+ if (el.classList) {
484
+ el.classList.add(className);
485
+ }
486
+ else {
487
+ el.className += ` ${className}`;
488
+ }
574
489
  }
575
-
576
490
  function removeClass(el, className) {
577
- if (el.classList) {
578
- el.classList.remove(className);
579
- } else {
580
- el.className = el.className.replace(new RegExp("(^|\\b)" + className.split(" ").join("|") + "(\\b|$)", "gi"), " ");
581
- }
491
+ if (el.classList) {
492
+ el.classList.remove(className);
493
+ }
494
+ else {
495
+ el.className = el.className.replace(new RegExp(`(^|\\b)${className.split(" ").join("|")}(\\b|$)`, "gi"), " ");
496
+ }
582
497
  }
583
-
584
498
  function hasClass(el, className) {
585
- if (el.classList) {
586
- return el.classList.contains(className)
587
- } else {
588
- return new RegExp("(^| )" + className + "( |$)", "gi").test(el.className)
589
- }
499
+ return el.classList ? el.classList.contains(className) : new RegExp(`(^| )${className}( |$)`, "gi").test(el.className);
590
500
  }
591
-
592
- function isRGBATuple(rgbaString) {
593
- return new RegExp("^#([A-Fa-f0-9]{8})$").test(rgbaString)
501
+ function isRGBA(rgbaString) {
502
+ return new RegExp("^#([A-Fa-f0-9]{8})$").test(rgbaString);
594
503
  }
595
-
596
504
  /**
597
505
  * Checks that the string is an RGBA tuple and returns a RGB Tripple.
598
506
  * A string that isn't an RGBA tuple will be returned to the caller.
599
- * @param {String} rgbaString
600
507
  */
601
508
  function rgbaToRGB(rgbaString) {
602
- if (isRGBATuple(rgbaString)) {
603
- rgbaString = rgbaString.slice(0, 7);
604
- }
605
- return rgbaString
509
+ return isRGBA(rgbaString) ? rgbaString.slice(0, 7) : rgbaString;
606
510
  }
607
-
608
511
  /**
609
512
  * Safely removes an element from the DOM, simply doing
610
513
  * nothing if the node is detached (Has no parent).
611
- * @param {Element} el The Element to remove
514
+ * @param el The Element to remove
612
515
  */
613
516
  function safeRemoveElement(el) {
614
- if (el.parentNode) {
615
- el.parentNode.removeChild(el);
616
- }
517
+ if (el && el.parentNode) {
518
+ el.parentNode.removeChild(el);
519
+ }
617
520
  }
618
-
619
521
  var DOMHelpers = {
620
- addClass: addClass,
621
- removeClass: removeClass,
622
- hasClass: hasClass,
623
- rgbaToRGB: rgbaToRGB,
624
- isRGBA: isRGBATuple,
625
- safeRemoveElement: safeRemoveElement,
522
+ addClass,
523
+ removeClass,
524
+ hasClass,
525
+ rgbaToRGB,
526
+ isRGBA,
527
+ safeRemoveElement,
626
528
  };
627
529
 
628
- let appElement, logBox, logContainer, staticContainer, staticBox;
629
-
530
+ let appElement;
531
+ let logBox;
532
+ let logContainer;
533
+ let staticContainer;
534
+ let staticBox;
630
535
  function init() {
631
- logBox = document.createElement("div");
632
- logContainer = document.createElement("span");
633
- staticBox = document.createElement("div");
634
- staticContainer = document.createElement("span");
635
-
636
- if (appElement === undefined) {
637
- appElement = document.body;
638
- }
639
-
640
- logBox.id = "logBox";
641
- logBox.style.position = "absolute";
642
- logBox.style.width = "63%";
643
- logBox.style.left = "5%";
644
- logBox.style.top = "15%";
645
- logBox.style.bottom = "25%";
646
- logBox.style.backgroundColor = "#1D1D1D";
647
- logBox.style.opacity = 0.9;
648
- logBox.style.overflow = "hidden";
649
-
650
- staticBox.id = "staticBox";
651
- staticBox.style.position = "absolute";
652
- staticBox.style.width = "30%";
653
- staticBox.style.right = "1%";
654
- staticBox.style.top = "15%";
655
- staticBox.style.bottom = "25%";
656
- staticBox.style.backgroundColor = "#1D1D1D";
657
- staticBox.style.opacity = 0.9;
658
- staticBox.style.overflow = "hidden";
659
-
660
- logContainer.id = "logContainer";
661
- logContainer.style.color = "#ffffff";
662
- logContainer.style.fontSize = "11pt";
663
- logContainer.style.position = "absolute";
664
- logContainer.style.bottom = "1%";
665
- logContainer.style.left = "1%";
666
- logContainer.style.wordWrap = "break-word";
667
- logContainer.style.whiteSpace = "pre-line";
668
-
669
- staticContainer.id = "staticContainer";
670
- staticContainer.style.color = "#ffffff";
671
- staticContainer.style.fontSize = "11pt";
672
- staticContainer.style.wordWrap = "break-word";
673
- staticContainer.style.left = "1%";
674
- staticContainer.style.whiteSpace = "pre-line";
675
-
676
- logBox.appendChild(logContainer);
677
- staticBox.appendChild(staticContainer);
678
- appElement.appendChild(logBox);
679
- appElement.appendChild(staticBox);
536
+ logBox = document.createElement("div");
537
+ logContainer = document.createElement("span");
538
+ staticBox = document.createElement("div");
539
+ staticContainer = document.createElement("span");
540
+ if (appElement === undefined) {
541
+ appElement = document.body;
542
+ }
543
+ logBox.id = "logBox";
544
+ logBox.style.position = "absolute";
545
+ logBox.style.width = "63%";
546
+ logBox.style.left = "5%";
547
+ logBox.style.top = "15%";
548
+ logBox.style.bottom = "25%";
549
+ logBox.style.backgroundColor = "#1D1D1D";
550
+ logBox.style.opacity = "0.9";
551
+ logBox.style.overflow = "hidden";
552
+ staticBox.id = "staticBox";
553
+ staticBox.style.position = "absolute";
554
+ staticBox.style.width = "30%";
555
+ staticBox.style.right = "1%";
556
+ staticBox.style.top = "15%";
557
+ staticBox.style.bottom = "25%";
558
+ staticBox.style.backgroundColor = "#1D1D1D";
559
+ staticBox.style.opacity = "0.9";
560
+ staticBox.style.overflow = "hidden";
561
+ logContainer.id = "logContainer";
562
+ logContainer.style.color = "#ffffff";
563
+ logContainer.style.fontSize = "11pt";
564
+ logContainer.style.position = "absolute";
565
+ logContainer.style.bottom = "1%";
566
+ logContainer.style.left = "1%";
567
+ logContainer.style.wordWrap = "break-word";
568
+ logContainer.style.whiteSpace = "pre-line";
569
+ staticContainer.id = "staticContainer";
570
+ staticContainer.style.color = "#ffffff";
571
+ staticContainer.style.fontSize = "11pt";
572
+ staticContainer.style.wordWrap = "break-word";
573
+ staticContainer.style.left = "1%";
574
+ staticContainer.style.whiteSpace = "pre-line";
575
+ logBox.appendChild(logContainer);
576
+ staticBox.appendChild(staticContainer);
577
+ appElement.appendChild(logBox);
578
+ appElement.appendChild(staticBox);
680
579
  }
681
-
682
580
  function setRootElement(root) {
683
- if (root) {
684
- appElement = root;
685
- }
581
+ if (root) {
582
+ appElement = root;
583
+ }
686
584
  }
687
-
688
- function render(logData) {
689
- const LINES_TO_DISPLAY = 29;
690
- let dynamicLogs = logData.dynamic;
691
-
692
- if (dynamicLogs.length === 0) {
693
- logContainer.textContent = "";
694
- }
695
-
696
- dynamicLogs = dynamicLogs.slice(-LINES_TO_DISPLAY);
697
- logContainer.textContent = dynamicLogs.join("\n");
698
-
699
- logData.static.forEach(updateStaticElements);
585
+ function renderDynamicLogs(dynamic) {
586
+ if (logContainer)
587
+ logContainer.textContent = dynamic.join("\n");
700
588
  }
701
-
702
- function updateStaticElements(log) {
703
- const existingElement = document.getElementById(log.key);
704
- const text = log.key + ": " + log.value;
705
-
706
- if (existingElement) {
707
- if (text !== existingElement.textContent) {
708
- existingElement.textContent = text;
709
- }
710
- } else {
711
- createNewStaticElement(log.key, log.value);
712
- }
589
+ function renderStaticLogs(staticLogs) {
590
+ staticLogs.forEach((entry) => renderStaticLog(entry));
713
591
  }
714
-
715
- function createNewStaticElement(key, value) {
716
- const staticLog = document.createElement("div");
717
-
718
- staticLog.id = key;
719
- staticLog.style.paddingBottom = "1%";
720
- staticLog.style.borderBottom = "1px solid white";
721
- staticLog.textContent = key + ": " + value;
722
-
723
- staticContainer.appendChild(staticLog);
592
+ function render({ dynamic: dynamicLogs, static: staticLogs }) {
593
+ renderDynamicLogs(dynamicLogs);
594
+ renderStaticLogs(staticLogs);
595
+ }
596
+ function renderStaticLog(entry) {
597
+ const { id, key, value } = entry;
598
+ const existingElement = document.querySelector(`#${id}`);
599
+ const text = `${key}: ${value}`;
600
+ if (existingElement == null) {
601
+ createNewStaticElement(entry);
602
+ return;
603
+ }
604
+ if (existingElement.textContent === text) {
605
+ return;
606
+ }
607
+ existingElement.textContent = text;
608
+ }
609
+ function createNewStaticElement({ id, key, value }) {
610
+ const staticLog = document.createElement("div");
611
+ staticLog.id = id;
612
+ staticLog.style.paddingBottom = "1%";
613
+ staticLog.style.borderBottom = "1px solid white";
614
+ staticLog.textContent = `${key}: ${value}`;
615
+ staticContainer === null || staticContainer === void 0 ? void 0 : staticContainer.appendChild(staticLog);
724
616
  }
725
-
726
617
  function tearDown() {
727
- DOMHelpers.safeRemoveElement(logBox);
728
- DOMHelpers.safeRemoveElement(staticBox);
729
-
730
- appElement = undefined;
731
- staticContainer = undefined;
732
- logContainer = undefined;
733
- logBox = undefined;
618
+ DOMHelpers.safeRemoveElement(logBox);
619
+ DOMHelpers.safeRemoveElement(staticBox);
620
+ appElement = undefined;
621
+ staticContainer = undefined;
622
+ logContainer = undefined;
623
+ logBox = undefined;
734
624
  }
735
-
736
625
  var DebugView = {
737
- init: init,
738
- setRootElement: setRootElement,
739
- render: render,
740
- tearDown: tearDown,
626
+ init,
627
+ setRootElement,
628
+ render,
629
+ tearDown,
741
630
  };
742
631
 
743
- function DebugTool() {
744
- const presenter = DebugPresenter;
632
+ const invertedMediaState = {
633
+ 0: "STOPPED",
634
+ 1: "PAUSED",
635
+ 2: "PLAYING",
636
+ 4: "WAITING",
637
+ 5: "ENDED",
638
+ 6: "FATAL_ERROR",
639
+ };
640
+ const DYNAMIC_ENTRY_LIMIT = 29;
641
+ function zeroPadHMS(time) {
642
+ return `${time < 10 ? "0" : ""}${time}`;
643
+ }
644
+ function zeroPadMs(milliseconds) {
645
+ return `${milliseconds < 100 ? "0" : ""}${milliseconds < 10 ? "0" : ""}${milliseconds}`;
646
+ }
647
+ function formatDate(value) {
648
+ const hours = value.getUTCHours();
649
+ const mins = value.getUTCMinutes();
650
+ const secs = value.getUTCSeconds();
651
+ return `${zeroPadHMS(hours)}:${zeroPadHMS(mins)}:${zeroPadHMS(secs)}`;
652
+ }
653
+ class DebugViewController {
654
+ constructor() {
655
+ this.isVisible = false;
656
+ this.shouldRender = false;
657
+ this.filters = [];
658
+ this.dynamicEntries = [];
659
+ this.latestMetricByKey = {};
660
+ }
661
+ isMerged(metric) {
662
+ const { kind } = metric;
663
+ const mediaStateMetrics = ["ended", "paused", "ready-state", "seeking"];
664
+ return mediaStateMetrics.includes(kind);
665
+ }
666
+ mergeMediaState(entry) {
667
+ const prevData = this.latestMetricByKey["media-element-state"] == null
668
+ ? {}
669
+ : this.latestMetricByKey["media-element-state"].data;
670
+ const { kind, data } = entry;
671
+ return Object.assign(Object.assign({}, entry), { category: "union", kind: "media-element-state", data: Object.assign(Object.assign({}, prevData), { [kind]: data }) });
672
+ }
673
+ cacheEntry(entry) {
674
+ const { category } = entry;
675
+ switch (category) {
676
+ case EntryCategory.METRIC:
677
+ return this.cacheStaticEntry(this.isMerged(entry) ? this.mergeMediaState(entry) : entry);
678
+ case EntryCategory.MESSAGE:
679
+ case EntryCategory.TRACE:
680
+ this.cacheDynamicEntry(entry);
681
+ if (this.dynamicEntries.length >= DYNAMIC_ENTRY_LIMIT) {
682
+ this.dynamicEntries = this.dynamicEntries.slice(-DYNAMIC_ENTRY_LIMIT);
683
+ }
684
+ break;
685
+ }
686
+ }
687
+ cacheStaticEntry(entry) {
688
+ var _a;
689
+ const latestSessionTimeSoFar = (_a = this.latestMetricByKey[entry.kind]) === null || _a === void 0 ? void 0 : _a.sessionTime;
690
+ if (typeof latestSessionTimeSoFar === "number" && latestSessionTimeSoFar > entry.sessionTime) {
691
+ return;
692
+ }
693
+ this.latestMetricByKey[entry.kind] = entry;
694
+ }
695
+ cacheDynamicEntry(entry) {
696
+ if (entry.category === "time") {
697
+ this.cacheTimestamp(entry);
698
+ return;
699
+ }
700
+ this.dynamicEntries.push(entry);
701
+ }
702
+ cacheTimestamp(entry) {
703
+ const lastDynamicEntry = this.dynamicEntries[this.dynamicEntries.length - 1];
704
+ if (lastDynamicEntry == null || lastDynamicEntry.category !== "time") {
705
+ this.dynamicEntries.push(entry);
706
+ return;
707
+ }
708
+ this.dynamicEntries[this.dynamicEntries.length - 1] = entry;
709
+ }
710
+ serialiseDynamicEntry(entry) {
711
+ let formattedData;
712
+ const { category } = entry;
713
+ switch (category) {
714
+ case EntryCategory.MESSAGE:
715
+ formattedData = this.serialiseMessage(entry);
716
+ break;
717
+ case "time":
718
+ formattedData = this.serialiseTime(entry);
719
+ break;
720
+ case EntryCategory.TRACE:
721
+ formattedData = this.serialiseTrace(entry);
722
+ break;
723
+ }
724
+ const sessionTime = new Date(entry.sessionTime);
725
+ const formatedSessionTime = `${formatDate(sessionTime)}.${zeroPadMs(sessionTime.getUTCMilliseconds())}`;
726
+ return `${formatedSessionTime} - ${formattedData}`;
727
+ }
728
+ serialiseMessage(message) {
729
+ const { kind, data } = message;
730
+ switch (kind) {
731
+ case "debug":
732
+ return `Debug: ${data}`;
733
+ case "info":
734
+ return `Info: ${data}`;
735
+ case "warning":
736
+ return `Warning: ${data}`;
737
+ }
738
+ }
739
+ serialiseTime(time) {
740
+ const { currentElementTime } = time;
741
+ return `Video time: ${currentElementTime.toFixed(2)}`;
742
+ }
743
+ serialiseTrace(trace) {
744
+ var _a;
745
+ const { currentElementTime, kind, data } = trace;
746
+ switch (kind) {
747
+ case "apicall": {
748
+ const { functionName, functionArgs } = data;
749
+ const argsPart = functionArgs.length === 0 ? "" : ` with args [${functionArgs.join(", ")}]`;
750
+ return `Called '${functionName}${argsPart}'`;
751
+ }
752
+ case "buffered-ranges": {
753
+ const buffered = data.buffered.map(([start, end]) => `${start.toFixed(2)} - ${end.toFixed(2)}`).join(", ");
754
+ return `Buffered ${data.kind}: [${buffered}] at current time ${currentElementTime.toFixed(2)}`;
755
+ }
756
+ case "error":
757
+ return `${(_a = data.name) !== null && _a !== void 0 ? _a : "Error"}: ${data.message}`;
758
+ case "event": {
759
+ const { eventType, eventTarget } = data;
760
+ return `Event: '${eventType}' from ${eventTarget}`;
761
+ }
762
+ case "gap": {
763
+ const { from, to } = data;
764
+ return `Gap from ${from} to ${to}`;
765
+ }
766
+ case "session-start":
767
+ return `Playback session started at ${new Date(data).toISOString().replace("T", " ")}`;
768
+ case "session-end":
769
+ return `Playback session ended at ${new Date(data).toISOString().replace("T", " ")}`;
770
+ case "quota-exceeded": {
771
+ const { bufferLevel, time } = data;
772
+ return `Quota exceeded with buffer level ${bufferLevel} at chunk start time ${time}`;
773
+ }
774
+ case "state-change":
775
+ return `Event: ${invertedMediaState[data]}`;
776
+ }
777
+ }
778
+ serialiseStaticEntry(entry) {
779
+ const { kind } = entry;
780
+ const parsedKey = kind.replace(/-/g, " ");
781
+ const parsedValue = this.serialiseMetric(entry);
782
+ return { id: kind, key: parsedKey, value: parsedValue };
783
+ }
784
+ serialiseMetric({ kind, data }) {
785
+ if (typeof data !== "object") {
786
+ return data;
787
+ }
788
+ if (kind === "media-element-state") {
789
+ const parts = [];
790
+ const isWaiting = typeof data["ready-state"] === "number" && data["ready-state"] <= 2;
791
+ if (!isWaiting && !data.paused && !data.seeking) {
792
+ parts.push("playing");
793
+ }
794
+ if (isWaiting) {
795
+ parts.push("waiting");
796
+ }
797
+ if (data.paused) {
798
+ parts.push("paused");
799
+ }
800
+ if (data.seeking) {
801
+ parts.push("seeking");
802
+ }
803
+ if (data.ended) {
804
+ parts.push("ended");
805
+ }
806
+ return parts.join(", ");
807
+ }
808
+ if (kind === "seekable-range") {
809
+ const [start, end] = data;
810
+ return `${formatDate(new Date(start))} - ${formatDate(new Date(end))}`;
811
+ }
812
+ if (kind === "representation-audio" || kind === "representation-video") {
813
+ const [qualityIndex, bitrate] = data;
814
+ return `${qualityIndex} (${bitrate} kbps)`;
815
+ }
816
+ return data.join(", ");
817
+ }
818
+ render() {
819
+ DebugView.render({
820
+ static: getValues(this.latestMetricByKey).map((entry) => this.serialiseStaticEntry(entry)),
821
+ dynamic: this.dynamicEntries.map((entry) => this.serialiseDynamicEntry(entry)),
822
+ });
823
+ }
824
+ setFilters(filters) {
825
+ this.filters = filters;
826
+ }
827
+ addTime({ currentElementTime, sessionTime }) {
828
+ this.cacheTimestamp({ currentElementTime, sessionTime, category: "time" });
829
+ this.shouldRender = true;
830
+ }
831
+ addEntries(entries) {
832
+ for (const entry of entries) {
833
+ if (!this.filters.every((filter) => filter(entry))) {
834
+ continue;
835
+ }
836
+ this.cacheEntry(entry);
837
+ }
838
+ this.shouldRender = true;
839
+ }
840
+ hideView() {
841
+ clearInterval(this.renderInterval);
842
+ DebugView.tearDown();
843
+ this.isVisible = false;
844
+ }
845
+ showView() {
846
+ DebugView.setRootElement(this.rootElement);
847
+ DebugView.init();
848
+ this.renderInterval = setInterval(() => {
849
+ if (this.shouldRender) {
850
+ this.render();
851
+ this.shouldRender = false;
852
+ }
853
+ }, 250);
854
+ this.isVisible = true;
855
+ }
856
+ setRootElement(el) {
857
+ DebugView.setRootElement(el);
858
+ }
859
+ }
745
860
 
746
- const LOG_LEVELS = {
861
+ const LogLevels = {
747
862
  ERROR: 0,
748
863
  WARN: 1,
749
864
  INFO: 2,
750
- VERBOSE: 3,
751
- };
752
-
753
- let visible = false;
754
- let logLevel = LOG_LEVELS.INFO;
755
- let staticFieldValues = {};
756
-
757
- let rootElement, view;
758
-
759
- function toggleVisibility() {
760
- if (visible) {
761
- hide();
762
- } else {
763
- show();
865
+ DEBUG: 3,
866
+ };
867
+ function shouldDisplayEntry(entry) {
868
+ return (!isTrace(entry) ||
869
+ entry.kind !== "event" ||
870
+ entry.data.eventTarget !== "MediaElement" ||
871
+ ["paused", "playing", "seeking", "seeked", "waiting"].includes(entry.data.eventType));
872
+ }
873
+ function DebugTool() {
874
+ let chronicle = new Chronicle();
875
+ let currentLogLevel = LogLevels.INFO;
876
+ let viewController = new DebugViewController();
877
+ function init() {
878
+ chronicle = new Chronicle();
879
+ viewController = new DebugViewController();
880
+ setLogLevel(LogLevels.INFO);
881
+ chronicle.trace("session-start", Date.now());
882
+ }
883
+ function tearDown() {
884
+ if (viewController.isVisible) {
885
+ hide();
886
+ }
887
+ chronicle.trace("session-end", Date.now());
764
888
  }
765
- }
766
-
767
- function setLogLevel(newLogLevel) {
768
- if (newLogLevel !== undefined) {
769
- logLevel = newLogLevel;
889
+ function getDebugLogs() {
890
+ return chronicle.retrieve();
770
891
  }
771
- }
772
-
773
- function show() {
774
- view = DebugView;
775
- view.setRootElement(rootElement);
776
- view.init();
777
- presenter.init(view);
778
- presenter.update(Chronicle.retrieve());
779
- Chronicle.registerForUpdates(presenter.update);
780
- visible = true;
781
- }
782
-
783
- function hide() {
784
- view.tearDown();
785
- Chronicle.unregisterForUpdates(presenter.update);
786
- visible = false;
787
- }
788
-
789
- function info(log) {
790
- if (logLevel >= LOG_LEVELS.INFO) {
791
- Chronicle.info(log);
892
+ function setLogLevel(newLogLevel) {
893
+ if (typeof newLogLevel !== "number") {
894
+ return;
895
+ }
896
+ if (newLogLevel === LogLevels.DEBUG) {
897
+ viewController.setFilters([]);
898
+ }
899
+ else {
900
+ viewController.setFilters([shouldDisplayEntry]);
901
+ }
902
+ currentLogLevel = newLogLevel;
792
903
  }
793
- }
794
-
795
- function event(log) {
796
- if (logLevel >= LOG_LEVELS.INFO) {
797
- Chronicle.event(log);
904
+ function setRootElement(element) {
905
+ viewController.setRootElement(element);
798
906
  }
799
- }
800
-
801
- function time(log) {
802
- if (logLevel >= LOG_LEVELS.INFO) {
803
- Chronicle.time(log);
907
+ function updateElementTime(seconds) {
908
+ chronicle.setCurrentElementTime(seconds);
804
909
  }
805
- }
806
-
807
- function error(log) {
808
- if (logLevel < LOG_LEVELS.ERROR) {
809
- return
910
+ function apicall(functionName, functionArgs = []) {
911
+ chronicle.trace("apicall", { functionName, functionArgs });
810
912
  }
811
-
812
- const error = typeof log === "object" && log.message ? log : new Error(log);
813
-
814
- Chronicle.error(error);
815
- }
816
-
817
- function warn(log) {
818
- if (logLevel < LOG_LEVELS.WARN) {
819
- return
913
+ function buffered(kind, buffered) {
914
+ chronicle.trace("buffered-ranges", { kind, buffered });
820
915
  }
821
-
822
- Chronicle.warn(log);
823
- }
824
-
825
- function verbose(log) {
826
- if (logLevel >= LOG_LEVELS.VERBOSE) {
827
- Chronicle.verbose(log);
916
+ function debug(...parts) {
917
+ if (currentLogLevel < LogLevels.DEBUG) {
918
+ return;
919
+ }
920
+ chronicle.debug(parts.join(" "));
828
921
  }
829
- }
830
-
831
- function updateKeyValue(message) {
832
- const staticFieldValue = staticFieldValues[message.key];
833
-
834
- if (staticFieldValue) {
835
- const entry = Chronicle.retrieve()[staticFieldValue.index];
836
-
837
- if (entry) {
838
- entry.keyvalue = message;
839
- }
840
- } else {
841
- staticFieldValues[message.key] = { value: message.value, index: Chronicle.retrieve().length };
842
- Chronicle.keyValue(message);
922
+ function error(...parts) {
923
+ if (currentLogLevel < LogLevels.ERROR) {
924
+ return;
925
+ }
926
+ const data = parts.length < 2 ? parts[0] : parts.join(" ");
927
+ chronicle.trace("error", typeof data === "object" && "message" in data ? { name: data.name, message: data.message } : { message: data });
843
928
  }
844
- }
845
-
846
- function setRootElement(element) {
847
- rootElement = element;
848
- }
849
-
850
- function tearDown() {
851
- staticFieldValues = {};
852
- if (visible) {
853
- hide();
929
+ function event(eventType, eventTarget = "unknown") {
930
+ chronicle.trace("event", { eventTarget, eventType });
854
931
  }
855
- }
856
-
857
- return {
858
- logLevels: LOG_LEVELS,
859
- error,
860
- event,
861
- info,
862
- setLogLevel,
863
- setRootElement,
864
- tearDown,
865
- time,
866
- toggleVisibility,
867
- verbose,
868
- warn,
869
- apicall: Chronicle.apicall,
870
- keyValue: updateKeyValue,
871
- }
932
+ function gap(from, to) {
933
+ chronicle.trace("gap", { from, to });
934
+ }
935
+ function quotaExceeded(bufferLevel, time) {
936
+ chronicle.trace("quota-exceeded", { bufferLevel, time });
937
+ }
938
+ function info(...parts) {
939
+ if (currentLogLevel < LogLevels.INFO) {
940
+ return;
941
+ }
942
+ chronicle.info(parts.join(" "));
943
+ }
944
+ function statechange(value) {
945
+ chronicle.trace("state-change", value);
946
+ }
947
+ function warn(...parts) {
948
+ if (currentLogLevel < LogLevels.WARN) {
949
+ return;
950
+ }
951
+ chronicle.warn(parts.join(" "));
952
+ }
953
+ function dynamicMetric(kind, data) {
954
+ chronicle.appendMetric(kind, data);
955
+ }
956
+ function staticMetric(kind, data) {
957
+ chronicle.setMetric(kind, data);
958
+ }
959
+ function handleHistoryUpdate(change) {
960
+ viewController.addEntries([change]);
961
+ }
962
+ function handleTimeUpdate(seconds) {
963
+ viewController.addTime({ currentElementTime: seconds, sessionTime: chronicle.getSessionTime() });
964
+ }
965
+ function hide() {
966
+ viewController.hideView();
967
+ chronicle.off("update", handleHistoryUpdate);
968
+ chronicle.off("timeupdate", handleTimeUpdate);
969
+ }
970
+ function show() {
971
+ viewController.showView();
972
+ viewController.addEntries(chronicle.retrieve());
973
+ viewController.addTime({
974
+ currentElementTime: chronicle.getCurrentElementTime(),
975
+ sessionTime: chronicle.getSessionTime(),
976
+ });
977
+ chronicle.on("update", handleHistoryUpdate);
978
+ chronicle.on("timeupdate", handleTimeUpdate);
979
+ }
980
+ function toggleVisibility() {
981
+ const toggle = viewController.isVisible ? hide : show;
982
+ toggle();
983
+ }
984
+ return {
985
+ logLevels: LogLevels,
986
+ init,
987
+ tearDown,
988
+ getDebugLogs,
989
+ setLogLevel,
990
+ updateElementTime,
991
+ apicall,
992
+ buffered,
993
+ debug,
994
+ error,
995
+ event,
996
+ gap,
997
+ quotaExceeded,
998
+ info,
999
+ statechange,
1000
+ warn,
1001
+ dynamicMetric,
1002
+ staticMetric,
1003
+ hide,
1004
+ show,
1005
+ setRootElement,
1006
+ toggleVisibility,
1007
+ };
872
1008
  }
873
-
874
1009
  const DebugToolInstance = DebugTool();
875
1010
 
876
1011
  function LiveGlitchCurtain(parentElement) {
@@ -943,14 +1078,14 @@ function LegacyPlayerAdapter(mediaSources, windowType, playbackElement, isUHD, p
943
1078
 
944
1079
  function eventHandler(event) {
945
1080
  const handleEvent = {
946
- playing: onPlaying,
947
- paused: onPaused,
948
- buffering: onBuffering,
1081
+ "playing": onPlaying,
1082
+ "paused": onPaused,
1083
+ "buffering": onBuffering,
949
1084
  "seek-attempted": onSeekAttempted,
950
1085
  "seek-finished": onSeekFinished,
951
- status: onTimeUpdate,
952
- complete: onEnded,
953
- error: onError,
1086
+ "status": onTimeUpdate,
1087
+ "complete": onEnded,
1088
+ "error": onError,
954
1089
  };
955
1090
 
956
1091
  if (handleEvent.hasOwnProperty(event.type)) {
@@ -987,6 +1122,8 @@ function LegacyPlayerAdapter(mediaSources, windowType, playbackElement, isUHD, p
987
1122
  }
988
1123
 
989
1124
  function onTimeUpdate(event) {
1125
+ DebugToolInstance.updateElementTime(event.currentTime);
1126
+
990
1127
  isPaused = false;
991
1128
 
992
1129
  // Note: Multiple consecutive CDN failover logic
@@ -999,6 +1136,7 @@ function LegacyPlayerAdapter(mediaSources, windowType, playbackElement, isUHD, p
999
1136
  // Must publish this time update before checkSeekSucceded - which could cause a pause event
1000
1137
  // This is a device specific event ordering issue.
1001
1138
  publishTimeUpdate();
1139
+
1002
1140
  if ((handleErrorOnExitingSeek || delayPauseOnExitSeek) && exitingSeek) {
1003
1141
  checkSeekSucceeded(event.seekableRange.start, event.currentTime);
1004
1142
  }
@@ -1146,13 +1284,10 @@ function LegacyPlayerAdapter(mediaSources, windowType, playbackElement, isUHD, p
1146
1284
 
1147
1285
  if (!isPlaybackFromLivePoint && typeof mediaPlayer.beginPlaybackFrom === "function") {
1148
1286
  currentTime = startTime;
1149
- DebugToolInstance.keyValue({ key: "initial-playback-time", value: startTime + timeCorrection });
1150
1287
  mediaPlayer.beginPlaybackFrom(startTime + timeCorrection || 0);
1151
1288
  } else {
1152
1289
  mediaPlayer.beginPlayback();
1153
1290
  }
1154
-
1155
- DebugToolInstance.keyValue({ key: "strategy", value: getStrategy() });
1156
1291
  },
1157
1292
  play: () => {
1158
1293
  isPaused = false;
@@ -5189,7 +5324,9 @@ function hasFiniteSeekableRange(seekableRange) {
5189
5324
  let hasRange = true;
5190
5325
  try {
5191
5326
  hasRange = seekableRange.end !== Infinity;
5192
- } catch (e) {}
5327
+ } catch (_error) {
5328
+ /* empty */
5329
+ }
5193
5330
  return hasRange
5194
5331
  }
5195
5332
 
@@ -5231,7 +5368,7 @@ function autoResumeAtStartOfRange(
5231
5368
  resume
5232
5369
  ) {
5233
5370
  const resumeTimeOut = Math.max(0, currentTime - seekableRange.start - AUTO_RESUME_WINDOW_START_CUSHION_SECONDS);
5234
- DebugToolInstance.keyValue({ key: "autoresume", value: resumeTimeOut });
5371
+ DebugToolInstance.dynamicMetric("auto-resume", resumeTimeOut);
5235
5372
  const autoResumeTimer = setTimeout(() => {
5236
5373
  removeEventCallback(undefined, detectIfUnpaused);
5237
5374
  resume();
@@ -5248,9 +5385,9 @@ function autoResumeAtStartOfRange(
5248
5385
  }
5249
5386
 
5250
5387
  var DynamicWindowUtils = {
5251
- autoResumeAtStartOfRange: autoResumeAtStartOfRange,
5252
- canPause: canPause,
5253
- canSeek: canSeek,
5388
+ autoResumeAtStartOfRange,
5389
+ canPause,
5390
+ canSeek,
5254
5391
  };
5255
5392
 
5256
5393
  function RestartableLivePlayer(mediaPlayer, windowType, mediaSources) {
@@ -5512,8 +5649,8 @@ function NativeStrategy(mediaSources, windowType, mediaKind, playbackElement, is
5512
5649
  NativeStrategy.getLiveSupport = () => window.bigscreenPlayer.liveSupport;
5513
5650
 
5514
5651
  const MediaKinds = {
5515
- AUDIO: "audio",
5516
- VIDEO: "video",
5652
+ AUDIO: "audio",
5653
+ VIDEO: "video",
5517
5654
  };
5518
5655
 
5519
5656
  function BasicStrategy(mediaSources, windowType, mediaKind, playbackElement) {
@@ -5546,14 +5683,16 @@ function BasicStrategy(mediaSources, windowType, mediaKind, playbackElement) {
5546
5683
  }
5547
5684
 
5548
5685
  function load(_mimeType, startTime) {
5549
- if (!mediaElement) {
5686
+ if (mediaElement == null) {
5550
5687
  setUpMediaElement(startTime);
5551
5688
  setUpMediaListeners();
5552
- } else {
5553
- mediaElement.src = mediaSources.currentSource();
5554
- setStartTime(startTime);
5555
- mediaElement.load();
5689
+
5690
+ return
5556
5691
  }
5692
+
5693
+ mediaElement.src = mediaSources.currentSource();
5694
+ setStartTime(startTime);
5695
+ mediaElement.load();
5557
5696
  }
5558
5697
 
5559
5698
  function setUpMediaElement(startTime) {
@@ -5623,6 +5762,8 @@ function BasicStrategy(mediaSources, windowType, mediaKind, playbackElement) {
5623
5762
  }
5624
5763
 
5625
5764
  function onTimeUpdate() {
5765
+ DebugToolInstance.updateElementTime(mediaElement.currentTime);
5766
+
5626
5767
  publishTimeUpdate();
5627
5768
  }
5628
5769
 
@@ -5795,7 +5936,7 @@ BasicStrategy.getLiveSupport = () => LiveSupport.SEEKABLE;
5795
5936
  function StrategyPicker() {
5796
5937
  return new Promise((resolve, reject) => {
5797
5938
  if (window.bigscreenPlayer.playbackStrategy === PlaybackStrategy.MSE) {
5798
- return import('./msestrategy-f3c61ef4.js')
5939
+ return import('./msestrategy-41492b38.js')
5799
5940
  .then(({ default: MSEStrategy }) => resolve(MSEStrategy))
5800
5941
  .catch(() => {
5801
5942
  reject({ error: "strategyDynamicLoadError" });
@@ -6213,9 +6354,9 @@ function getLiveSupport$1() {
6213
6354
  PlayerComponent.getLiveSupport = getLiveSupport$1;
6214
6355
 
6215
6356
  const PauseTriggers = {
6216
- USER: 1,
6217
- APP: 2,
6218
- DEVICE: 3,
6357
+ USER: 1,
6358
+ APP: 2,
6359
+ DEVICE: 3,
6219
6360
  };
6220
6361
 
6221
6362
  function DeferExceptions(cb) {
@@ -6244,7 +6385,7 @@ function CallCallbacks(callbacks, data) {
6244
6385
  }
6245
6386
  }
6246
6387
 
6247
- var version = "7.1.5";
6388
+ var Version = "7.2.0";
6248
6389
 
6249
6390
  var sourceList;
6250
6391
  var source;
@@ -6564,7 +6705,7 @@ var mockFunctions = {
6564
6705
  return
6565
6706
  },
6566
6707
  getFrameworkVersion: function () {
6567
- return version
6708
+ return Version
6568
6709
  },
6569
6710
  tearDown: function () {
6570
6711
  manifestError = false;
@@ -7483,11 +7624,11 @@ function MediaSources() {
7483
7624
  }
7484
7625
 
7485
7626
  function updateDebugOutput() {
7486
- DebugToolInstance.keyValue({ key: "available cdns", value: availableCdns() });
7487
- DebugToolInstance.keyValue({ key: "url", value: stripQueryParamsAndHash(getCurrentUrl()) });
7627
+ DebugToolInstance.dynamicMetric("cdns-available", availableCdns());
7628
+ DebugToolInstance.dynamicMetric("current-url", stripQueryParamsAndHash(getCurrentUrl()));
7488
7629
 
7489
- DebugToolInstance.keyValue({ key: "available subtitle cdns", value: availableSubtitlesCdns() });
7490
- DebugToolInstance.keyValue({ key: "subtitles url", value: stripQueryParamsAndHash(getCurrentSubtitlesUrl()) });
7630
+ DebugToolInstance.dynamicMetric("subtitle-cdns-available", availableSubtitlesCdns());
7631
+ DebugToolInstance.dynamicMetric("subtitle-current-url", stripQueryParamsAndHash(getCurrentSubtitlesUrl()));
7491
7632
  }
7492
7633
 
7493
7634
  function tearDown() {
@@ -7636,7 +7777,7 @@ function Subtitles(mediaPlayer, autoStart, playbackElement, defaultStyleOpts, me
7636
7777
 
7637
7778
  if (available()) {
7638
7779
  if (useLegacySubs) {
7639
- import('./legacysubtitles-fc6e0bc6.js')
7780
+ import('./legacysubtitles-33f2dd7e.js')
7640
7781
  .then(({ default: LegacySubtitles }) => {
7641
7782
  subtitlesContainer = LegacySubtitles(mediaPlayer, autoStart, playbackElement, mediaSources, defaultStyleOpts);
7642
7783
  callback(subtitlesEnabled);
@@ -7645,7 +7786,7 @@ function Subtitles(mediaPlayer, autoStart, playbackElement, defaultStyleOpts, me
7645
7786
  Plugins.interface.onSubtitlesDynamicLoadError();
7646
7787
  });
7647
7788
  } else {
7648
- import('./imscsubtitles-abbf8ed4.js')
7789
+ import('./imscsubtitles-92685a59.js')
7649
7790
  .then(({ default: IMSCSubtitles }) => {
7650
7791
  subtitlesContainer = IMSCSubtitles(mediaPlayer, autoStart, playbackElement, mediaSources, defaultStyleOpts);
7651
7792
  callback(subtitlesEnabled);
@@ -7767,7 +7908,6 @@ function BigscreenPlayer() {
7767
7908
 
7768
7909
  function mediaStateUpdateCallback(evt) {
7769
7910
  if (evt.timeUpdate) {
7770
- DebugToolInstance.time(evt.data.currentTime);
7771
7911
  CallCallbacks(timeUpdateCallbacks, {
7772
7912
  currentTime: evt.data.currentTime,
7773
7913
  endOfStream,
@@ -7796,18 +7936,20 @@ function BigscreenPlayer() {
7796
7936
  }
7797
7937
 
7798
7938
  stateObject.endOfStream = endOfStream;
7799
- DebugToolInstance.event(stateObject);
7939
+ DebugToolInstance.statechange(evt.data.state);
7800
7940
 
7801
7941
  CallCallbacks(stateChangeCallbacks, stateObject);
7802
7942
  }
7803
7943
 
7804
7944
  if (evt.data.seekableRange) {
7805
- DebugToolInstance.keyValue({ key: "seekableRangeStart", value: deviceTimeToDate(evt.data.seekableRange.start) });
7806
- DebugToolInstance.keyValue({ key: "seekableRangeEnd", value: deviceTimeToDate(evt.data.seekableRange.end) });
7945
+ DebugToolInstance.staticMetric("seekable-range", [
7946
+ deviceTimeToDate(evt.data.seekableRange.start).getTime(),
7947
+ deviceTimeToDate(evt.data.seekableRange.end).getTime(),
7948
+ ]);
7807
7949
  }
7808
7950
 
7809
7951
  if (evt.data.duration) {
7810
- DebugToolInstance.keyValue({ key: "duration", value: evt.data.duration });
7952
+ DebugToolInstance.dynamicMetric("duration", evt.data.duration);
7811
7953
  }
7812
7954
 
7813
7955
  if (playerComponent && readyHelper) {
@@ -7914,10 +8056,19 @@ function BigscreenPlayer() {
7914
8056
  */
7915
8057
  init: (newPlaybackElement, bigscreenPlayerData, newWindowType, enableSubtitles, callbacks = {}) => {
7916
8058
  playbackElement = newPlaybackElement;
7917
- Chronicle.init();
7918
8059
  resizer = Resizer();
8060
+ DebugToolInstance.init();
7919
8061
  DebugToolInstance.setRootElement(playbackElement);
7920
- DebugToolInstance.keyValue({ key: "framework-version", value: version });
8062
+ DebugToolInstance.staticMetric("version", Version);
8063
+
8064
+ if (typeof bigscreenPlayerData.initialPlaybackTime === "number") {
8065
+ DebugToolInstance.staticMetric("initial-playback-time", bigscreenPlayerData.initialPlaybackTime);
8066
+ }
8067
+
8068
+ if (typeof window.bigscreenPlayer?.playbackStrategy === "string") {
8069
+ DebugToolInstance.staticMetric("strategy", window.bigscreenPlayer && window.bigscreenPlayer.playbackStrategy);
8070
+ }
8071
+
7921
8072
  windowType = newWindowType;
7922
8073
  serverDate = bigscreenPlayerData.serverDate;
7923
8074
 
@@ -7973,7 +8124,6 @@ function BigscreenPlayer() {
7973
8124
  resizer = undefined;
7974
8125
  this.unregisterPlugin();
7975
8126
  DebugToolInstance.tearDown();
7976
- Chronicle.tearDown();
7977
8127
  },
7978
8128
 
7979
8129
  /**
@@ -8049,7 +8199,7 @@ function BigscreenPlayer() {
8049
8199
  * @param {Number} time - In seconds
8050
8200
  */
8051
8201
  setCurrentTime(time) {
8052
- DebugToolInstance.apicall("setCurrentTime");
8202
+ DebugToolInstance.apicall("setCurrentTime", [time]);
8053
8203
  if (playerComponent) {
8054
8204
  // this flag must be set before calling into playerComponent.setCurrentTime - as this synchronously fires a WAITING event (when native strategy).
8055
8205
  isSeeking = true;
@@ -8359,7 +8509,7 @@ function BigscreenPlayer() {
8359
8509
  * @function
8360
8510
  * @return The runtime version of the library.
8361
8511
  */
8362
- getFrameworkVersion: () => version,
8512
+ getFrameworkVersion: () => Version,
8363
8513
 
8364
8514
  /**
8365
8515
  * @function
@@ -8384,8 +8534,8 @@ function BigscreenPlayer() {
8384
8534
  * @function
8385
8535
  * @param logLevel - log level to display @see getLogLevels
8386
8536
  */
8387
- setLogLevel: DebugToolInstance.setLogLevel,
8388
- getDebugLogs: () => Chronicle.retrieve(),
8537
+ setLogLevel: (level) => DebugToolInstance.setLogLevel(level),
8538
+ getDebugLogs: () => DebugToolInstance.getDebugLogs(),
8389
8539
  }
8390
8540
  }
8391
8541
 
@@ -8400,21 +8550,24 @@ function getLiveSupport() {
8400
8550
 
8401
8551
  BigscreenPlayer.getLiveSupport = getLiveSupport;
8402
8552
 
8403
- BigscreenPlayer.version = version;
8553
+ BigscreenPlayer.version = Version;
8404
8554
 
8555
+ /**
8556
+ * Provides an enumeration of on-screen transport control positions, which can be combined as flags.
8557
+ */
8405
8558
  const TransportControlPosition = {
8406
- /** No transport controls are visible. */
8407
- NONE: 0,
8408
- /** The basic transport controls are visible. */
8409
- CONTROLS_ONLY: 1,
8410
- /** The transport controls are visible with an expanded info area. */
8411
- CONTROLS_WITH_INFO: 2,
8412
- /** The left-hand onwards navigation carousel is visible. */
8413
- LEFT_CAROUSEL: 4,
8414
- /** The bottom-right onwards navigation carousel is visible. */
8415
- BOTTOM_CAROUSEL: 8,
8416
- /** The whole screen is obscured by a navigation menu. */
8417
- FULLSCREEN: 16,
8559
+ /** No transport controls are visible. */
8560
+ NONE: 0,
8561
+ /** The basic transport controls are visible. */
8562
+ CONTROLS_ONLY: 1,
8563
+ /** The transport controls are visible with an expanded info area. */
8564
+ CONTROLS_WITH_INFO: 2,
8565
+ /** The left-hand onwards navigation carousel is visible. */
8566
+ LEFT_CAROUSEL: 4,
8567
+ /** The bottom-right onwards navigation carousel is visible. */
8568
+ BOTTOM_CAROUSEL: 8,
8569
+ /** The whole screen is obscured by a navigation menu. */
8570
+ FULLSCREEN: 16,
8418
8571
  };
8419
8572
 
8420
- export { BigscreenPlayer as B, DOMHelpers as D, LoadUrl as L, MediaState as M, Plugins as P, TransportControlPosition as T, Utils as U, WindowTypes as W, DebugToolInstance as a, LiveSupport as b, MediaKinds as c, TimeUtils as d, DynamicWindowUtils as e, findSegmentTemplate as f, MockBigscreenPlayer as g, PauseTriggers as h, PlaybackStrategy as i, TransferFormat as j };
8573
+ export { BigscreenPlayer as B, DOMHelpers as D, EntryCategory as E, LoadUrl as L, MediaState as M, Plugins as P, TransportControlPosition as T, Utils as U, WindowTypes as W, DebugToolInstance as a, LiveSupport as b, MediaKinds as c, TimeUtils as d, DynamicWindowUtils as e, findSegmentTemplate as f, MockBigscreenPlayer as g, PauseTriggers as h, PlaybackStrategy as i, TransferFormat as j, isMessage as k, isMetric as l, isTrace as m };