shaka-player 4.3.5 → 4.3.7

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 (102) hide show
  1. package/.github/workflows/demo-version-index.yaml +3 -3
  2. package/.github/workflows/selenium-lab-tests.yaml +23 -1
  3. package/AUTHORS +2 -1
  4. package/CHANGELOG.md +53 -0
  5. package/CONTRIBUTORS +4 -1
  6. package/README.md +3 -0
  7. package/demo/demo.less +1 -0
  8. package/dist/controls.css +2 -2
  9. package/dist/controls.css.map +1 -1
  10. package/dist/demo.compiled.debug.js +167 -296
  11. package/dist/demo.compiled.debug.map +4 -4
  12. package/dist/demo.compiled.js +167 -296
  13. package/dist/demo.compiled.map +4 -4
  14. package/dist/demo.css +1 -1
  15. package/dist/demo.css.map +1 -1
  16. package/dist/deps.js +1 -1
  17. package/dist/locales.js +32 -32
  18. package/dist/receiver.compiled.debug.js +34 -63
  19. package/dist/receiver.compiled.debug.map +4 -4
  20. package/dist/receiver.compiled.js +34 -63
  21. package/dist/receiver.compiled.map +4 -4
  22. package/dist/shaka-player.compiled.d.ts +20 -3
  23. package/dist/shaka-player.compiled.debug.d.ts +20 -3
  24. package/dist/shaka-player.compiled.debug.externs.js +29 -14
  25. package/dist/shaka-player.compiled.debug.js +303 -292
  26. package/dist/shaka-player.compiled.debug.map +4 -4
  27. package/dist/shaka-player.compiled.externs.js +29 -14
  28. package/dist/shaka-player.compiled.js +886 -879
  29. package/dist/shaka-player.compiled.map +3 -3
  30. package/dist/shaka-player.ui.d.ts +20 -3
  31. package/dist/shaka-player.ui.debug.d.ts +20 -3
  32. package/dist/shaka-player.ui.debug.externs.js +17 -2
  33. package/dist/shaka-player.ui.debug.js +321 -309
  34. package/dist/shaka-player.ui.debug.map +3 -3
  35. package/dist/shaka-player.ui.externs.js +17 -2
  36. package/dist/shaka-player.ui.js +1027 -1021
  37. package/dist/shaka-player.ui.map +3 -3
  38. package/docs/tutorials/a11y.md +0 -4
  39. package/docs/tutorials/ad_monetization.md +0 -4
  40. package/docs/tutorials/basic-usage.md +0 -5
  41. package/docs/tutorials/config.md +0 -5
  42. package/docs/tutorials/debugging.md +0 -5
  43. package/docs/tutorials/drm-config.md +0 -5
  44. package/docs/tutorials/fairplay.md +2 -2
  45. package/docs/tutorials/license-server-auth.md +0 -5
  46. package/docs/tutorials/license-wrapping.md +0 -5
  47. package/docs/tutorials/network-and-buffering-config.md +0 -5
  48. package/docs/tutorials/ui-customization.md +0 -5
  49. package/docs/tutorials/ui.md +0 -7
  50. package/docs/tutorials/welcome.md +1 -6
  51. package/externs/network_information.js +7 -2
  52. package/externs/shaka/abr_manager.js +6 -0
  53. package/externs/shaka/net.js +1 -0
  54. package/externs/shaka/player.js +13 -7
  55. package/lib/abr/simple_abr_manager.js +27 -3
  56. package/lib/ads/client_side_ad_manager.js +6 -3
  57. package/lib/cea/mp4_cea_parser.js +5 -2
  58. package/lib/dash/dash_parser.js +49 -48
  59. package/lib/debug/log.js +9 -13
  60. package/lib/hls/hls_parser.js +60 -7
  61. package/lib/hls/manifest_text_parser.js +10 -1
  62. package/lib/media/drm_engine.js +9 -6
  63. package/lib/media/media_source_engine.js +33 -13
  64. package/lib/media/presentation_timeline.js +9 -2
  65. package/lib/media/segment_index.js +2 -0
  66. package/lib/media/segment_reference.js +25 -2
  67. package/lib/media/streaming_engine.js +40 -11
  68. package/lib/net/http_fetch_plugin.js +79 -57
  69. package/lib/net/networking_engine.js +1 -0
  70. package/lib/player.js +26 -3
  71. package/lib/polyfill/media_capabilities.js +13 -0
  72. package/lib/text/mp4_vtt_parser.js +4 -0
  73. package/lib/text/text_engine.js +1 -0
  74. package/lib/util/manifest_parser_utils.js +1 -2
  75. package/lib/util/mime_utils.js +11 -0
  76. package/lib/util/periods.js +5 -5
  77. package/lib/util/stream_utils.js +2 -2
  78. package/maintained-branches.md +2 -3
  79. package/package.json +8 -3
  80. package/test/cea/mp4_cea_parser_unit.js +19 -0
  81. package/test/dash/dash_parser_live_unit.js +3 -2
  82. package/test/hls/hls_live_unit.js +3 -1
  83. package/test/hls/hls_parser_unit.js +156 -0
  84. package/test/media/content_workarounds_unit.js +43 -0
  85. package/test/media/drm_engine_integration.js +4 -17
  86. package/test/media/media_source_engine_unit.js +30 -0
  87. package/test/media/streaming_engine_unit.js +6 -1
  88. package/test/net/networking_engine_unit.js +6 -1
  89. package/test/player_integration.js +39 -0
  90. package/test/player_unit.js +57 -0
  91. package/test/polyfill/media_capabilities_unit.js +1 -0
  92. package/test/test/assets/h265-cea-init.mp4 +0 -0
  93. package/test/test/assets/h265-cea-segment.mp4 +0 -0
  94. package/test/test/assets/text-clip-alt.vtt +63 -0
  95. package/test/test/util/fake_drm_engine.js +3 -0
  96. package/test/test/util/fake_media_source_engine.js +4 -0
  97. package/test/test/util/layout_tests.js +4 -3
  98. package/test/test/util/simple_fakes.js +6 -0
  99. package/test/test/util/test_scheme.js +9 -14
  100. package/test/text/mp4_vtt_parser_unit.js +8 -0
  101. package/test/util/mime_utils_unit.js +10 -0
  102. package/ui/less/containers.less +4 -0
@@ -0,0 +1,43 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ describe('ContentWorkarounds', () => {
8
+ const encryptionBoxes = {
9
+ 'encv': ['hev1', 'hvc1', 'avc1', 'avc3'],
10
+ 'enca': ['ac-3', 'ec-3', 'mp4a'],
11
+ };
12
+ for (const encryptionBox of Object.keys(encryptionBoxes)) {
13
+ for (const box of encryptionBoxes[encryptionBox]) {
14
+ it(`adds ${encryptionBox} box for ${box}`, () => {
15
+ const boxType = [];
16
+ for (const char of box) {
17
+ boxType.push(char.charCodeAt(0));
18
+ }
19
+ const unencrypted = new Uint8Array([
20
+ 0x00, 0x00, 0x00, 0x20, // size
21
+ 0x73, 0x74, 0x73, 0x64, // stsd
22
+ 0x01, // version
23
+ 0x12, 0x34, 0x56, // flags
24
+ 0x00, 0x00, 0x00, 0x01, // count
25
+ 0x00, 0x00, 0x00, 0x10, // size
26
+ ...boxType, // box type
27
+ 0x01, // version
28
+ 0x12, 0x34, 0x56, // flags
29
+ 0x00, 0x11, 0x22, 0x33, // payload
30
+ ]);
31
+
32
+ const faked =
33
+ shaka.media.ContentWorkarounds.fakeEncryption(unencrypted);
34
+ const spy = jasmine.createSpy('boxCallback');
35
+ new shaka.util.Mp4Parser()
36
+ .fullBox('stsd', shaka.util.Mp4Parser.sampleDescription)
37
+ .box(encryptionBox, /** @type {!Function} */ (spy))
38
+ .parse(faked);
39
+ expect(spy).toHaveBeenCalled();
40
+ });
41
+ }
42
+ }
43
+ });
@@ -74,19 +74,6 @@ describe('DrmEngine', () => {
74
74
  onEventSpy = jasmine.createSpy('onEvent');
75
75
 
76
76
  networkingEngine = new shaka.net.NetworkingEngine();
77
- networkingEngine.registerRequestFilter((type, request) => {
78
- if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
79
- return;
80
- }
81
-
82
- request.headers['X-AxDRM-Message'] = [
83
- 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lk',
84
- 'IjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc2FnZSI6e',
85
- 'yJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiNmU1YTFkMj',
86
- 'YtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflOPv9qHnu3ZWJNZ12j',
87
- 'gkqTabmwXbDWk_47tLNE',
88
- ].join('');
89
- });
90
77
 
91
78
  const playerInterface = {
92
79
  netEngine: networkingEngine,
@@ -99,22 +86,22 @@ describe('DrmEngine', () => {
99
86
  drmEngine = new shaka.media.DrmEngine(playerInterface);
100
87
  const config = shaka.util.PlayerConfiguration.createDefault().drm;
101
88
  config.servers['com.widevine.alpha'] =
102
- 'https://drm-widevine-licensing.axtest.net/AcquireLicense';
89
+ 'https://cwip-shaka-proxy.appspot.com/specific_key?blodJidXR9eARuql0dNLWg=GX8m9XLIZNIzizrl0RTqnA';
103
90
  config.servers['com.microsoft.playready'] =
104
- 'https://drm-playready-licensing.axtest.net/AcquireLicense';
91
+ 'https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(kid:6e5a1d26-2757-47d7-8046-eaa5d1d34b5a,contentkey:GX8m9XLIZNIzizrl0RTqnA==,sl:150)';
105
92
  drmEngine.configure(config);
106
93
 
107
94
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
108
95
  manifest.addVariant(0, (variant) => {
109
96
  variant.addVideo(1, (stream) => {
110
97
  stream.encrypted = true;
111
- stream.addDrmInfo('com.widevine.alpha');
112
98
  stream.addDrmInfo('com.microsoft.playready');
99
+ stream.addDrmInfo('com.widevine.alpha');
113
100
  });
114
101
  variant.addAudio(2, (stream) => {
115
102
  stream.encrypted = true;
116
- stream.addDrmInfo('com.widevine.alpha');
117
103
  stream.addDrmInfo('com.microsoft.playready');
104
+ stream.addDrmInfo('com.widevine.alpha');
118
105
  });
119
106
  });
120
107
  });
@@ -171,9 +171,12 @@ describe('MediaSourceEngine', () => {
171
171
  describe('constructor', () => {
172
172
  const originalCreateObjectURL =
173
173
  shaka.media.MediaSourceEngine.createObjectURL;
174
+ const originalRevokeObjectURL = window.URL.revokeObjectURL;
174
175
  const originalMediaSource = window.MediaSource;
175
176
  /** @type {jasmine.Spy} */
176
177
  let createObjectURLSpy;
178
+ /** @type {jasmine.Spy} */
179
+ let revokeObjectURLSpy;
177
180
 
178
181
  beforeEach(async () => {
179
182
  // Mock out MediaSource so we can test the production version of
@@ -188,6 +191,9 @@ describe('MediaSourceEngine', () => {
188
191
  shaka.media.MediaSourceEngine.createObjectURL =
189
192
  Util.spyFunc(createObjectURLSpy);
190
193
 
194
+ revokeObjectURLSpy = jasmine.createSpy('revokeObjectURL');
195
+ window.URL.revokeObjectURL = Util.spyFunc(revokeObjectURLSpy);
196
+
191
197
  const mediaSourceSpy = jasmine.createSpy('MediaSource');
192
198
  // Because this is a fake constructor, it must be callable with "new".
193
199
  // This will cause jasmine to invoke the callback with "new" as well, so
@@ -205,6 +211,7 @@ describe('MediaSourceEngine', () => {
205
211
  afterAll(() => {
206
212
  shaka.media.MediaSourceEngine.createObjectURL = originalCreateObjectURL;
207
213
  window.MediaSource = originalMediaSource;
214
+ window.URL.revokeObjectURL = originalRevokeObjectURL;
208
215
  });
209
216
 
210
217
  it('creates a MediaSource object and sets video.src', () => {
@@ -216,6 +223,29 @@ describe('MediaSourceEngine', () => {
216
223
  expect(createObjectURLSpy).toHaveBeenCalled();
217
224
  expect(mockVideo.src).toBe('blob:foo');
218
225
  });
226
+
227
+ it('revokes object URL after MediaSource opens', () => {
228
+ let onSourceOpenListener;
229
+
230
+ mockMediaSource.addEventListener.and.callFake((event, callback, _) => {
231
+ if (event == 'sourceopen') {
232
+ onSourceOpenListener = callback;
233
+ }
234
+ });
235
+
236
+ mediaSourceEngine = new shaka.media.MediaSourceEngine(
237
+ video,
238
+ new shaka.test.FakeTextDisplayer());
239
+
240
+ expect(mockMediaSource.addEventListener).toHaveBeenCalledTimes(1);
241
+ expect(mockMediaSource.addEventListener.calls.mostRecent().args[0])
242
+ .toBe('sourceopen');
243
+ expect(typeof onSourceOpenListener).toBe(typeof Function);
244
+
245
+ onSourceOpenListener();
246
+
247
+ expect(revokeObjectURLSpy).toHaveBeenCalledWith('blob:foo');
248
+ });
219
249
  });
220
250
 
221
251
  describe('init', () => {
@@ -3412,7 +3412,12 @@ describe('StreamingEngine', () => {
3412
3412
  netEngine.request.and.callFake((requestType, request) => {
3413
3413
  const buffer = new ArrayBuffer(0);
3414
3414
  /** @type {shaka.extern.Response} */
3415
- const response = {uri: request.uris[0], data: buffer, headers: {}};
3415
+ const response = {
3416
+ uri: request.uris[0],
3417
+ originalUri: request.uris[0],
3418
+ data: buffer,
3419
+ headers: {},
3420
+ };
3416
3421
  return shaka.util.AbortableOperation.completed(response);
3417
3422
  });
3418
3423
 
@@ -1226,6 +1226,11 @@ describe('NetworkingEngine', /** @suppress {accessControls} */ () => {
1226
1226
 
1227
1227
  /** @return {shaka.extern.Response} */
1228
1228
  function createResponse() {
1229
- return {uri: '', data: new ArrayBuffer(5), headers: {}};
1229
+ return {
1230
+ uri: '',
1231
+ originalUri: '',
1232
+ data: new ArrayBuffer(5),
1233
+ headers: {},
1234
+ };
1230
1235
  }
1231
1236
  }); // describe('NetworkingEngine')
@@ -319,6 +319,45 @@ describe('Player', () => {
319
319
  player.setTextTrackVisibility(true);
320
320
  expect(getTracksActive()).toEqual([false, true]);
321
321
  });
322
+
323
+ // https://github.com/shaka-project/shaka-player/issues/4821
324
+ it('loads a single text stream', async () => {
325
+ player.configure({preferredTextLanguage: 'en'});
326
+ await player.load('test:sintel_no_text_compiled');
327
+
328
+ // Add preferred language text track.
329
+ const locationUri = new goog.Uri(location.href);
330
+ const partialUri = new goog.Uri('/base/test/test/assets/text-clip.vtt');
331
+ const absoluteUri = locationUri.resolve(partialUri);
332
+ await player.addTextTrackAsync(
333
+ absoluteUri.toString(), 'en', 'subtitles', 'text/vtt');
334
+
335
+ // Add alternate language text track.
336
+ // Two text tracks with same timings but different text
337
+ // are necessary for test.
338
+ const partialUri2 =
339
+ new goog.Uri('/base/test/test/assets/text-clip-alt.vtt');
340
+ const absoluteUri2 = locationUri.resolve(partialUri2);
341
+ await player.addTextTrackAsync(
342
+ absoluteUri2.toString(), 'fr', 'subtitles', 'text/vtt');
343
+
344
+ const textTracks = player.getTextTracks();
345
+ expect(textTracks.length).toBe(2);
346
+ expect(textTracks[0].language).toBe('en');
347
+ expect(textTracks[1].language).toBe('fr');
348
+
349
+ // Enable text visibilty and immediately change language.
350
+ // Only one set of cues should be active.
351
+ // Cues should be of the selected language track.
352
+ player.setTextTrackVisibility(true);
353
+ player.selectTextLanguage('fr');
354
+ video.currentTime = 5;
355
+ video.play();
356
+ await waiter.waitForMovementOrFailOnTimeout(video, 10);
357
+
358
+ expect(video.textTracks[0].activeCues.length).toBe(1);
359
+ expect(player.getTextTracks()[1].active).toBe(true);
360
+ });
322
361
  }); // describe('setTextTrackVisibility')
323
362
 
324
363
  describe('autoShowText', () => {
@@ -208,6 +208,7 @@ describe('Player', () => {
208
208
  await player.destroy();
209
209
 
210
210
  expect(abrManager.stop).toHaveBeenCalled();
211
+ expect(abrManager.release).toHaveBeenCalled();
211
212
  expect(networkingEngine.destroy).toHaveBeenCalled();
212
213
  expect(drmEngine.destroy).toHaveBeenCalled();
213
214
  expect(playhead.release).toHaveBeenCalled();
@@ -246,6 +247,7 @@ describe('Player', () => {
246
247
  parser.start.and.returnValue(p);
247
248
  parser.stop.and.callFake(() => {
248
249
  expect(abrManager.stop).not.toHaveBeenCalled();
250
+ expect(abrManager.release).not.toHaveBeenCalled();
249
251
  expect(networkingEngine.destroy).not.toHaveBeenCalled();
250
252
  });
251
253
  shaka.media.ManifestParser.registerParserByMime(
@@ -255,6 +257,7 @@ describe('Player', () => {
255
257
  await shaka.test.Util.shortDelay();
256
258
  await player.destroy();
257
259
  expect(abrManager.stop).toHaveBeenCalled();
260
+ expect(abrManager.release).toHaveBeenCalled();
258
261
  expect(networkingEngine.destroy).toHaveBeenCalled();
259
262
  expect(parser.stop).toHaveBeenCalled();
260
263
  await expectAsync(load).toBeRejected();
@@ -554,6 +557,60 @@ describe('Player', () => {
554
557
  expect(streamingEngine.unloadTextStream).not.toHaveBeenCalled();
555
558
  });
556
559
  });
560
+
561
+ describe('when config.streaming.preferNativeHls is set to true', () => {
562
+ beforeEach(() => {
563
+ shaka.media.ManifestParser.registerParserByMime(
564
+ 'application/x-mpegurl',
565
+ () => new shaka.test.FakeManifestParser(manifest));
566
+ });
567
+
568
+ afterEach(() => {
569
+ shaka.media.ManifestParser.unregisterParserByMime(
570
+ 'application/x-mpegurl');
571
+ video.canPlayType.calls.reset();
572
+ });
573
+
574
+ it('only applies to HLS streams', async () => {
575
+ video.canPlayType.and.returnValue('maybe');
576
+ spyOn(shaka.util.Platform, 'anyMediaElement').and.returnValue(video);
577
+ spyOn(shaka.util.Platform, 'supportsMediaSource').and.returnValue(true);
578
+ spyOn(shaka.util.Platform, 'isApple').and.returnValue(false);
579
+ // Make sure player.load() resolves for src=
580
+ spyOn(shaka.util.MediaReadyState, 'waitForReadyState').and.callFake(
581
+ (mediaElement, readyState, eventManager, callback) => {
582
+ callback();
583
+ });
584
+
585
+ player.configure({
586
+ streaming: {
587
+ preferNativeHls: true,
588
+ useNativeHlsOnSafari: false,
589
+ },
590
+ });
591
+
592
+ await player.load(fakeManifestUri, undefined, 'application/x-mpegurl');
593
+
594
+ expect(player.getLoadMode()).toBe(shaka.Player.LoadMode.SRC_EQUALS);
595
+ });
596
+
597
+ it('does not apply to non-HLS streams', async () => {
598
+ video.canPlayType.and.returnValue('maybe');
599
+ spyOn(shaka.util.Platform, 'supportsMediaSource').and.returnValue(true);
600
+ spyOn(shaka.util.Platform, 'isApple').and.returnValue(false);
601
+
602
+ player.configure({
603
+ streaming: {
604
+ preferNativeHls: true,
605
+ useNativeHlsOnSafari: false,
606
+ },
607
+ });
608
+
609
+ await player.load(fakeManifestUri, 0, fakeMimeType);
610
+
611
+ expect(player.getLoadMode()).toBe(shaka.Player.LoadMode.MEDIA_SOURCE);
612
+ });
613
+ });
557
614
  }); // describe('load/unload')
558
615
 
559
616
  describe('getConfiguration', () => {
@@ -69,6 +69,7 @@ describe('MediaCapabilities', () => {
69
69
  },
70
70
  };
71
71
  shaka.polyfill.MediaCapabilities.memoizedMediaKeySystemAccessRequests_ = {};
72
+ supportMap.clear();
72
73
 
73
74
  mockCanDisplayType = jasmine.createSpy('canDisplayType');
74
75
  mockCanDisplayType.and.returnValue(false);
@@ -0,0 +1,63 @@
1
+ WEBVTT
2
+
3
+ 00:04.000 --> 00:07.300
4
+ Journal de bord du capitaine.
5
+ Date stellaire 41636.9.
6
+
7
+ 00:07.500 --> 00:11.800
8
+ Comme nous le craignions, l'épave
9
+ du cargo Odin de la Fédération,
10
+
11
+ 00:12.100 --> 00:16.400
12
+ percuté par un astéroïde,
13
+ ne révèle aucun signe de vie.
14
+
15
+ 00:16.700 --> 00:19.000
16
+ Mais trois nacelles
17
+ de sauvetage manquaient,
18
+
19
+ 00:19.300 --> 00:21.900
20
+ laissant supposer
21
+ qu'il y aurait des survivants.
22
+
23
+ 00:22.700 --> 00:27.700
24
+ - Mise sur orbite Angel One, paré.
25
+ - Quel genre d'endroit, Data ?
26
+
27
+ 00:28.200 --> 00:31.600
28
+ Planète de Classe-M.
29
+ Faune et flore à base de carbone.
30
+
31
+ 00:31.900 --> 00:34.300
32
+ Population éparse
33
+ et forme de vie intelligente.
34
+
35
+ 00:34.600 --> 00:38.400
36
+ Développement technique équivalent
37
+ au milieu du 20ème siècle terrien.
38
+
39
+ 00:38.800 --> 00:41.000
40
+ C'est presque un retour aux sources.
41
+
42
+ 00:41.300 --> 00:43.600
43
+ Si jamais des survivants
44
+ ont pu aller si loin,
45
+
46
+ 00:43.800 --> 00:49.000
47
+ c'était la planète la plus proche.
48
+ La distance qui nous a pris 2 jours
49
+
50
+ 00:49.500 --> 00:52.400
51
+ aurait pris 5 mois aux nacelles
52
+ de sauvetage du Odin.
53
+
54
+ 00:52.600 --> 00:54.700
55
+ Cinq mois, six jours, onze heures,
56
+ deux min...
57
+
58
+ 00:54.900 --> 00:58.400
59
+ - Merci, Data.
60
+ - ..et 57 secondes.
61
+
62
+ 00:58.600 --> 01:01.300
63
+ Signal audio provenant d'Angel One.
@@ -81,6 +81,9 @@ shaka.test.FakeDrmEngine = class {
81
81
  /** @type {!jasmine.Spy} */
82
82
  this.supportsVariant = jasmine.createSpy('supportsVariant');
83
83
  this.supportsVariant.and.returnValue(true);
84
+
85
+ /** @type {!jasmine.Spy} */
86
+ this.setSrcEquals = jasmine.createSpy('setSrcEquals');
84
87
  }
85
88
 
86
89
  /**
@@ -136,6 +136,10 @@ shaka.test.FakeMediaSourceEngine = class {
136
136
  /** @type {!jasmine.Spy} */
137
137
  this.updateLcevcDil =
138
138
  jasmine.createSpy('updateLcevcDil').and.stub();
139
+
140
+ /** @type {!jasmine.Spy} */
141
+ this.resync=
142
+ jasmine.createSpy('resync').and.stub();
139
143
  }
140
144
 
141
145
  /** @override */
@@ -43,9 +43,10 @@ shaka.test.LayoutTests = class {
43
43
  });
44
44
  });
45
45
 
46
- // Wait one extra tick to make sure the font rendering on the page has been
47
- // updated. Without this, we saw some rare test flake in Firefox on Mac.
48
- await shaka.test.Util.shortDelay();
46
+ // Wait one extra second to make sure the font rendering on the page has
47
+ // been updated. Without this, we saw some rare test flake in Firefox on
48
+ // Mac.
49
+ await shaka.test.Util.delay(1);
49
50
  }
50
51
 
51
52
  /**
@@ -35,6 +35,9 @@ shaka.test.FakeAbrManager = class {
35
35
  /** @type {!jasmine.Spy} */
36
36
  this.stop = jasmine.createSpy('stop');
37
37
 
38
+ /** @type {!jasmine.Spy} */
39
+ this.release = jasmine.createSpy('release');
40
+
38
41
  /** @type {!jasmine.Spy} */
39
42
  this.enable = jasmine.createSpy('enable');
40
43
 
@@ -225,6 +228,9 @@ shaka.test.FakeVideo = class {
225
228
 
226
229
  /** @type {!jasmine.Spy} */
227
230
  this.dispatchEvent = jasmine.createSpy('dispatchEvent');
231
+
232
+ /** @type {!jasmine.Spy} */
233
+ this.canPlayType = jasmine.createSpy('canPlayType');
228
234
  }
229
235
  };
230
236
 
@@ -455,6 +455,7 @@ const widevineDrmServers = {
455
455
 
456
456
  /** @type {AVMetadataType} */
457
457
  const axinomMultiDrmVideoSegment = {
458
+ // Taken from Axinom's v6 test vector.
458
459
  initSegmentUri: '/base/test/test/assets/multidrm-video-init.mp4',
459
460
  mdhdOffset: 0x1d1,
460
461
  segmentUri: '/base/test/test/assets/multidrm-video-segment.mp4',
@@ -469,6 +470,7 @@ const axinomMultiDrmVideoSegment = {
469
470
 
470
471
  /** @type {AVMetadataType} */
471
472
  const axinomMultiDrmAudioSegment = {
473
+ // Taken from Axinom's v6 test vector.
472
474
  initSegmentUri: '/base/test/test/assets/multidrm-audio-init.mp4',
473
475
  mdhdOffset: 0x192,
474
476
  segmentUri: '/base/test/test/assets/multidrm-audio-segment.mp4',
@@ -483,20 +485,15 @@ const axinomMultiDrmAudioSegment = {
483
485
 
484
486
  /** @type {!Object.<string, string>} */
485
487
  const axinomDrmServers = {
488
+ // NOTE: These are not Axinom's actual servers. These are test servers for
489
+ // Widevine and PlayReady that let us specify the known key IDs and keys for
490
+ // Axinom's v6 test vectors. Axinom's own servers started returning 403
491
+ // errors for these older test vectors, and we were forced to switch to
492
+ // something stable and independent.
486
493
  'com.widevine.alpha':
487
- 'https://drm-widevine-licensing.axtest.net/AcquireLicense',
494
+ 'https://cwip-shaka-proxy.appspot.com/specific_key?blodJidXR9eARuql0dNLWg=GX8m9XLIZNIzizrl0RTqnA',
488
495
  'com.microsoft.playready':
489
- 'https://drm-playready-licensing.axtest.net/AcquireLicense',
490
- };
491
-
492
- /** @type {!Object.<string, string>} */
493
- const axinomDrmHeaders = {
494
- 'X-AxDRM-Message':
495
- 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5' +
496
- 'X2lkIjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc' +
497
- '2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIj' +
498
- 'oiNmU1YTFkMjYtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflO' +
499
- 'Pv9qHnu3ZWJNZ12jgkqTabmwXbDWk_47tLNE',
496
+ 'https://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(kid:6e5a1d26-2757-47d7-8046-eaa5d1d34b5a,contentkey:GX8m9XLIZNIzizrl0RTqnA==,sl:150)',
500
497
  };
501
498
 
502
499
  /** @type {TextMetadataType} */
@@ -614,7 +611,6 @@ shaka.test.TestScheme.DATA = {
614
611
  audio: axinomMultiDrmAudioSegment,
615
612
  text: vttSegment,
616
613
  licenseServers: axinomDrmServers,
617
- licenseRequestHeaders: axinomDrmHeaders,
618
614
  duration: 30,
619
615
  },
620
616
 
@@ -626,7 +622,6 @@ shaka.test.TestScheme.DATA = {
626
622
  initData: undefined,
627
623
  }),
628
624
  licenseServers: axinomDrmServers,
629
- licenseRequestHeaders: axinomDrmHeaders,
630
625
  duration: 30,
631
626
  },
632
627
 
@@ -171,6 +171,14 @@ describe('Mp4VttParser', () => {
171
171
  verifyHelper(cues, result);
172
172
  });
173
173
 
174
+ it('handles empty media segments', () => {
175
+ const parser = new shaka.text.Mp4VttParser();
176
+ parser.parseInit(vttInitSegment);
177
+ const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0};
178
+ const result = parser.parseMedia(new Uint8Array(0), time);
179
+ verifyHelper([], result);
180
+ });
181
+
174
182
  it('rejects init segment with no vtt', () => {
175
183
  const error = shaka.test.Util.jasmineError(new shaka.util.Error(
176
184
  shaka.util.Error.Severity.CRITICAL,
@@ -51,4 +51,14 @@ describe('MimeUtils', () => {
51
51
  expect(getNormalizedCodec('dvh1.05')).toBe('dovi');
52
52
  expect(getNormalizedCodec('dvhe.05')).toBe('dovi');
53
53
  });
54
+
55
+ it('isHlsType', () => {
56
+ const isHlsType = (mimeType) => shaka.util.MimeUtils.isHlsType(mimeType);
57
+
58
+ expect(isHlsType('application/x-mpegurl')).toBe(true);
59
+ expect(isHlsType('application/vnd.apple.mpegurl')).toBe(true);
60
+ expect(isHlsType('application/dash+xml')).toBe(false);
61
+ expect(isHlsType('application/vnd.ms-sstr+xml')).toBe(false);
62
+ expect(isHlsType('foo')).toBe(false);
63
+ });
54
64
  });
@@ -103,6 +103,10 @@
103
103
  * below (Y axis) .shaka-play-button-container. */
104
104
  .shaka-canvas-container {
105
105
  .overlay-child();
106
+
107
+ /* Make sure pointer events can reach the video element in the case of native
108
+ * controls. */
109
+ pointer-events: none;
106
110
  }
107
111
 
108
112
  /* Container for controls positioned at the bottom of the video container: