shaka-player 4.0.0 → 4.1.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.
Files changed (114) hide show
  1. package/.github/config.yml +1 -0
  2. package/.github/workflows/release-please.yaml +6 -11
  3. package/CHANGELOG.md +33 -0
  4. package/CONTRIBUTORS +1 -0
  5. package/README.md +4 -4
  6. package/build/misspellings.txt +1 -0
  7. package/demo/common/message_ids.js +1 -0
  8. package/demo/config.js +3 -1
  9. package/demo/demo.less +0 -1
  10. package/demo/locales/en.json +1 -0
  11. package/demo/locales/source.json +4 -0
  12. package/dist/controls.css +3 -3
  13. package/dist/controls.css.map +1 -1
  14. package/dist/demo.compiled.debug.js +4 -4
  15. package/dist/demo.compiled.debug.map +2 -2
  16. package/dist/demo.compiled.js +4 -4
  17. package/dist/demo.compiled.map +2 -2
  18. package/dist/demo.css +1 -1
  19. package/dist/demo.css.map +1 -1
  20. package/dist/deps.js +3 -3
  21. package/dist/locales.js +32 -32
  22. package/dist/receiver.compiled.debug.js +2 -2
  23. package/dist/receiver.compiled.debug.map +2 -2
  24. package/dist/receiver.compiled.js +2 -2
  25. package/dist/receiver.compiled.map +2 -2
  26. package/dist/shaka-player.compiled.d.ts +15 -8
  27. package/dist/shaka-player.compiled.debug.d.ts +15 -8
  28. package/dist/shaka-player.compiled.debug.externs.js +11 -2
  29. package/dist/shaka-player.compiled.debug.js +266 -253
  30. package/dist/shaka-player.compiled.debug.map +3 -3
  31. package/dist/shaka-player.compiled.externs.js +11 -2
  32. package/dist/shaka-player.compiled.js +792 -784
  33. package/dist/shaka-player.compiled.map +3 -3
  34. package/dist/shaka-player.ui.d.ts +16 -9
  35. package/dist/shaka-player.ui.debug.d.ts +16 -9
  36. package/dist/shaka-player.ui.debug.externs.js +11 -2
  37. package/dist/shaka-player.ui.debug.js +299 -282
  38. package/dist/shaka-player.ui.debug.map +3 -3
  39. package/dist/shaka-player.ui.externs.js +11 -2
  40. package/dist/shaka-player.ui.js +948 -941
  41. package/dist/shaka-player.ui.map +3 -3
  42. package/docs/design/chromecast.md +3 -1
  43. package/docs/tutorials/drm-config.md +16 -0
  44. package/docs/tutorials/ui.md +26 -0
  45. package/docs/tutorials/upgrade.md +4 -2
  46. package/externs/chromecast.js +9 -2
  47. package/externs/shaka/manifest.js +7 -0
  48. package/externs/shaka/player.js +32 -2
  49. package/externs/shaka/text.js +7 -0
  50. package/karma.conf.js +4 -0
  51. package/lib/abr/simple_abr_manager.js +2 -1
  52. package/lib/cast/cast_proxy.js +19 -8
  53. package/lib/cast/cast_receiver.js +3 -3
  54. package/lib/cast/cast_sender.js +12 -2
  55. package/lib/dash/dash_parser.js +2 -2
  56. package/lib/hls/hls_parser.js +46 -15
  57. package/lib/media/drm_engine.js +36 -8
  58. package/lib/media/gap_jumping_controller.js +23 -1
  59. package/lib/media/media_source_engine.js +91 -37
  60. package/lib/media/playhead.js +47 -4
  61. package/lib/media/stall_detector.js +19 -2
  62. package/lib/media/streaming_engine.js +9 -3
  63. package/lib/offline/indexeddb/storage_mechanism.js +4 -2
  64. package/lib/offline/manifest_converter.js +1 -0
  65. package/lib/player.js +339 -175
  66. package/lib/text/cue.js +6 -0
  67. package/lib/text/ui_text_displayer.js +1 -0
  68. package/lib/text/vtt_text_parser.js +11 -7
  69. package/lib/util/config_utils.js +25 -0
  70. package/lib/util/error.js +13 -0
  71. package/lib/util/fake_event.js +39 -0
  72. package/lib/util/manifest_parser_utils.js +1 -1
  73. package/lib/util/mime_utils.js +62 -6
  74. package/lib/util/periods.js +5 -4
  75. package/lib/util/player_configuration.js +16 -14
  76. package/lib/util/stats.js +28 -1
  77. package/lib/util/stream_utils.js +11 -2
  78. package/package.json +5 -2
  79. package/test/cast/cast_proxy_unit.js +3 -1
  80. package/test/cast/cast_sender_unit.js +21 -6
  81. package/test/demo/demo_unit.js +2 -1
  82. package/test/hls/hls_live_unit.js +79 -7
  83. package/test/hls/manifest_text_parser_unit.js +19 -0
  84. package/test/media/adaptation_set_unit.js +1 -0
  85. package/test/media/playhead_unit.js +114 -25
  86. package/test/media/stall_detector_unit.js +20 -2
  87. package/test/media/streaming_engine_integration.js +2 -1
  88. package/test/media/streaming_engine_unit.js +1 -0
  89. package/test/offline/indexeddb_storage_unit.js +1 -1
  90. package/test/offline/storage_compatibility_unit.js +1 -1
  91. package/test/player_external.js +7 -1
  92. package/test/player_integration.js +9 -10
  93. package/test/player_src_equals_integration.js +81 -83
  94. package/test/player_unit.js +240 -2
  95. package/test/test/boot.js +9 -0
  96. package/test/test/externs/filters.js +4 -0
  97. package/test/test/util/manifest_generator.js +2 -0
  98. package/test/test/util/simple_fakes.js +45 -2
  99. package/test/test/util/streaming_engine_util.js +1 -0
  100. package/test/text/vtt_text_parser_unit.js +68 -5
  101. package/test/ui/ui_unit.js +18 -5
  102. package/test/util/mime_utils_unit.js +54 -0
  103. package/test/util/periods_unit.js +79 -0
  104. package/test/util/stream_utils_unit.js +108 -0
  105. package/ui/controls.js +12 -8
  106. package/ui/externs/ui.js +10 -1
  107. package/ui/less/containers.less +1 -1
  108. package/ui/less/general.less +1 -1
  109. package/ui/less/range_elements.less +1 -0
  110. package/ui/resolution_selection.js +1 -1
  111. package/ui/statistics_button.js +10 -0
  112. package/ui/ui.js +12 -1
  113. package/.github/pull_request_template.md +0 -10
  114. package/docs/tutorials/gsoc-ideas-list.md +0 -3
@@ -5,6 +5,8 @@
5
5
  */
6
6
 
7
7
  describe('StallDetector', () => {
8
+ const Util = shaka.test.Util;
9
+
8
10
  /**
9
11
  * @implements {shaka.media.StallDetector.Implementation}
10
12
  * @final
@@ -38,16 +40,21 @@ describe('StallDetector', () => {
38
40
  /** @type {!jasmine.Spy} */
39
41
  let onStall;
40
42
 
43
+ /** @type {!jasmine.Spy} */
44
+ let onEvent;
45
+
41
46
  beforeEach(() => {
42
47
  onStall = jasmine.createSpy('onStall');
48
+ onEvent = jasmine.createSpy('onEvent');
43
49
 
44
50
  implementation = new TestImplementation();
45
51
 
46
52
  detector = new shaka.media.StallDetector(
47
53
  implementation,
48
- /* stallThresholdSeconds= */ 1);
54
+ /* stallThresholdSeconds= */ 1,
55
+ Util.spyFunc(onEvent));
49
56
 
50
- detector.onStall(shaka.test.Util.spyFunc(onStall));
57
+ detector.onStall(Util.spyFunc(onStall));
51
58
  });
52
59
 
53
60
  it('does not call onStall when values changes', () => {
@@ -63,6 +70,7 @@ describe('StallDetector', () => {
63
70
 
64
71
  detector.poll();
65
72
 
73
+ expect(onEvent).not.toHaveBeenCalled();
66
74
  expect(onStall).not.toHaveBeenCalled();
67
75
  });
68
76
 
@@ -74,6 +82,7 @@ describe('StallDetector', () => {
74
82
  implementation.wallSeconds = time;
75
83
 
76
84
  detector.poll();
85
+ expect(onEvent).not.toHaveBeenCalled();
77
86
  expect(onStall).not.toHaveBeenCalled();
78
87
  }
79
88
 
@@ -81,6 +90,7 @@ describe('StallDetector', () => {
81
90
  implementation.wallSeconds = 1;
82
91
 
83
92
  detector.poll();
93
+ expect(onEvent).toHaveBeenCalled();
84
94
  expect(onStall).toHaveBeenCalledOnceMoreWith([
85
95
  /* stalledWith= */ 5,
86
96
  /* stallDurationSeconds= */ 1,
@@ -96,6 +106,7 @@ describe('StallDetector', () => {
96
106
  implementation.wallSeconds = 10;
97
107
  detector.poll();
98
108
 
109
+ expect(onEvent).toHaveBeenCalled();
99
110
  expect(onStall).toHaveBeenCalledOnceMoreWith([
100
111
  /* stalledWith= */ 5,
101
112
  /* stallDurationms= */ 10,
@@ -117,6 +128,7 @@ describe('StallDetector', () => {
117
128
 
118
129
  detector.poll();
119
130
 
131
+ expect(onEvent).not.toHaveBeenCalled();
120
132
  expect(onStall).not.toHaveBeenCalled();
121
133
  });
122
134
 
@@ -135,6 +147,7 @@ describe('StallDetector', () => {
135
147
  implementation.wallSeconds = 10;
136
148
  detector.poll();
137
149
 
150
+ expect(onEvent).not.toHaveBeenCalled();
138
151
  expect(onStall).not.toHaveBeenCalled();
139
152
  });
140
153
 
@@ -143,16 +156,20 @@ describe('StallDetector', () => {
143
156
  implementation.presentationSeconds = 0;
144
157
  implementation.wallSeconds = 0;
145
158
  detector.poll();
159
+ expect(onEvent).not.toHaveBeenCalled();
146
160
  expect(onStall).not.toHaveBeenCalled();
147
161
 
148
162
  implementation.wallSeconds = 10;
149
163
  detector.poll();
164
+ expect(onEvent).toHaveBeenCalled();
150
165
  expect(onStall).toHaveBeenCalled();
166
+ onEvent.calls.reset();
151
167
  onStall.calls.reset();
152
168
 
153
169
  // This is the same stall, should not be called again.
154
170
  implementation.wallSeconds = 20;
155
171
  detector.poll();
172
+ expect(onEvent).not.toHaveBeenCalled();
156
173
  expect(onStall).not.toHaveBeenCalled();
157
174
 
158
175
  // Now that we changed time, we should get another call.
@@ -161,6 +178,7 @@ describe('StallDetector', () => {
161
178
  detector.poll();
162
179
  implementation.wallSeconds = 40;
163
180
  detector.poll();
181
+ expect(onEvent).toHaveBeenCalled();
164
182
  expect(onStall).toHaveBeenCalled();
165
183
  });
166
184
  });
@@ -214,7 +214,8 @@ describe('StreamingEngine', () => {
214
214
  manifest,
215
215
  config,
216
216
  /* startTime= */ null,
217
- onSeek);
217
+ onSeek,
218
+ shaka.test.Util.spyFunc(onEvent));
218
219
  }
219
220
 
220
221
  function setupManifest(
@@ -396,6 +396,7 @@ describe('StreamingEngine', () => {
396
396
  video: /** @type {shaka.extern.Stream} */ (alternateVideoStream),
397
397
  id: 0,
398
398
  language: 'und',
399
+ disabledUntilTime: 0,
399
400
  primary: false,
400
401
  bandwidth: 0,
401
402
  allowedByApplication: true,
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- filterDescribe('IndexeddbStorageCell', () => window.indexedDB, () => {
7
+ filterDescribe('IndexeddbStorageCell', offlineSupported, () => {
8
8
  const IndexedDBUtils = shaka.test.IndexedDBUtils;
9
9
  const OfflineUtils = shaka.test.OfflineUtils;
10
10
  const Util = shaka.test.Util;
@@ -91,7 +91,7 @@ const compatibilityTestsMetadata = [
91
91
  },
92
92
  ];
93
93
 
94
- filterDescribe('Storage Compatibility', () => window.indexedDB, () => {
94
+ filterDescribe('Storage Compatibility', offlineSupported, () => {
95
95
  for (const metadata of compatibilityTestsMetadata) {
96
96
  describe(metadata.name, () => {
97
97
  makeTests(metadata);
@@ -114,7 +114,13 @@ describe('Player', () => {
114
114
  const networkingEngine = player.getNetworkingEngine();
115
115
  asset.applyFilters(networkingEngine);
116
116
 
117
- await player.load(asset.manifestUri);
117
+ // Rather than awaiting the load() method, catch any load() errors and
118
+ // wait on the 'canplay' event. This has the advantage that we will
119
+ // get better logging of the media state on a timeout, since that
120
+ // capabilitiy is built into the waiter for media element events.
121
+ player.load(asset.manifestUri).catch(fail);
122
+ await waiter.timeoutAfter(60).waitForEvent(video, 'canplay');
123
+
118
124
  if (asset.features) {
119
125
  const isLive = asset.features.includes(Feature.LIVE);
120
126
  expect(player.isLive()).toBe(isLive);
@@ -126,6 +126,9 @@ describe('Player', () => {
126
126
  corruptedFrames: jasmine.any(Number),
127
127
  estimatedBandwidth: jasmine.any(Number),
128
128
 
129
+ gapsJumped: jasmine.any(Number),
130
+ stallsDetected: jasmine.any(Number),
131
+
129
132
  completionPercent: jasmine.any(Number),
130
133
  loadLatency: jasmine.any(Number),
131
134
  manifestTimeSeconds: jasmine.any(Number),
@@ -1069,16 +1072,16 @@ describe('Player', () => {
1069
1072
  });
1070
1073
  }); // describe('unloading')
1071
1074
 
1072
- describe('chapters', () => {
1073
- it('add external chapters in vtt format', async () => {
1075
+ describe('addChaptersTrack', () => {
1076
+ it('adds external chapters in vtt format', async () => {
1074
1077
  await player.load('test:sintel_no_text_compiled');
1075
1078
  const locationUri = new goog.Uri(location.href);
1076
1079
  const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
1077
1080
  const absoluteUri1 = locationUri.resolve(partialUri1);
1078
1081
  await player.addChaptersTrack(absoluteUri1.toString(), 'en');
1079
1082
 
1080
- await shaka.test.Util.delay(1.5);
1081
-
1083
+ // Data should be available as soon as addChaptersTrack resolves.
1084
+ // See https://github.com/shaka-project/shaka-player/issues/4186
1082
1085
  const chapters = player.getChapters('en');
1083
1086
  expect(chapters.length).toBe(3);
1084
1087
  const chapter1 = chapters[0];
@@ -1098,8 +1101,6 @@ describe('Player', () => {
1098
1101
  const absoluteUri2 = locationUri.resolve(partialUri2);
1099
1102
  await player.addChaptersTrack(absoluteUri2.toString(), 'en');
1100
1103
 
1101
- await shaka.test.Util.delay(1.5);
1102
-
1103
1104
  const chaptersUpdated = player.getChapters('en');
1104
1105
  expect(chaptersUpdated.length).toBe(6);
1105
1106
  const chapterUpdated1 = chaptersUpdated[0];
@@ -1128,15 +1129,13 @@ describe('Player', () => {
1128
1129
  expect(chapterUpdated6.endTime).toBe(61.349);
1129
1130
  });
1130
1131
 
1131
- it('add external chapters in srt format', async () => {
1132
+ it('adds external chapters in srt format', async () => {
1132
1133
  await player.load('test:sintel_no_text_compiled');
1133
1134
  const locationUri = new goog.Uri(location.href);
1134
1135
  const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
1135
1136
  const absoluteUri = locationUri.resolve(partialUri);
1136
1137
  await player.addChaptersTrack(absoluteUri.toString(), 'es');
1137
1138
 
1138
- await shaka.test.Util.delay(1.5);
1139
-
1140
1139
  const chapters = player.getChapters('es');
1141
1140
  expect(chapters.length).toBe(3);
1142
1141
  const chapter1 = chapters[0];
@@ -1152,5 +1151,5 @@ describe('Player', () => {
1152
1151
  expect(chapter3.startTime).toBe(30);
1153
1152
  expect(chapter3.endTime).toBe(61.349);
1154
1153
  });
1155
- }); // describe('chapters')
1154
+ }); // describe('addChaptersTrack')
1156
1155
  });
@@ -319,90 +319,88 @@ describe('Player Src Equals', () => {
319
319
  expect(newTrack).toBeTruthy();
320
320
  });
321
321
 
322
- it('add external chapters in vtt format', async () => {
323
- await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
324
-
325
- const locationUri = new goog.Uri(location.href);
326
- const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
327
- const absoluteUri1 = locationUri.resolve(partialUri1);
328
- await player.addChaptersTrack(absoluteUri1.toString(), 'en');
329
-
330
- await shaka.test.Util.delay(1.5);
331
-
332
- const chapters = player.getChapters('en');
333
- expect(chapters.length).toBe(3);
334
- const chapter1 = chapters[0];
335
- expect(chapter1.title).toBe('Chapter 1');
336
- expect(chapter1.startTime).toBe(0);
337
- expect(chapter1.endTime).toBe(5);
338
- const chapter2 = chapters[1];
339
- expect(chapter2.title).toBe('Chapter 2');
340
- expect(chapter2.startTime).toBe(5);
341
- expect(chapter2.endTime).toBe(10);
342
- const chapter3 = chapters[2];
343
- expect(chapter3.title).toBe('Chapter 3');
344
- expect(chapter3.startTime).toBe(10);
345
- expect(chapter3.endTime).toBe(20);
346
-
347
- const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
348
- const absoluteUri2 = locationUri.resolve(partialUri2);
349
- await player.addChaptersTrack(absoluteUri2.toString(), 'en');
350
-
351
- await shaka.test.Util.delay(1.5);
352
-
353
- const chaptersUpdated = player.getChapters('en');
354
- expect(chaptersUpdated.length).toBe(6);
355
- const chapterUpdated1 = chaptersUpdated[0];
356
- expect(chapterUpdated1.title).toBe('Chapter 1');
357
- expect(chapterUpdated1.startTime).toBe(0);
358
- expect(chapterUpdated1.endTime).toBe(5);
359
- const chapterUpdated2 = chaptersUpdated[1];
360
- expect(chapterUpdated2.title).toBe('Chapter 2');
361
- expect(chapterUpdated2.startTime).toBe(5);
362
- expect(chapterUpdated2.endTime).toBe(10);
363
- const chapterUpdated3 = chaptersUpdated[2];
364
- expect(chapterUpdated3.title).toBe('Chapter 3');
365
- expect(chapterUpdated3.startTime).toBe(10);
366
- expect(chapterUpdated3.endTime).toBe(20);
367
- const chapterUpdated4 = chaptersUpdated[3];
368
- expect(chapterUpdated4.title).toBe('Chapter 4');
369
- expect(chapterUpdated4.startTime).toBe(20);
370
- expect(chapterUpdated4.endTime).toBe(30);
371
- const chapterUpdated5 = chaptersUpdated[4];
372
- expect(chapterUpdated5.title).toBe('Chapter 5');
373
- expect(chapterUpdated5.startTime).toBe(30);
374
- expect(chapterUpdated5.endTime).toBe(40);
375
- const chapterUpdated6 = chaptersUpdated[5];
376
- expect(chapterUpdated6.title).toBe('Chapter 6');
377
- expect(chapterUpdated6.startTime).toBe(40);
378
- expect(chapterUpdated6.endTime).toBe(61.349);
379
- });
380
-
381
- it('add external chapters in srt format', async () => {
382
- await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
383
-
384
- const locationUri = new goog.Uri(location.href);
385
- const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
386
- const absoluteUri = locationUri.resolve(partialUri);
387
- await player.addChaptersTrack(absoluteUri.toString(), 'es');
388
-
389
- await shaka.test.Util.delay(1.5);
322
+ describe('addChaptersTrack', () => {
323
+ it('adds external chapters in vtt format', async () => {
324
+ await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
325
+
326
+ const locationUri = new goog.Uri(location.href);
327
+ const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
328
+ const absoluteUri1 = locationUri.resolve(partialUri1);
329
+ await player.addChaptersTrack(absoluteUri1.toString(), 'en');
330
+
331
+ // Data should be available as soon as addChaptersTrack resolves.
332
+ // See https://github.com/shaka-project/shaka-player/issues/4186
333
+ const chapters = player.getChapters('en');
334
+ expect(chapters.length).toBe(3);
335
+ const chapter1 = chapters[0];
336
+ expect(chapter1.title).toBe('Chapter 1');
337
+ expect(chapter1.startTime).toBe(0);
338
+ expect(chapter1.endTime).toBe(5);
339
+ const chapter2 = chapters[1];
340
+ expect(chapter2.title).toBe('Chapter 2');
341
+ expect(chapter2.startTime).toBe(5);
342
+ expect(chapter2.endTime).toBe(10);
343
+ const chapter3 = chapters[2];
344
+ expect(chapter3.title).toBe('Chapter 3');
345
+ expect(chapter3.startTime).toBe(10);
346
+ expect(chapter3.endTime).toBe(20);
347
+
348
+ const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
349
+ const absoluteUri2 = locationUri.resolve(partialUri2);
350
+ await player.addChaptersTrack(absoluteUri2.toString(), 'en');
351
+
352
+ const chaptersUpdated = player.getChapters('en');
353
+ expect(chaptersUpdated.length).toBe(6);
354
+ const chapterUpdated1 = chaptersUpdated[0];
355
+ expect(chapterUpdated1.title).toBe('Chapter 1');
356
+ expect(chapterUpdated1.startTime).toBe(0);
357
+ expect(chapterUpdated1.endTime).toBe(5);
358
+ const chapterUpdated2 = chaptersUpdated[1];
359
+ expect(chapterUpdated2.title).toBe('Chapter 2');
360
+ expect(chapterUpdated2.startTime).toBe(5);
361
+ expect(chapterUpdated2.endTime).toBe(10);
362
+ const chapterUpdated3 = chaptersUpdated[2];
363
+ expect(chapterUpdated3.title).toBe('Chapter 3');
364
+ expect(chapterUpdated3.startTime).toBe(10);
365
+ expect(chapterUpdated3.endTime).toBe(20);
366
+ const chapterUpdated4 = chaptersUpdated[3];
367
+ expect(chapterUpdated4.title).toBe('Chapter 4');
368
+ expect(chapterUpdated4.startTime).toBe(20);
369
+ expect(chapterUpdated4.endTime).toBe(30);
370
+ const chapterUpdated5 = chaptersUpdated[4];
371
+ expect(chapterUpdated5.title).toBe('Chapter 5');
372
+ expect(chapterUpdated5.startTime).toBe(30);
373
+ expect(chapterUpdated5.endTime).toBe(40);
374
+ const chapterUpdated6 = chaptersUpdated[5];
375
+ expect(chapterUpdated6.title).toBe('Chapter 6');
376
+ expect(chapterUpdated6.startTime).toBe(40);
377
+ expect(chapterUpdated6.endTime).toBe(61.349);
378
+ });
390
379
 
391
- const chapters = player.getChapters('es');
392
- expect(chapters.length).toBe(3);
393
- const chapter1 = chapters[0];
394
- expect(chapter1.title).toBe('Chapter 1');
395
- expect(chapter1.startTime).toBe(0);
396
- expect(chapter1.endTime).toBe(5);
397
- const chapter2 = chapters[1];
398
- expect(chapter2.title).toBe('Chapter 2');
399
- expect(chapter2.startTime).toBe(5);
400
- expect(chapter2.endTime).toBe(30);
401
- const chapter3 = chapters[2];
402
- expect(chapter3.title).toBe('Chapter 3');
403
- expect(chapter3.startTime).toBe(30);
404
- expect(chapter3.endTime).toBe(61.349);
405
- });
380
+ it('add external chapters in srt format', async () => {
381
+ await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
382
+
383
+ const locationUri = new goog.Uri(location.href);
384
+ const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
385
+ const absoluteUri = locationUri.resolve(partialUri);
386
+ await player.addChaptersTrack(absoluteUri.toString(), 'es');
387
+
388
+ const chapters = player.getChapters('es');
389
+ expect(chapters.length).toBe(3);
390
+ const chapter1 = chapters[0];
391
+ expect(chapter1.title).toBe('Chapter 1');
392
+ expect(chapter1.startTime).toBe(0);
393
+ expect(chapter1.endTime).toBe(5);
394
+ const chapter2 = chapters[1];
395
+ expect(chapter2.title).toBe('Chapter 2');
396
+ expect(chapter2.startTime).toBe(5);
397
+ expect(chapter2.endTime).toBe(30);
398
+ const chapter3 = chapters[2];
399
+ expect(chapter3.title).toBe('Chapter 3');
400
+ expect(chapter3.startTime).toBe(30);
401
+ expect(chapter3.endTime).toBe(61.349);
402
+ });
403
+ }); // describe('addChaptersTrack')
406
404
 
407
405
  // Since we are not in-charge of streaming, calling |retryStreaming| should
408
406
  // have no effect.