shaka-player 3.1.5 → 3.2.3

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 (134) hide show
  1. package/CHANGELOG.md +129 -6
  2. package/README.md +4 -4
  3. package/build/types/polyfill +1 -0
  4. package/demo/common/asset.js +9 -7
  5. package/demo/common/assets.js +10 -1
  6. package/demo/common/message_ids.js +2 -1
  7. package/demo/config.js +5 -2
  8. package/demo/index.html +1 -1
  9. package/demo/locales/en.json +2 -1
  10. package/demo/locales/source.json +8 -4
  11. package/demo/main.js +2 -1
  12. package/dist/demo.compiled.debug.js +14 -14
  13. package/dist/demo.compiled.debug.map +2 -2
  14. package/dist/demo.compiled.js +14 -14
  15. package/dist/demo.compiled.map +2 -2
  16. package/dist/deps.js +21 -20
  17. package/dist/locales.js +30 -30
  18. package/dist/receiver.compiled.debug.js +8 -8
  19. package/dist/receiver.compiled.debug.map +2 -2
  20. package/dist/receiver.compiled.js +8 -8
  21. package/dist/receiver.compiled.map +2 -2
  22. package/dist/shaka-player.compiled.d.ts +63 -10
  23. package/dist/shaka-player.compiled.debug.d.ts +63 -10
  24. package/dist/shaka-player.compiled.debug.externs.js +786 -716
  25. package/dist/shaka-player.compiled.debug.js +563 -534
  26. package/dist/shaka-player.compiled.debug.map +4 -4
  27. package/dist/shaka-player.compiled.externs.js +786 -716
  28. package/dist/shaka-player.compiled.js +820 -809
  29. package/dist/shaka-player.compiled.map +4 -4
  30. package/dist/shaka-player.ui.d.ts +63 -10
  31. package/dist/shaka-player.ui.debug.d.ts +63 -10
  32. package/dist/shaka-player.ui.debug.externs.js +542 -472
  33. package/dist/shaka-player.ui.debug.js +594 -566
  34. package/dist/shaka-player.ui.debug.map +4 -4
  35. package/dist/shaka-player.ui.externs.js +542 -472
  36. package/dist/shaka-player.ui.js +938 -927
  37. package/dist/shaka-player.ui.map +4 -4
  38. package/docs/tutorials/ui.md +5 -5
  39. package/externs/aria.js +6 -0
  40. package/externs/shaka/ads.js +24 -1
  41. package/externs/shaka/manifest.js +6 -1
  42. package/externs/shaka/offline.js +5 -0
  43. package/externs/shaka/player.js +61 -9
  44. package/externs/shaka/text.js +10 -10
  45. package/externs/texttrack.js +3 -0
  46. package/lib/ads/ad_manager.js +16 -15
  47. package/lib/ads/client_side_ad_manager.js +6 -2
  48. package/lib/ads/server_side_ad_manager.js +19 -2
  49. package/lib/cast/cast_proxy.js +8 -0
  50. package/lib/cast/cast_utils.js +6 -1
  51. package/lib/cea/cea608_data_channel.js +56 -56
  52. package/lib/cea/cea608_memory.js +33 -33
  53. package/lib/cea/cea708_service.js +43 -43
  54. package/lib/cea/cea708_window.js +38 -38
  55. package/lib/cea/cea_decoder.js +13 -14
  56. package/lib/cea/cea_utils.js +23 -23
  57. package/lib/cea/dtvcc_packet_builder.js +7 -7
  58. package/lib/cea/i_caption_decoder.js +2 -3
  59. package/lib/cea/i_cea_parser.js +2 -2
  60. package/lib/cea/mp4_cea_parser.js +6 -6
  61. package/lib/dash/dash_parser.js +5 -0
  62. package/lib/hls/hls_parser.js +159 -12
  63. package/lib/media/closed_caption_parser.js +1 -2
  64. package/lib/media/drm_engine.js +162 -192
  65. package/lib/media/segment_index.js +4 -1
  66. package/lib/media/segment_reference.js +37 -2
  67. package/lib/media/streaming_engine.js +6 -6
  68. package/lib/net/networking_engine.js +1 -0
  69. package/lib/offline/download_manager.js +1 -2
  70. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  71. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  72. package/lib/offline/manifest_converter.js +3 -1
  73. package/lib/offline/storage.js +12 -14
  74. package/lib/player.js +426 -149
  75. package/lib/polyfill/aria.js +82 -0
  76. package/lib/routing/walker.js +2 -3
  77. package/lib/text/srt_text_parser.js +4 -4
  78. package/lib/text/text_engine.js +2 -2
  79. package/lib/text/vtt_text_parser.js +2 -2
  80. package/lib/text/web_vtt_generator.js +55 -12
  81. package/lib/util/error.js +6 -0
  82. package/lib/util/manifest_parser_utils.js +1 -0
  83. package/lib/util/mp4_box_parsers.js +20 -20
  84. package/lib/util/multi_map.js +8 -0
  85. package/lib/util/player_configuration.js +13 -1
  86. package/lib/util/stream_utils.js +168 -88
  87. package/lib/util/xml_utils.js +31 -12
  88. package/package.json +1 -1
  89. package/roadmap.md +24 -22
  90. package/shaka-player.uncompiled.js +1 -0
  91. package/test/cast/cast_utils_unit.js +1 -0
  92. package/test/cea/cea608_memory_unit.js +1 -1
  93. package/test/cea/cea708_service_unit.js +8 -8
  94. package/test/cea/cea708_window_unit.js +6 -6
  95. package/test/cea/cea_decoder_unit.js +1 -1
  96. package/test/cea/dtvcc_packet_builder_unit.js +2 -2
  97. package/test/dash/dash_parser_manifest_unit.js +43 -1
  98. package/test/hls/hls_parser_unit.js +250 -0
  99. package/test/media/drm_engine_integration.js +86 -12
  100. package/test/media/drm_engine_unit.js +310 -450
  101. package/test/offline/manifest_convert_unit.js +2 -0
  102. package/test/offline/storage_integration.js +9 -19
  103. package/test/player_integration.js +85 -0
  104. package/test/player_src_equals_integration.js +85 -0
  105. package/test/player_unit.js +25 -37
  106. package/test/test/assets/chapters.srt +11 -0
  107. package/test/test/assets/chapters.vtt +10 -0
  108. package/test/test/assets/chapters2.vtt +10 -0
  109. package/test/test/util/cea_utils.js +12 -12
  110. package/test/test/util/fake_ad_manager.js +7 -0
  111. package/test/test/util/manifest_generator.js +2 -0
  112. package/test/test/util/manifest_parser_util.js +3 -1
  113. package/test/text/web_vtt_generator_unit.js +81 -7
  114. package/test/util/stream_utils_unit.js +118 -10
  115. package/ui/airplay_button.js +1 -1
  116. package/ui/audio_language_selection.js +2 -5
  117. package/ui/cast_button.js +4 -6
  118. package/ui/constants.js +0 -3
  119. package/ui/fast_forward_button.js +2 -3
  120. package/ui/fullscreen_button.js +1 -3
  121. package/ui/language_utils.js +1 -1
  122. package/ui/loop_button.js +1 -3
  123. package/ui/mute_button.js +1 -3
  124. package/ui/overflow_menu.js +2 -3
  125. package/ui/pip_button.js +5 -7
  126. package/ui/playback_rate_selection.js +3 -6
  127. package/ui/presentation_time.js +1 -3
  128. package/ui/resolution_selection.js +4 -7
  129. package/ui/rewind_button.js +2 -3
  130. package/ui/seek_bar.js +2 -4
  131. package/ui/spacer.js +1 -1
  132. package/ui/text_selection.js +8 -11
  133. package/ui/ui_utils.js +1 -1
  134. package/ui/volume_bar.js +1 -3
@@ -101,6 +101,7 @@ describe('ManifestConverter', () => {
101
101
  audioRobustness: 'very',
102
102
  videoRobustness: 'kinda_sorta',
103
103
  serverCertificate: new Uint8Array([1, 2, 3]),
104
+ serverCertificateUri: '',
104
105
  sessionType: '',
105
106
  initData: [{
106
107
  initData: new Uint8Array([4, 5, 6]),
@@ -316,6 +317,7 @@ describe('ManifestConverter', () => {
316
317
  appendWindowStart: 0,
317
318
  appendWindowEnd: Infinity,
318
319
  timestampOffset: 0,
320
+ tilesLayout: '',
319
321
  };
320
322
 
321
323
  return segment;
@@ -147,15 +147,7 @@ filterDescribe('Storage', storageSupport, () => {
147
147
  }
148
148
  });
149
149
 
150
- for (const useMediaCapabilities of [true, false]) {
151
- const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
152
- filterDescribe('persistent license with MediaCapabilities ' + isEnabled,
153
- drmStorageSupport, () => {
154
- testPersistentLicense(useMediaCapabilities);
155
- });
156
- }
157
-
158
- function testPersistentLicense(useMediaCapabilities) {
150
+ filterDescribe('persistent license', drmStorageSupport, () => {
159
151
  /** @type {!shaka.Player} */
160
152
  let player;
161
153
  /** @type {!shaka.offline.Storage} */
@@ -166,7 +158,6 @@ filterDescribe('Storage', storageSupport, () => {
166
158
  // networking engine. This allows us to use Player.configure in these
167
159
  // tests.
168
160
  player = new shaka.Player();
169
- player.configure({'useMediaCapabilities': useMediaCapabilities});
170
161
  storage = new shaka.offline.Storage(player);
171
162
  });
172
163
 
@@ -201,7 +192,7 @@ filterDescribe('Storage', storageSupport, () => {
201
192
  expect(manifest.offlineSessionIds.length).toBeTruthy();
202
193
 
203
194
  // PART 2 - Check that the licences are stored.
204
- await withDrm(player, manifest, useMediaCapabilities, (drm) => {
195
+ await withDrm(player, manifest, (drm) => {
205
196
  return Promise.all(manifest.offlineSessionIds.map(async (session) => {
206
197
  const foundSession = await loadOfflineSession(drm, session);
207
198
  expect(foundSession).toBeTruthy();
@@ -213,7 +204,7 @@ filterDescribe('Storage', storageSupport, () => {
213
204
  await storage.remove(uri.toString());
214
205
 
215
206
  // PART 4 - Check that the licenses were removed.
216
- const p = withDrm(player, manifest, useMediaCapabilities, (drm) => {
207
+ const p = withDrm(player, manifest, (drm) => {
217
208
  return Promise.all(manifest.offlineSessionIds.map(async (session) => {
218
209
  const notFoundSession = await loadOfflineSession(drm, session);
219
210
  expect(notFoundSession).toBeFalsy();
@@ -257,7 +248,7 @@ filterDescribe('Storage', storageSupport, () => {
257
248
  const storedContents = await storage.list();
258
249
  expect(storedContents).toEqual([]);
259
250
 
260
- await withDrm(player, manifest, useMediaCapabilities, (drm) => {
251
+ await withDrm(player, manifest, (drm) => {
261
252
  return Promise.all(manifest.offlineSessionIds.map(async (session) => {
262
253
  const foundSession = await loadOfflineSession(drm, session);
263
254
  expect(foundSession).toBeTruthy();
@@ -270,7 +261,7 @@ filterDescribe('Storage', storageSupport, () => {
270
261
  expect(didRemoveAll).toBe(true);
271
262
 
272
263
  // PART 6 - Check that the licenses were removed.
273
- const p = withDrm(player, manifest, useMediaCapabilities, (drm) => {
264
+ const p = withDrm(player, manifest, (drm) => {
274
265
  return Promise.all(manifest.offlineSessionIds.map(async (session) => {
275
266
  const notFoundSession = await loadOfflineSession(drm, session);
276
267
  expect(notFoundSession).toBeFalsy();
@@ -282,7 +273,7 @@ filterDescribe('Storage', storageSupport, () => {
282
273
  shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));
283
274
  await expectAsync(p).toBeRejectedWith(expected);
284
275
  });
285
- }
276
+ });
286
277
 
287
278
  describe('default track selection callback', () => {
288
279
  const PlayerConfiguration = shaka.util.PlayerConfiguration;
@@ -1598,6 +1589,7 @@ filterDescribe('Storage', storageSupport, () => {
1598
1589
  keyIds: null,
1599
1590
  sessionType: 'temporary',
1600
1591
  serverCertificate: null,
1592
+ serverCertificateUri: '',
1601
1593
  audioRobustness: 'HARDY',
1602
1594
  videoRobustness: 'OTHER',
1603
1595
  };
@@ -1681,11 +1673,10 @@ filterDescribe('Storage', storageSupport, () => {
1681
1673
  /**
1682
1674
  * @param {!shaka.Player} player
1683
1675
  * @param {shaka.extern.Manifest} manifest
1684
- * @param {boolean} useMediaCapabilities
1685
1676
  * @param {function(!shaka.media.DrmEngine):Promise} action
1686
1677
  * @return {!Promise}
1687
1678
  */
1688
- async function withDrm(player, manifest, useMediaCapabilities, action) {
1679
+ async function withDrm(player, manifest, action) {
1689
1680
  const net = player.getNetworkingEngine();
1690
1681
  goog.asserts.assert(net, 'Player should have a net engine right now');
1691
1682
 
@@ -1703,8 +1694,7 @@ filterDescribe('Storage', storageSupport, () => {
1703
1694
  try {
1704
1695
  drm.configure(player.getConfiguration().drm);
1705
1696
  const variants = manifest.variants;
1706
- await drm.initForStorage(variants, /* usePersistentLicenses= */ true,
1707
- useMediaCapabilities);
1697
+ await drm.initForStorage(variants, /* usePersistentLicenses= */ true);
1708
1698
  await action(drm);
1709
1699
  } finally {
1710
1700
  await drm.destroy();
@@ -959,4 +959,89 @@ describe('Player', () => {
959
959
  }
960
960
  });
961
961
  }); // describe('unloading')
962
+
963
+ describe('chapters', () => {
964
+ it('add external chapters in vtt format', async () => {
965
+ await player.load('test:sintel_no_text_compiled');
966
+ const locationUri = new goog.Uri(location.href);
967
+ const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
968
+ const absoluteUri1 = locationUri.resolve(partialUri1);
969
+ await player.addChaptersTrack(absoluteUri1.toString(), 'en');
970
+
971
+ await shaka.test.Util.delay(1.5);
972
+
973
+ const chapters = player.getChapters('en');
974
+ expect(chapters.length).toBe(3);
975
+ const chapter1 = chapters[0];
976
+ expect(chapter1.title).toBe('Chapter 1');
977
+ expect(chapter1.startTime).toBe(0);
978
+ expect(chapter1.endTime).toBe(5);
979
+ const chapter2 = chapters[1];
980
+ expect(chapter2.title).toBe('Chapter 2');
981
+ expect(chapter2.startTime).toBe(5);
982
+ expect(chapter2.endTime).toBe(10);
983
+ const chapter3 = chapters[2];
984
+ expect(chapter3.title).toBe('Chapter 3');
985
+ expect(chapter3.startTime).toBe(10);
986
+ expect(chapter3.endTime).toBe(20);
987
+
988
+ const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
989
+ const absoluteUri2 = locationUri.resolve(partialUri2);
990
+ await player.addChaptersTrack(absoluteUri2.toString(), 'en');
991
+
992
+ await shaka.test.Util.delay(1.5);
993
+
994
+ const chaptersUpdated = player.getChapters('en');
995
+ expect(chaptersUpdated.length).toBe(6);
996
+ const chapterUpdated1 = chaptersUpdated[0];
997
+ expect(chapterUpdated1.title).toBe('Chapter 1');
998
+ expect(chapterUpdated1.startTime).toBe(0);
999
+ expect(chapterUpdated1.endTime).toBe(5);
1000
+ const chapterUpdated2 = chaptersUpdated[1];
1001
+ expect(chapterUpdated2.title).toBe('Chapter 2');
1002
+ expect(chapterUpdated2.startTime).toBe(5);
1003
+ expect(chapterUpdated2.endTime).toBe(10);
1004
+ const chapterUpdated3 = chaptersUpdated[2];
1005
+ expect(chapterUpdated3.title).toBe('Chapter 3');
1006
+ expect(chapterUpdated3.startTime).toBe(10);
1007
+ expect(chapterUpdated3.endTime).toBe(20);
1008
+ const chapterUpdated4 = chaptersUpdated[3];
1009
+ expect(chapterUpdated4.title).toBe('Chapter 4');
1010
+ expect(chapterUpdated4.startTime).toBe(20);
1011
+ expect(chapterUpdated4.endTime).toBe(30);
1012
+ const chapterUpdated5 = chaptersUpdated[4];
1013
+ expect(chapterUpdated5.title).toBe('Chapter 5');
1014
+ expect(chapterUpdated5.startTime).toBe(30);
1015
+ expect(chapterUpdated5.endTime).toBe(40);
1016
+ const chapterUpdated6 = chaptersUpdated[5];
1017
+ expect(chapterUpdated6.title).toBe('Chapter 6');
1018
+ expect(chapterUpdated6.startTime).toBe(40);
1019
+ expect(chapterUpdated6.endTime).toBe(61.349);
1020
+ });
1021
+
1022
+ it('add external chapters in srt format', async () => {
1023
+ await player.load('test:sintel_no_text_compiled');
1024
+ const locationUri = new goog.Uri(location.href);
1025
+ const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
1026
+ const absoluteUri = locationUri.resolve(partialUri);
1027
+ await player.addChaptersTrack(absoluteUri.toString(), 'es');
1028
+
1029
+ await shaka.test.Util.delay(1.5);
1030
+
1031
+ const chapters = player.getChapters('es');
1032
+ expect(chapters.length).toBe(3);
1033
+ const chapter1 = chapters[0];
1034
+ expect(chapter1.title).toBe('Chapter 1');
1035
+ expect(chapter1.startTime).toBe(0);
1036
+ expect(chapter1.endTime).toBe(5);
1037
+ const chapter2 = chapters[1];
1038
+ expect(chapter2.title).toBe('Chapter 2');
1039
+ expect(chapter2.startTime).toBe(5);
1040
+ expect(chapter2.endTime).toBe(30);
1041
+ const chapter3 = chapters[2];
1042
+ expect(chapter3.title).toBe('Chapter 3');
1043
+ expect(chapter3.startTime).toBe(30);
1044
+ expect(chapter3.endTime).toBe(61.349);
1045
+ });
1046
+ }); // describe('chapters')
962
1047
  });
@@ -326,6 +326,91 @@ describe('Player Src Equals', () => {
326
326
  expect(newTrack).toBeTruthy();
327
327
  });
328
328
 
329
+ it('add external chapters in vtt format', async () => {
330
+ await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
331
+
332
+ const locationUri = new goog.Uri(location.href);
333
+ const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
334
+ const absoluteUri1 = locationUri.resolve(partialUri1);
335
+ await player.addChaptersTrack(absoluteUri1.toString(), 'en');
336
+
337
+ await shaka.test.Util.delay(1.5);
338
+
339
+ const chapters = player.getChapters('en');
340
+ expect(chapters.length).toBe(3);
341
+ const chapter1 = chapters[0];
342
+ expect(chapter1.title).toBe('Chapter 1');
343
+ expect(chapter1.startTime).toBe(0);
344
+ expect(chapter1.endTime).toBe(5);
345
+ const chapter2 = chapters[1];
346
+ expect(chapter2.title).toBe('Chapter 2');
347
+ expect(chapter2.startTime).toBe(5);
348
+ expect(chapter2.endTime).toBe(10);
349
+ const chapter3 = chapters[2];
350
+ expect(chapter3.title).toBe('Chapter 3');
351
+ expect(chapter3.startTime).toBe(10);
352
+ expect(chapter3.endTime).toBe(20);
353
+
354
+ const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
355
+ const absoluteUri2 = locationUri.resolve(partialUri2);
356
+ await player.addChaptersTrack(absoluteUri2.toString(), 'en');
357
+
358
+ await shaka.test.Util.delay(1.5);
359
+
360
+ const chaptersUpdated = player.getChapters('en');
361
+ expect(chaptersUpdated.length).toBe(6);
362
+ const chapterUpdated1 = chaptersUpdated[0];
363
+ expect(chapterUpdated1.title).toBe('Chapter 1');
364
+ expect(chapterUpdated1.startTime).toBe(0);
365
+ expect(chapterUpdated1.endTime).toBe(5);
366
+ const chapterUpdated2 = chaptersUpdated[1];
367
+ expect(chapterUpdated2.title).toBe('Chapter 2');
368
+ expect(chapterUpdated2.startTime).toBe(5);
369
+ expect(chapterUpdated2.endTime).toBe(10);
370
+ const chapterUpdated3 = chaptersUpdated[2];
371
+ expect(chapterUpdated3.title).toBe('Chapter 3');
372
+ expect(chapterUpdated3.startTime).toBe(10);
373
+ expect(chapterUpdated3.endTime).toBe(20);
374
+ const chapterUpdated4 = chaptersUpdated[3];
375
+ expect(chapterUpdated4.title).toBe('Chapter 4');
376
+ expect(chapterUpdated4.startTime).toBe(20);
377
+ expect(chapterUpdated4.endTime).toBe(30);
378
+ const chapterUpdated5 = chaptersUpdated[4];
379
+ expect(chapterUpdated5.title).toBe('Chapter 5');
380
+ expect(chapterUpdated5.startTime).toBe(30);
381
+ expect(chapterUpdated5.endTime).toBe(40);
382
+ const chapterUpdated6 = chaptersUpdated[5];
383
+ expect(chapterUpdated6.title).toBe('Chapter 6');
384
+ expect(chapterUpdated6.startTime).toBe(40);
385
+ expect(chapterUpdated6.endTime).toBe(61.349);
386
+ });
387
+
388
+ it('add external chapters in srt format', async () => {
389
+ await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
390
+
391
+ const locationUri = new goog.Uri(location.href);
392
+ const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
393
+ const absoluteUri = locationUri.resolve(partialUri);
394
+ await player.addChaptersTrack(absoluteUri.toString(), 'es');
395
+
396
+ await shaka.test.Util.delay(1.5);
397
+
398
+ const chapters = player.getChapters('es');
399
+ expect(chapters.length).toBe(3);
400
+ const chapter1 = chapters[0];
401
+ expect(chapter1.title).toBe('Chapter 1');
402
+ expect(chapter1.startTime).toBe(0);
403
+ expect(chapter1.endTime).toBe(5);
404
+ const chapter2 = chapters[1];
405
+ expect(chapter2.title).toBe('Chapter 2');
406
+ expect(chapter2.startTime).toBe(5);
407
+ expect(chapter2.endTime).toBe(30);
408
+ const chapter3 = chapters[2];
409
+ expect(chapter3.title).toBe('Chapter 3');
410
+ expect(chapter3.startTime).toBe(30);
411
+ expect(chapter3.endTime).toBe(61.349);
412
+ });
413
+
329
414
  // Since we are not in-charge of streaming, calling |retryStreaming| should
330
415
  // have no effect.
331
416
  it('requesting streaming retry does nothing', async () => {
@@ -1092,8 +1092,8 @@ describe('Player', () => {
1092
1092
  // Image tracks
1093
1093
  manifest.addImageStream(53, (stream) => {
1094
1094
  stream.originalId = 'thumbnail';
1095
- stream.width = 100;
1096
- stream.height = 200;
1095
+ stream.width = 200;
1096
+ stream.height = 400;
1097
1097
  stream.bandwidth = 10;
1098
1098
  stream.mimeType = 'image/jpeg';
1099
1099
  stream.tilesLayout = '1x1';
@@ -1503,8 +1503,8 @@ describe('Player', () => {
1503
1503
  audioBandwidth: null,
1504
1504
  videoBandwidth: null,
1505
1505
  bandwidth: 10,
1506
- width: 100,
1507
- height: 200,
1506
+ width: 200,
1507
+ height: 400,
1508
1508
  frameRate: null,
1509
1509
  pixelAspectRatio: null,
1510
1510
  hdr: null,
@@ -2809,16 +2809,7 @@ describe('Player', () => {
2809
2809
  expect(tracks[0].id).toBe(4);
2810
2810
  });
2811
2811
 
2812
-
2813
- for (const useMediaCapabilities of [true, false]) {
2814
- const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
2815
- it('removes if key system does not support codec with ' +
2816
- 'MediaCapabilities ' + isEnabled, async () => {
2817
- await testWithUnsupportedCodec(useMediaCapabilities);
2818
- });
2819
- }
2820
-
2821
- async function testWithUnsupportedCodec(useMediaCapabilities) {
2812
+ it('removes if key system does not support codec', async () => {
2822
2813
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
2823
2814
  manifest.addVariant(0, (variant) => {
2824
2815
  variant.addVideo(1, (stream) => {
@@ -2836,35 +2827,22 @@ describe('Player', () => {
2836
2827
  });
2837
2828
  });
2838
2829
 
2839
- if (useMediaCapabilities) {
2840
- navigator.mediaCapabilities.decodingInfo = async (config) => {
2841
- await Promise.resolve();
2842
- const videoType = config['video'] ? config['video'].contentType : '';
2843
- if (videoType.includes('video') &&
2830
+ navigator.mediaCapabilities.decodingInfo = async (config) => {
2831
+ await Promise.resolve();
2832
+ const videoType = config['video'] ? config['video'].contentType : '';
2833
+ if (videoType.includes('video') &&
2844
2834
  videoType.includes('unsupported')) {
2845
- return {supported: false};
2846
- } else {
2847
- return {supported: true};
2848
- }
2849
- };
2850
- } else {
2851
- // We must be careful that our video/unsupported was not filtered out
2852
- // because of MSE support. We are specifically testing EME-based
2853
- // filtering of codecs.
2854
- expect(MediaSource.isTypeSupported('video/unsupported')).toBe(true);
2855
- // Make sure that drm engine will reject the variant with an unsupported
2856
- // video mime type.
2857
- drmEngine.supportsVariant.and.callFake((variant) => {
2858
- return variant.video.codecs != 'unsupported';
2859
- });
2860
- }
2835
+ return {supported: false};
2836
+ } else {
2837
+ return {supported: true};
2838
+ }
2839
+ };
2861
2840
 
2862
- player.configure({useMediaCapabilities: useMediaCapabilities});
2863
2841
  await player.load(fakeManifestUri, 0, fakeMimeType);
2864
2842
  const tracks = player.getVariantTracks();
2865
2843
  expect(tracks.length).toBe(1);
2866
2844
  expect(tracks[0].id).toBe(1);
2867
- }
2845
+ });
2868
2846
 
2869
2847
  it('removes based on bandwidth', async () => {
2870
2848
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
@@ -3559,29 +3537,39 @@ describe('Player', () => {
3559
3537
 
3560
3538
  await player.load(fakeManifestUri, 0, fakeMimeType);
3561
3539
 
3540
+ expect(player.getImageTracks()[0].width).toBe(100);
3541
+ expect(player.getImageTracks()[0].height).toBe(50);
3562
3542
  const thumbnail0 = await player.getThumbnails(5, 0);
3563
3543
  const thumbnail1 = await player.getThumbnails(5, 11);
3564
3544
  const thumbnail2 = await player.getThumbnails(5, 21);
3565
3545
  const thumbnail5 = await player.getThumbnails(5, 51);
3566
3546
  expect(thumbnail0).toEqual(jasmine.objectContaining({
3547
+ imageHeight: 150,
3548
+ imageWidth: 200,
3567
3549
  positionX: 0,
3568
3550
  positionY: 0,
3569
3551
  width: 100,
3570
3552
  height: 50,
3571
3553
  }));
3572
3554
  expect(thumbnail1).toEqual(jasmine.objectContaining({
3555
+ imageHeight: 150,
3556
+ imageWidth: 200,
3573
3557
  positionX: 100,
3574
3558
  positionY: 0,
3575
3559
  width: 100,
3576
3560
  height: 50,
3577
3561
  }));
3578
3562
  expect(thumbnail2).toEqual(jasmine.objectContaining({
3563
+ imageHeight: 150,
3564
+ imageWidth: 200,
3579
3565
  positionX: 0,
3580
3566
  positionY: 50,
3581
3567
  width: 100,
3582
3568
  height: 50,
3583
3569
  }));
3584
3570
  expect(thumbnail5).toEqual(jasmine.objectContaining({
3571
+ imageHeight: 150,
3572
+ imageWidth: 200,
3585
3573
  positionX: 100,
3586
3574
  positionY: 100,
3587
3575
  width: 100,
@@ -0,0 +1,11 @@
1
+ 1
2
+ 00:00,000 --> 00:05,000
3
+ Chapter 1
4
+
5
+ 2
6
+ 00:05,000 --> 00:30,000
7
+ Chapter 2
8
+
9
+ 3
10
+ 00:30,000 --> 01:01,349
11
+ Chapter 3
@@ -0,0 +1,10 @@
1
+ WEBVTT
2
+
3
+ 00:00.000 --> 00:05.000
4
+ Chapter 1
5
+
6
+ 00:05.000 --> 00:10.000
7
+ Chapter 2
8
+
9
+ 00:10.000 --> 00:20.000
10
+ Chapter 3
@@ -0,0 +1,10 @@
1
+ WEBVTT
2
+
3
+ 00:20.000 --> 00:30.000
4
+ Chapter 4
5
+
6
+ 00:30.000 --> 00:40.000
7
+ Chapter 5
8
+
9
+ 00:40.000 --> 01:01.349
10
+ Chapter 6
@@ -16,9 +16,9 @@ goog.require('shaka.text.Cue');
16
16
  shaka.test.CeaUtils = class {
17
17
  /**
18
18
  * Returns a cue with no underline/italics, and default colors
19
- * @param {!number} startTime
20
- * @param {!number} endTime
21
- * @param {!string} payload
19
+ * @param {number} startTime
20
+ * @param {number} endTime
21
+ * @param {string} payload
22
22
  */
23
23
  static createDefaultCue(startTime, endTime, payload) {
24
24
  const cue = new shaka.text.Cue(startTime, endTime, payload);
@@ -29,13 +29,13 @@ shaka.test.CeaUtils = class {
29
29
 
30
30
  /**
31
31
  * Returns a cue with custom underline, italics, color, background color.
32
- * @param {!number} startTime
33
- * @param {!number} endTime
34
- * @param {!string} payload
35
- * @param {!boolean} underline
36
- * @param {!boolean} italics
37
- * @param {!string} textColor
38
- * @param {!string} backgroundColor
32
+ * @param {number} startTime
33
+ * @param {number} endTime
34
+ * @param {string} payload
35
+ * @param {boolean} underline
36
+ * @param {boolean} italics
37
+ * @param {string} textColor
38
+ * @param {string} backgroundColor
39
39
  * @return {!shaka.text.Cue}
40
40
  */
41
41
  static createStyledCue(startTime, endTime, payload, underline,
@@ -54,8 +54,8 @@ shaka.test.CeaUtils = class {
54
54
 
55
55
  /**
56
56
  * Returns a cue that corresponds to a linebreak.
57
- * @param {!number} startTime
58
- * @param {!number} endTime
57
+ * @param {number} startTime
58
+ * @param {number} endTime
59
59
  * @return {!shaka.text.Cue}
60
60
  */
61
61
  static createLineBreakCue(startTime, endTime) {
@@ -53,6 +53,13 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
53
53
  /** @override */
54
54
  replaceServerSideAdTagParameters(adTagParameters) {}
55
55
 
56
+ /**
57
+ * @override
58
+ */
59
+ getServerSideCuePoints() {
60
+ return [];
61
+ }
62
+
56
63
  /** @override */
57
64
  getStats() {
58
65
  return this.stats_;
@@ -407,6 +407,8 @@ shaka.test.ManifestGenerator.DrmInfo = class {
407
407
  this.keyIds = new Set();
408
408
  /** @type {string} */
409
409
  this.sessionType = '';
410
+ /** @type {string} */
411
+ this.serverCertificateUri = '';
410
412
 
411
413
  /** @type {shaka.extern.DrmInfo} */
412
414
  const foo = this;
@@ -56,11 +56,12 @@ shaka.test.ManifestParser = class {
56
56
  * @param {?number=} endByte
57
57
  * @param {number=} timestampOffset
58
58
  * @param {!Array.<!shaka.media.SegmentReference>=} partialReferences
59
+ * @param {?string=} tilesLayout
59
60
  * @return {!shaka.media.SegmentReference}
60
61
  */
61
62
  static makeReference(uri, start, end, baseUri = '',
62
63
  startByte = 0, endByte = null, timestampOffset = 0,
63
- partialReferences = []) {
64
+ partialReferences = [], tilesLayout = '') {
64
65
  const getUris = () => uri.length ? [baseUri + uri] : [];
65
66
 
66
67
  // If a test wants to verify these, they can be set explicitly after
@@ -84,6 +85,7 @@ shaka.test.ManifestParser = class {
84
85
  appendWindowStart,
85
86
  appendWindowEnd,
86
87
  partialReferences,
88
+ tilesLayout,
87
89
  );
88
90
  }
89
91
  };
@@ -9,23 +9,45 @@ goog.require('shaka.text.WebVttGenerator');
9
9
 
10
10
  describe('WebVttGenerator', () => {
11
11
  it('supports no cues', () => {
12
- verifyHelper([], 'WEBVTT\n\n');
12
+ verifyHelper([], [], 'WEBVTT\n\n');
13
13
  });
14
14
 
15
15
  it('convert cues to WebVTT', () => {
16
16
  const shakaCue1 = new shaka.text.Cue(20, 40, 'Test');
17
+ shakaCue1.textAlign = shaka.text.Cue.textAlign.LEFT;
18
+ shakaCue1.writingMode = shaka.text.Cue.writingMode.VERTICAL_LEFT_TO_RIGHT;
17
19
  const shakaCue2 = new shaka.text.Cue(40, 50, 'Test2');
20
+ shakaCue2.textAlign = shaka.text.Cue.textAlign.RIGHT;
21
+ shakaCue2.writingMode = shaka.text.Cue.writingMode.VERTICAL_RIGHT_TO_LEFT;
22
+ const shakaCue3 = new shaka.text.Cue(50, 51, 'Test3');
23
+ shakaCue3.textAlign = shaka.text.Cue.textAlign.CENTER;
24
+ const shakaCue4 = new shaka.text.Cue(52, 53, 'Test4');
25
+ shakaCue4.textAlign = shaka.text.Cue.textAlign.START;
26
+ const shakaCue5 = new shaka.text.Cue(53, 54, 'Test5');
27
+ shakaCue5.textAlign = shaka.text.Cue.textAlign.END;
28
+
29
+ const adCuePoints = [];
18
30
 
19
31
  verifyHelper(
20
32
  [
21
33
  shakaCue1,
22
34
  shakaCue2,
35
+ shakaCue3,
36
+ shakaCue4,
37
+ shakaCue5,
23
38
  ],
39
+ adCuePoints,
24
40
  'WEBVTT\n\n' +
25
- '00:00:20.000 --> 00:00:40.000\n' +
41
+ '00:00:20.000 --> 00:00:40.000 align:left vertical:lr\n' +
26
42
  'Test\n\n' +
27
- '00:00:40.000 --> 00:00:50.000\n' +
28
- 'Test2\n\n');
43
+ '00:00:40.000 --> 00:00:50.000 align:right vertical:rl\n' +
44
+ 'Test2\n\n' +
45
+ '00:00:50.000 --> 00:00:51.000 align:middle\n' +
46
+ 'Test3\n\n' +
47
+ '00:00:52.000 --> 00:00:53.000 align:start\n' +
48
+ 'Test4\n\n' +
49
+ '00:00:53.000 --> 00:00:54.000 align:end\n' +
50
+ 'Test5\n\n');
29
51
  });
30
52
 
31
53
  it('creates style tags for cues with underline/italics/bold', () => {
@@ -49,19 +71,71 @@ describe('WebVttGenerator', () => {
49
71
  nestedCue4.textDecoration.push(shaka.text.Cue.textDecoration.UNDERLINE);
50
72
 
51
73
  shakaCue.nestedCues = [nestedCue1, nestedCue2, nestedCue3, nestedCue4];
74
+
75
+ const adCuePoints = [];
76
+
52
77
  verifyHelper(
53
78
  [shakaCue],
79
+ adCuePoints,
54
80
  'WEBVTT\n\n' +
55
- '00:00:10.000 --> 00:00:20.000\n' +
81
+ '00:00:10.000 --> 00:00:20.000 align:middle\n' +
56
82
  '<i><u>Test1</u></i><b><i>Test2</i></b>Test3<u>Test4</u>\n\n');
57
83
  });
58
84
 
85
+ it('computes the time with ad cue points', () => {
86
+ const shakaCue1 = new shaka.text.Cue(20, 30, 'Test');
87
+ shakaCue1.textAlign = shaka.text.Cue.textAlign.LEFT;
88
+ shakaCue1.writingMode = shaka.text.Cue.writingMode.VERTICAL_LEFT_TO_RIGHT;
89
+ const shakaCue2 = new shaka.text.Cue(40, 50, 'Test2');
90
+ shakaCue2.textAlign = shaka.text.Cue.textAlign.RIGHT;
91
+ shakaCue2.writingMode = shaka.text.Cue.writingMode.VERTICAL_RIGHT_TO_LEFT;
92
+ const shakaCue3 = new shaka.text.Cue(50, 51, 'Test3');
93
+ shakaCue3.textAlign = shaka.text.Cue.textAlign.CENTER;
94
+ const shakaCue4 = new shaka.text.Cue(52, 53, 'Test4');
95
+ shakaCue4.textAlign = shaka.text.Cue.textAlign.START;
96
+ const shakaCue5 = new shaka.text.Cue(53, 54, 'Test5');
97
+ shakaCue5.textAlign = shaka.text.Cue.textAlign.END;
98
+
99
+ const adCuePoints = [
100
+ {
101
+ start: 0,
102
+ end: 10,
103
+ },
104
+ {
105
+ start: 35,
106
+ end: 45,
107
+ },
108
+ ];
109
+
110
+ verifyHelper(
111
+ [
112
+ shakaCue1,
113
+ shakaCue2,
114
+ shakaCue3,
115
+ shakaCue4,
116
+ shakaCue5,
117
+ ],
118
+ adCuePoints,
119
+ 'WEBVTT\n\n' +
120
+ '00:00:30.000 --> 00:00:40.000 align:left vertical:lr\n' +
121
+ 'Test\n\n' +
122
+ '00:01:00.000 --> 00:01:10.000 align:right vertical:rl\n' +
123
+ 'Test2\n\n' +
124
+ '00:01:10.000 --> 00:01:11.000 align:middle\n' +
125
+ 'Test3\n\n' +
126
+ '00:01:12.000 --> 00:01:13.000 align:start\n' +
127
+ 'Test4\n\n' +
128
+ '00:01:13.000 --> 00:01:14.000 align:end\n' +
129
+ 'Test5\n\n');
130
+ });
131
+
59
132
  /**
60
133
  * @param {!Array} cues
134
+ * @param {!Array} adCuePoints
61
135
  * @param {string} text
62
136
  */
63
- function verifyHelper(cues, text) {
64
- const result = shaka.text.WebVttGenerator.convert(cues);
137
+ function verifyHelper(cues, adCuePoints, text) {
138
+ const result = shaka.text.WebVttGenerator.convert(cues, adCuePoints);
65
139
  expect(text).toBe(result);
66
140
  }
67
141
  });