shaka-player 3.2.16 → 3.2.17

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.
@@ -19,8 +19,8 @@ goog.require('shaka.util.IReleasable');
19
19
 
20
20
 
21
21
  /**
22
- * @event shaka.ads.AdManager.ADS_LOADED
23
- * @description Fired when an ad has started playing.
22
+ * @event shaka.ads.AdManager.AdsLoadedEvent
23
+ * @description Fired when a sequence of ads has been loaded.
24
24
  * @property {string} type
25
25
  * 'ads-loaded'
26
26
  * @property {number} loadTime
@@ -598,6 +598,11 @@ shaka.media.StreamingEngine = class {
598
598
  * within the presentation timeline.
599
599
  */
600
600
  seeked() {
601
+ if (!this.playerInterface_) {
602
+ // Already destroyed.
603
+ return;
604
+ }
605
+
601
606
  const presentationTime = this.playerInterface_.getPresentationTime();
602
607
  const smallGapLimit = this.config_.smallGapLimit;
603
608
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
@@ -652,7 +657,7 @@ shaka.media.StreamingEngine = class {
652
657
 
653
658
  /**
654
659
  * Clear the buffer for a given stream. Unlike clearBuffer_, this will handle
655
- * cases where a MediaState is performing an update. After this runs, every
660
+ * cases where a MediaState is performing an update. After this runs, the
656
661
  * MediaState will have a pending update.
657
662
  * @param {!shaka.media.StreamingEngine.MediaState_} mediaState
658
663
  * @private
@@ -767,9 +772,9 @@ shaka.media.StreamingEngine = class {
767
772
  for (const type of streamsByType.keys()) {
768
773
  const stream = streamsByType.get(type);
769
774
  if (!this.mediaStates_.has(type)) {
770
- const state = this.createMediaState_(stream);
771
- this.mediaStates_.set(type, state);
772
- this.scheduleUpdate_(state, 0);
775
+ const mediaState = this.createMediaState_(stream);
776
+ this.mediaStates_.set(type, mediaState);
777
+ this.scheduleUpdate_(mediaState, 0);
773
778
  }
774
779
  }
775
780
  }
@@ -873,7 +878,7 @@ shaka.media.StreamingEngine = class {
873
878
  // We switched streams while in the middle of this async call to
874
879
  // createSegmentIndex. Abandon this update and schedule a new one if
875
880
  // there's not already one pending.
876
- if (mediaState.updateTimer == null) {
881
+ if (!mediaState.performingUpdate && !mediaState.updateTimer) {
877
882
  this.scheduleUpdate_(mediaState, 0);
878
883
  }
879
884
  return;
@@ -1341,7 +1346,7 @@ shaka.media.StreamingEngine = class {
1341
1346
  // If the network slows down, abort the current fetch request and start
1342
1347
  // a new one, and ignore the error message.
1343
1348
  mediaState.performingUpdate = false;
1344
- mediaState.updateTimer = null;
1349
+ this.cancelUpdate_(mediaState);
1345
1350
  this.scheduleUpdate_(mediaState, 0);
1346
1351
  } else if (mediaState.type == ContentType.TEXT &&
1347
1352
  this.config_.ignoreTextStreamFailures) {
@@ -1386,7 +1391,10 @@ shaka.media.StreamingEngine = class {
1386
1391
 
1387
1392
  for (const mediaState of this.mediaStates_.values()) {
1388
1393
  const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
1389
- if (mediaState.hasError) {
1394
+ // Only schedule an update if it has an error, but it's not mid-update
1395
+ // and there is not already an update scheduled.
1396
+ if (mediaState.hasError && !mediaState.performingUpdate &&
1397
+ !mediaState.updateTimer) {
1390
1398
  shaka.log.info(logPrefix, 'Retrying after failure...');
1391
1399
  mediaState.hasError = false;
1392
1400
  this.scheduleUpdate_(mediaState, delaySeconds);
@@ -1851,7 +1859,11 @@ shaka.media.StreamingEngine = class {
1851
1859
  shaka.log.debug(logPrefix, 'cleared buffer');
1852
1860
  mediaState.clearingBuffer = false;
1853
1861
  mediaState.endOfStream = false;
1854
- this.scheduleUpdate_(mediaState, 0);
1862
+ // Since the clear operation was async, check to make sure we're not doing
1863
+ // another update and we don't have one scheduled yet.
1864
+ if (!mediaState.performingUpdate && !mediaState.updateTimer) {
1865
+ this.scheduleUpdate_(mediaState, 0);
1866
+ }
1855
1867
  }
1856
1868
 
1857
1869
 
package/lib/player.js CHANGED
@@ -3952,16 +3952,25 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
3952
3952
  return [];
3953
3953
  }
3954
3954
  const chapters = [];
3955
+ const uniqueChapters = new Set();
3955
3956
  for (const chaptersTrack of chaptersTracksWithLanguage) {
3956
3957
  if (chaptersTrack && chaptersTrack.cues) {
3957
3958
  for (const cue of chaptersTrack.cues) {
3959
+ let id = cue.id;
3960
+ if (!id || id == '') {
3961
+ id = cue.startTime + '-' + cue.endTime + '-' + cue.text;
3962
+ }
3958
3963
  /** @type {shaka.extern.Chapter} */
3959
3964
  const chapter = {
3965
+ id: id,
3960
3966
  title: cue.text,
3961
3967
  startTime: cue.startTime,
3962
3968
  endTime: cue.endTime,
3963
3969
  };
3964
- chapters.push(chapter);
3970
+ if (!uniqueChapters.has(id)) {
3971
+ chapters.push(chapter);
3972
+ uniqueChapters.add(id);
3973
+ }
3965
3974
  }
3966
3975
  }
3967
3976
  }
@@ -6444,7 +6453,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
6444
6453
  * @define {string} A version number taken from git at compile time.
6445
6454
  * @export
6446
6455
  */
6447
- shaka.Player.version = 'v3.2.16-uncompiled';
6456
+ shaka.Player.version = 'v3.2.17-uncompiled';
6448
6457
 
6449
6458
  // Initialize the deprecation system using the version string we just set
6450
6459
  // on the player.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "3.2.16",
4
+ "version": "3.2.17",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -779,7 +779,7 @@ describe('Player', () => {
779
779
  expect(getBufferedBehind()).toBe(20); // Buffered to start still.
780
780
  video.currentTime = 50;
781
781
  await waitUntilBuffered(30);
782
- expect(getBufferedBehind()).toBeLessThan(30);
782
+ expect(getBufferedBehind()).toBeLessThan(40); // 30 + segment_size
783
783
 
784
784
  player.configure('streaming.bufferBehind', 10);
785
785
  // We only evict content when we append a segment, so increase the
@@ -806,7 +806,7 @@ describe('Player', () => {
806
806
  }
807
807
 
808
808
  async function waitUntilBuffered(amount) {
809
- for (let i = 0; i < 25; i++) {
809
+ for (let i = 0; i < 50; i++) {
810
810
  // We buffer from an internal segment, so this shouldn't take long to
811
811
  // buffer.
812
812
  await Util.delay(0.1); // eslint-disable-line no-await-in-loop
@@ -814,7 +814,14 @@ describe('Player', () => {
814
814
  return;
815
815
  }
816
816
  }
817
- throw new Error('Timeout waiting to buffer');
817
+
818
+ const ranges =
819
+ shaka.media.TimeRangesUtils.getBufferedInfo(video.buffered);
820
+ const currentTime = video.currentTime;
821
+ const target = currentTime + amount;
822
+
823
+ throw new Error('Timeout waiting to buffer! ' +
824
+ JSON.stringify({ranges, currentTime, target}));
818
825
  }
819
826
  }); // describe('buffering')
820
827
 
package/test/test/boot.js CHANGED
@@ -66,22 +66,40 @@ function failTestsOnNamespacedElementOrAttributeNames() {
66
66
  }
67
67
 
68
68
  /**
69
- * Listen for unhandled Promise rejections (which may occur after a test) and
70
- * convert them into test failures.
69
+ * Fail the current test on a given error, constructed with a given header and
70
+ * the full stack trace of the error.
71
+ *
72
+ * @param {string} messageHeader
73
+ * @param {!Error} error
71
74
  */
72
- function failTestsOnUnhandledRejections() {
75
+ function failOnError(messageHeader, error) {
76
+ let message = `${messageHeader}: ${error}`;
77
+ // Shaka errors have the stack trace in their toString() already, so don't
78
+ // add it again. For native errors, we need to see where it came from.
79
+ if (error && error.stack && !(error instanceof shaka.util.Error)) {
80
+ message += '\n' + error.stack;
81
+ }
82
+ fail(message);
83
+ }
84
+
85
+ /**
86
+ * Listen for unhandled errors and Promise rejections (which may occur after a
87
+ * test) and convert them into test failures.
88
+ */
89
+ function failTestsOnUnhandledErrors() {
73
90
  // https://developer.mozilla.org/en-US/docs/Web/Events/unhandledrejection
74
91
  window.addEventListener('unhandledrejection', (event) => {
75
92
  /** @type {?} */
76
93
  const error = event.reason;
77
- let message = 'Unhandled rejection in Promise: ' + error;
94
+ failOnError('Unhandled rejection in Promise', error);
95
+ });
78
96
 
79
- // Shaka errors have the stack trace in their toString() already, so don't
80
- // add it again. For native errors, we need to see where it came from.
81
- if (error && error.stack && !(error instanceof shaka.util.Error)) {
82
- message += '\n' + error.stack;
83
- }
84
- fail(message);
97
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event
98
+ // https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent
99
+ window.addEventListener('error', (event) => {
100
+ /** @type {?} */
101
+ const error = event['error'];
102
+ failOnError('Unhandled error', error);
85
103
  });
86
104
  }
87
105
 
@@ -387,7 +405,7 @@ function configureJasmineEnvironment() {
387
405
  function setupTestEnvironment() {
388
406
  failTestsOnFailedAssertions();
389
407
  failTestsOnNamespacedElementOrAttributeNames();
390
- failTestsOnUnhandledRejections();
408
+ failTestsOnUnhandledErrors();
391
409
  disableScrollbars();
392
410
  workAroundLegacyEdgePromiseIssues();
393
411
 
@@ -389,7 +389,7 @@ const sintelAudioSegment = {
389
389
  mdhdOffset: 0x1b6,
390
390
  segmentUri: '/base/test/test/assets/sintel-audio-segment.mp4',
391
391
  tfdtOffset: 0x3c,
392
- segmentDuration: 10.005,
392
+ segmentDuration: 10,
393
393
  mimeType: 'audio/mp4',
394
394
  codecs: 'mp4a.40.2',
395
395
  };
@@ -415,7 +415,7 @@ const sintelEncryptedAudio = {
415
415
  mdhdOffset: 0x1b6,
416
416
  segmentUri: '/base/test/test/assets/encrypted-sintel-audio-segment.mp4',
417
417
  tfdtOffset: 0x3c,
418
- segmentDuration: 10.005,
418
+ segmentDuration: 10,
419
419
  mimeType: 'audio/mp4',
420
420
  codecs: 'mp4a.40.2',
421
421
  initData: