shaka-player 3.1.3 → 3.2.2
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.
- package/AUTHORS +3 -0
- package/CHANGELOG.md +175 -3
- package/CONTRIBUTORS +3 -0
- package/README.md +4 -4
- package/build/generateExterns.js +1 -1
- package/build/types/polyfill +1 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +11 -2
- package/demo/common/message_ids.js +2 -1
- package/demo/config.js +5 -2
- package/demo/index.html +1 -1
- package/demo/locales/en.json +2 -1
- package/demo/locales/source.json +8 -4
- package/demo/main.js +2 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +15 -15
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +15 -15
- package/dist/demo.compiled.map +2 -2
- package/dist/deps.js +22 -21
- package/dist/locales.js +36 -36
- package/dist/receiver.compiled.debug.js +9 -9
- package/dist/receiver.compiled.debug.map +2 -2
- package/dist/receiver.compiled.js +9 -9
- package/dist/receiver.compiled.map +2 -2
- package/dist/shaka-player.compiled.d.ts +58 -10
- package/dist/shaka-player.compiled.debug.d.ts +58 -10
- package/dist/shaka-player.compiled.debug.externs.js +777 -717
- package/dist/shaka-player.compiled.debug.js +639 -607
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +777 -717
- package/dist/shaka-player.compiled.js +826 -819
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +58 -10
- package/dist/shaka-player.ui.debug.d.ts +58 -10
- package/dist/shaka-player.ui.debug.externs.js +529 -469
- package/dist/shaka-player.ui.debug.js +676 -645
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +529 -469
- package/dist/shaka-player.ui.js +963 -955
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/docs/tutorials/ui.md +5 -5
- package/externs/aria.js +6 -0
- package/externs/shaka/ads.js +24 -1
- package/externs/shaka/manifest.js +6 -1
- package/externs/shaka/offline.js +5 -0
- package/externs/shaka/player.js +53 -9
- package/externs/shaka/text.js +10 -10
- package/externs/texttrack.js +3 -0
- package/karma.conf.js +1 -0
- package/lib/ads/ad_manager.js +16 -15
- package/lib/ads/client_side_ad_manager.js +52 -88
- package/lib/ads/server_side_ad_manager.js +26 -12
- package/lib/cast/cast_proxy.js +11 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cast/cast_utils.js +6 -1
- package/lib/cea/cea608_data_channel.js +56 -56
- package/lib/cea/cea608_memory.js +33 -33
- package/lib/cea/cea708_service.js +43 -43
- package/lib/cea/cea708_window.js +38 -38
- package/lib/cea/cea_decoder.js +13 -14
- package/lib/cea/cea_utils.js +23 -23
- package/lib/cea/dtvcc_packet_builder.js +7 -7
- package/lib/cea/i_caption_decoder.js +2 -3
- package/lib/cea/i_cea_parser.js +2 -2
- package/lib/cea/mp4_cea_parser.js +6 -6
- package/lib/dash/dash_parser.js +98 -2
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +1 -1
- package/lib/hls/hls_parser.js +159 -29
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +169 -192
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/segment_index.js +3 -1
- package/lib/media/segment_reference.js +19 -2
- package/lib/media/streaming_engine.js +8 -7
- package/lib/net/networking_engine.js +3 -1
- package/lib/offline/download_manager.js +1 -2
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +3 -1
- package/lib/offline/storage.js +12 -14
- package/lib/player.js +437 -167
- package/lib/polyfill/aria.js +82 -0
- package/lib/polyfill/media_capabilities.js +7 -1
- package/lib/polyfill/mediasource.js +6 -0
- package/lib/polyfill/orientation.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +4 -4
- package/lib/polyfill/patchedmediakeys_ms.js +4 -4
- package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
- package/lib/routing/walker.js +2 -3
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +16 -4
- package/lib/text/ttml_text_parser.js +5 -0
- package/lib/text/ui_text_displayer.js +85 -37
- package/lib/text/vtt_text_parser.js +2 -2
- package/lib/text/web_vtt_generator.js +55 -12
- package/lib/util/error.js +6 -0
- package/lib/util/fake_event.js +53 -7
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_box_parsers.js +20 -20
- package/lib/util/multi_map.js +8 -0
- package/lib/util/periods.js +4 -1
- package/lib/util/platform.js +13 -1
- package/lib/util/player_configuration.js +13 -1
- package/lib/util/stream_utils.js +153 -85
- package/lib/util/xml_utils.js +31 -12
- package/package.json +1 -1
- package/roadmap.md +24 -22
- package/shaka-player.uncompiled.js +1 -0
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_utils_unit.js +2 -1
- package/test/cea/cea608_memory_unit.js +1 -1
- package/test/cea/cea708_service_unit.js +8 -8
- package/test/cea/cea708_window_unit.js +6 -6
- package/test/cea/cea_decoder_unit.js +1 -1
- package/test/cea/dtvcc_packet_builder_unit.js +2 -2
- package/test/dash/dash_parser_manifest_unit.js +230 -2
- package/test/hls/hls_parser_unit.js +255 -1
- package/test/media/closed_caption_parser_unit.js +6 -1
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +353 -450
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +9 -19
- package/test/player_integration.js +90 -0
- package/test/player_src_equals_integration.js +52 -0
- package/test/player_unit.js +11 -33
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/fake_ad_manager.js +8 -1
- package/test/test/util/manifest_generator.js +2 -0
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/text/ttml_text_parser_unit.js +9 -0
- package/test/text/ui_text_displayer_unit.js +29 -17
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +13 -1
- package/test/util/stream_utils_unit.js +153 -10
- package/ui/airplay_button.js +1 -1
- package/ui/audio_language_selection.js +2 -5
- package/ui/cast_button.js +6 -9
- package/ui/constants.js +0 -3
- package/ui/controls.js +4 -6
- package/ui/fast_forward_button.js +2 -3
- package/ui/fullscreen_button.js +1 -3
- package/ui/language_utils.js +1 -1
- package/ui/less/containers.less +3 -7
- package/ui/locales/ru.json +6 -6
- package/ui/localization.js +28 -51
- package/ui/loop_button.js +1 -3
- package/ui/mute_button.js +1 -3
- package/ui/overflow_menu.js +2 -3
- package/ui/pip_button.js +7 -10
- package/ui/playback_rate_selection.js +3 -6
- package/ui/presentation_time.js +1 -3
- package/ui/resolution_selection.js +4 -7
- package/ui/rewind_button.js +2 -3
- package/ui/seek_bar.js +2 -4
- package/ui/spacer.js +1 -1
- package/ui/text_selection.js +8 -11
- package/ui/ui_utils.js +1 -1
- package/ui/volume_bar.js +1 -3
|
@@ -23,14 +23,8 @@ goog.require('shaka.util.PublicPromise');
|
|
|
23
23
|
goog.require('shaka.util.StringUtils');
|
|
24
24
|
goog.require('shaka.util.Uint8ArrayUtils');
|
|
25
25
|
|
|
26
|
-
for (const useMediaCapabilities of [true, false]) {
|
|
27
|
-
const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
|
|
28
|
-
describe('DrmEngine with MediaCapabilities ' + isEnabled, () => {
|
|
29
|
-
testDrmEngine(useMediaCapabilities);
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
26
|
|
|
33
|
-
|
|
27
|
+
describe('DrmEngine', () => {
|
|
34
28
|
const Util = shaka.test.Util;
|
|
35
29
|
|
|
36
30
|
const originalRequestMediaKeySystemAccess =
|
|
@@ -39,8 +33,6 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
39
33
|
const originalBatchTime = shaka.media.DrmEngine.KEY_STATUS_BATCH_TIME;
|
|
40
34
|
const originalDecodingInfo = window.shakaMediaCapabilities.decodingInfo;
|
|
41
35
|
|
|
42
|
-
/** @type {!jasmine.Spy} */
|
|
43
|
-
let requestMediaKeySystemAccessSpy;
|
|
44
36
|
/** @type {!jasmine.Spy} */
|
|
45
37
|
let decodingInfoSpy;
|
|
46
38
|
/** @type {!jasmine.Spy} */
|
|
@@ -83,10 +75,6 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
83
75
|
});
|
|
84
76
|
|
|
85
77
|
beforeEach(() => {
|
|
86
|
-
requestMediaKeySystemAccessSpy =
|
|
87
|
-
jasmine.createSpy('requestMediaKeySystemAccess');
|
|
88
|
-
navigator.requestMediaKeySystemAccess =
|
|
89
|
-
shaka.test.Util.spyFunc(requestMediaKeySystemAccessSpy);
|
|
90
78
|
decodingInfoSpy = jasmine.createSpy('decodingInfo');
|
|
91
79
|
window.shakaMediaCapabilities.decodingInfo =
|
|
92
80
|
shaka.test.Util.spyFunc(decodingInfoSpy);
|
|
@@ -121,7 +109,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
121
109
|
logErrorSpy.and.callFake(fail);
|
|
122
110
|
|
|
123
111
|
// By default, allow keysystem drm.abc
|
|
124
|
-
|
|
112
|
+
setDecodingInfoSpy(['drm.abc']);
|
|
125
113
|
|
|
126
114
|
mockVideo = new shaka.test.FakeVideo();
|
|
127
115
|
|
|
@@ -192,74 +180,62 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
192
180
|
describe('init', () => {
|
|
193
181
|
it('stops on first available key system', async () => {
|
|
194
182
|
// Accept both drm.abc and drm.def. Only one can be chosen.
|
|
195
|
-
|
|
183
|
+
setDecodingInfoSpy(['drm.abc', 'drm.def']);
|
|
196
184
|
|
|
197
185
|
const variants = manifest.variants;
|
|
198
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
199
|
-
useMediaCapabilities);
|
|
186
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
200
187
|
expect(drmEngine.initialized()).toBe(true);
|
|
201
188
|
expect(shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo()))
|
|
202
189
|
.toBe('drm.abc');
|
|
203
|
-
|
|
204
|
-
if (!useMediaCapabilities) {
|
|
205
|
-
// Only one call, since the first key system worked.
|
|
206
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
207
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
208
|
-
.toHaveBeenCalledWith('drm.abc', jasmine.any(Object));
|
|
209
|
-
}
|
|
210
190
|
});
|
|
211
191
|
|
|
212
192
|
it('tries to get the key systems in the order they appear in', async () => {
|
|
213
193
|
// Fail both key systems.
|
|
214
|
-
|
|
194
|
+
setDecodingInfoSpy([]);
|
|
215
195
|
|
|
216
196
|
const variants = manifest.variants;
|
|
217
197
|
await expectAsync(drmEngine.initForPlayback(variants,
|
|
218
|
-
manifest.offlineSessionIds
|
|
198
|
+
manifest.offlineSessionIds)).toBeRejected();
|
|
219
199
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}));
|
|
200
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(2);
|
|
201
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
202
|
+
keySystemConfiguration: containing({keySystem: 'drm.abc'}),
|
|
203
|
+
}));
|
|
225
204
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
} else {
|
|
230
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(2);
|
|
231
|
-
// These should be in the same order as the key systems appear in the
|
|
232
|
-
// manifest.
|
|
233
|
-
const calls = requestMediaKeySystemAccessSpy.calls;
|
|
234
|
-
expect(calls.argsFor(0)[0]).toBe('drm.abc');
|
|
235
|
-
expect(calls.argsFor(1)[0]).toBe('drm.def');
|
|
236
|
-
}
|
|
205
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
206
|
+
keySystemConfiguration: containing({keySystem: 'drm.def'}),
|
|
207
|
+
}));
|
|
237
208
|
});
|
|
238
209
|
|
|
239
210
|
it('tries the second key system if the first fails', async () => {
|
|
240
211
|
// Accept drm.def, but not drm.abc.
|
|
241
|
-
|
|
212
|
+
setDecodingInfoSpy(['drm.def']);
|
|
242
213
|
|
|
243
214
|
const variants = manifest.variants;
|
|
244
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
245
|
-
useMediaCapabilities);
|
|
215
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
246
216
|
expect(drmEngine.initialized()).toBe(true);
|
|
247
217
|
expect(shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo()))
|
|
248
218
|
.toBe('drm.def');
|
|
219
|
+
});
|
|
249
220
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
221
|
+
it('chooses systems by configured preferredKeySystems', async () => {
|
|
222
|
+
// Accept both drm.abc and drm.def. Only one can be chosen.
|
|
223
|
+
setDecodingInfoSpy(['drm.abc', 'drm.def']);
|
|
224
|
+
config.preferredKeySystems = ['drm.def'];
|
|
225
|
+
drmEngine.configure(config);
|
|
226
|
+
logErrorSpy.and.stub();
|
|
227
|
+
|
|
228
|
+
const variants = manifest.variants;
|
|
229
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
230
|
+
|
|
231
|
+
expect(variants[0].decodingInfos.length).toBe(2);
|
|
232
|
+
expect(shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo()))
|
|
233
|
+
.toBe('drm.def');
|
|
258
234
|
});
|
|
259
235
|
|
|
260
236
|
it('chooses systems with configured license servers', async () => {
|
|
261
237
|
// Accept both drm.abc and drm.def. Only one can be chosen.
|
|
262
|
-
|
|
238
|
+
setDecodingInfoSpy(['drm.abc', 'drm.def']);
|
|
263
239
|
|
|
264
240
|
// Remove the server URI for drm.abc, which appears first in the manifest.
|
|
265
241
|
delete config.servers['drm.abc'];
|
|
@@ -268,25 +244,16 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
268
244
|
logErrorSpy.and.stub();
|
|
269
245
|
|
|
270
246
|
const variants = manifest.variants;
|
|
271
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
272
|
-
useMediaCapabilities);
|
|
247
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
273
248
|
|
|
274
|
-
|
|
275
|
-
expect(variants[0].decodingInfos.length).toBe(2);
|
|
276
|
-
} else {
|
|
277
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
278
|
-
// Although drm.def appears second in the manifest, it is queried first
|
|
279
|
-
// and also selected because it has a server configured.
|
|
280
|
-
const calls = requestMediaKeySystemAccessSpy.calls;
|
|
281
|
-
expect(calls.argsFor(0)[0]).toBe('drm.def');
|
|
282
|
-
}
|
|
249
|
+
expect(variants[0].decodingInfos.length).toBe(2);
|
|
283
250
|
expect(shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo()))
|
|
284
251
|
.toBe('drm.def');
|
|
285
252
|
});
|
|
286
253
|
|
|
287
254
|
it('overrides manifest with configured license servers', async () => {
|
|
288
255
|
// Accept both drm.abc and drm.def. Only one can be chosen.
|
|
289
|
-
|
|
256
|
+
setDecodingInfoSpy(['drm.abc', 'drm.def']);
|
|
290
257
|
|
|
291
258
|
// Add manifest-supplied license servers for both.
|
|
292
259
|
tweakDrmInfos((drmInfos) => {
|
|
@@ -313,18 +280,9 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
313
280
|
logErrorSpy.and.stub();
|
|
314
281
|
|
|
315
282
|
const variants = manifest.variants;
|
|
316
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
317
|
-
useMediaCapabilities);
|
|
318
|
-
|
|
319
|
-
if (useMediaCapabilities) {
|
|
320
|
-
expect(variants[0].decodingInfos.length).toBe(2);
|
|
321
|
-
} else {
|
|
322
|
-
// Although drm.def appears second in the manifest, it is queried first
|
|
323
|
-
// because it has a server configured. The manifest-supplied server for
|
|
324
|
-
// drm.abc will not be used.
|
|
325
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
326
|
-
}
|
|
283
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
327
284
|
|
|
285
|
+
expect(variants[0].decodingInfos.length).toBe(2);
|
|
328
286
|
const selectedDrmInfo = drmEngine.getDrmInfo();
|
|
329
287
|
expect(selectedDrmInfo).not.toBe(null);
|
|
330
288
|
expect(selectedDrmInfo.keySystem).toBe('drm.def');
|
|
@@ -332,11 +290,10 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
332
290
|
});
|
|
333
291
|
|
|
334
292
|
it('detects content type capabilities of key system', async () => {
|
|
335
|
-
|
|
293
|
+
setDecodingInfoSpy(['drm.abc']);
|
|
336
294
|
|
|
337
295
|
const variants = manifest.variants;
|
|
338
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
339
|
-
useMediaCapabilities);
|
|
296
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
340
297
|
expect(drmEngine.initialized()).toBe(true);
|
|
341
298
|
expect(drmEngine.willSupport('audio/webm')).toBeTruthy();
|
|
342
299
|
expect(drmEngine.willSupport('video/mp4; codecs="fake"')).toBeTruthy();
|
|
@@ -352,7 +309,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
352
309
|
|
|
353
310
|
it('fails to initialize if no key systems are available', async () => {
|
|
354
311
|
// Accept no key systems.
|
|
355
|
-
|
|
312
|
+
setDecodingInfoSpy([]);
|
|
356
313
|
|
|
357
314
|
const expected = Util.jasmineError(new shaka.util.Error(
|
|
358
315
|
shaka.util.Error.Severity.CRITICAL,
|
|
@@ -360,21 +317,12 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
360
317
|
shaka.util.Error.Code.REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE));
|
|
361
318
|
const variants = manifest.variants;
|
|
362
319
|
await expectAsync(
|
|
363
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
364
|
-
|
|
320
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
321
|
+
.toBeRejectedWith(expected);
|
|
365
322
|
|
|
366
323
|
expect(drmEngine.initialized()).toBe(false);
|
|
367
324
|
|
|
368
|
-
|
|
369
|
-
expect(variants[0].decodingInfos.length).toBe(2);
|
|
370
|
-
} else {
|
|
371
|
-
// Both key systems were tried, since the first one failed.
|
|
372
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(2);
|
|
373
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
374
|
-
.toHaveBeenCalledWith('drm.abc', jasmine.any(Object));
|
|
375
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
376
|
-
.toHaveBeenCalledWith('drm.def', jasmine.any(Object));
|
|
377
|
-
}
|
|
325
|
+
expect(variants[0].decodingInfos.length).toBe(2);
|
|
378
326
|
});
|
|
379
327
|
|
|
380
328
|
it('does not error for unencrypted assets with no EME', async () => {
|
|
@@ -390,13 +338,13 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
390
338
|
});
|
|
391
339
|
|
|
392
340
|
// Accept no key systems, simulating a lack of EME.
|
|
393
|
-
|
|
341
|
+
setDecodingInfoSpy([]);
|
|
394
342
|
|
|
395
343
|
const variants = manifest.variants;
|
|
396
344
|
// All that matters here is that we don't throw.
|
|
397
345
|
await expectAsync(
|
|
398
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
399
|
-
|
|
346
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
347
|
+
.not.toBeRejected();
|
|
400
348
|
});
|
|
401
349
|
|
|
402
350
|
it('fails to initialize if no key systems are recognized', async () => {
|
|
@@ -413,18 +361,13 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
413
361
|
shaka.util.Error.Code.NO_RECOGNIZED_KEY_SYSTEMS));
|
|
414
362
|
const variants = manifest.variants;
|
|
415
363
|
await expectAsync(
|
|
416
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
417
|
-
|
|
364
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
365
|
+
.toBeRejectedWith(expected);
|
|
418
366
|
|
|
419
367
|
expect(drmEngine.initialized()).toBe(false);
|
|
420
368
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
expect(variants[0].decodingInfos[0].keySystemAccess).toBeFalsy();
|
|
424
|
-
} else {
|
|
425
|
-
// No key systems were tried, since the dummy placeholder was detected.
|
|
426
|
-
expect(requestMediaKeySystemAccessSpy).not.toHaveBeenCalled();
|
|
427
|
-
}
|
|
369
|
+
expect(variants[0].decodingInfos.length).toBe(1);
|
|
370
|
+
expect(variants[0].decodingInfos[0].keySystemAccess).toBeFalsy();
|
|
428
371
|
});
|
|
429
372
|
|
|
430
373
|
it('fails to initialize if the CDM cannot be created', async () => {
|
|
@@ -438,146 +381,95 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
438
381
|
'whoops!'));
|
|
439
382
|
const variants = manifest.variants;
|
|
440
383
|
await expectAsync(
|
|
441
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
442
|
-
|
|
384
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
385
|
+
.toBeRejectedWith(expected);
|
|
443
386
|
|
|
444
387
|
expect(drmEngine.initialized()).toBe(false);
|
|
445
|
-
|
|
446
|
-
if (useMediaCapabilities) {
|
|
447
|
-
expect(variants[0].decodingInfos.length).toBe(2);
|
|
448
|
-
} else {
|
|
449
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
450
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
451
|
-
.toHaveBeenCalledWith('drm.abc', jasmine.any(Object));
|
|
452
|
-
}
|
|
388
|
+
expect(variants[0].decodingInfos.length).toBe(2);
|
|
453
389
|
});
|
|
454
390
|
|
|
455
391
|
it('queries audio/video capabilities', async () => {
|
|
456
|
-
|
|
392
|
+
setDecodingInfoSpy([]);
|
|
457
393
|
|
|
458
394
|
const variants = manifest.variants;
|
|
459
395
|
await expectAsync(
|
|
460
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
461
|
-
|
|
396
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
397
|
+
.toBeRejected();
|
|
462
398
|
|
|
463
399
|
expect(drmEngine.initialized()).toBe(false);
|
|
464
400
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
});
|
|
401
|
+
const decodingConfig1 = containing({
|
|
402
|
+
video: containing({
|
|
403
|
+
contentType: 'video/foo; codecs="vbar"',
|
|
404
|
+
}),
|
|
405
|
+
audio: containing({
|
|
406
|
+
contentType: 'audio/foo; codecs="abar"',
|
|
407
|
+
}),
|
|
408
|
+
keySystemConfiguration: containing({
|
|
409
|
+
keySystem: 'drm.abc',
|
|
410
|
+
persistentState: 'optional',
|
|
411
|
+
distinctiveIdentifier: 'optional',
|
|
412
|
+
sessionTypes: ['temporary'],
|
|
413
|
+
initDataType: 'cenc',
|
|
414
|
+
}),
|
|
415
|
+
});
|
|
481
416
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
} else {
|
|
501
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(2);
|
|
502
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
503
|
-
.toHaveBeenCalledWith('drm.abc', [jasmine.objectContaining({
|
|
504
|
-
// audioCapabilities not present.
|
|
505
|
-
videoCapabilities: [jasmine.objectContaining({
|
|
506
|
-
contentType: 'video/foo; codecs="vbar"',
|
|
507
|
-
})],
|
|
508
|
-
distinctiveIdentifier: 'optional',
|
|
509
|
-
persistentState: 'optional',
|
|
510
|
-
sessionTypes: ['temporary'],
|
|
511
|
-
})]);
|
|
512
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
513
|
-
.toHaveBeenCalledWith('drm.def', [jasmine.objectContaining({
|
|
514
|
-
audioCapabilities: [jasmine.objectContaining({
|
|
515
|
-
contentType: 'audio/foo; codecs="abar"',
|
|
516
|
-
})],
|
|
517
|
-
// videoCapabilities not present.
|
|
518
|
-
distinctiveIdentifier: 'optional',
|
|
519
|
-
persistentState: 'optional',
|
|
520
|
-
sessionTypes: ['temporary'],
|
|
521
|
-
})]);
|
|
522
|
-
}
|
|
417
|
+
const decodingConfig2 = containing({
|
|
418
|
+
video: containing({
|
|
419
|
+
contentType: 'video/foo; codecs="vbar"',
|
|
420
|
+
}),
|
|
421
|
+
audio: containing({
|
|
422
|
+
contentType: 'audio/foo; codecs="abar"',
|
|
423
|
+
}),
|
|
424
|
+
keySystemConfiguration: containing({
|
|
425
|
+
keySystem: 'drm.def',
|
|
426
|
+
persistentState: 'optional',
|
|
427
|
+
distinctiveIdentifier: 'optional',
|
|
428
|
+
sessionTypes: ['temporary'],
|
|
429
|
+
initDataType: 'cenc',
|
|
430
|
+
}),
|
|
431
|
+
});
|
|
432
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(2);
|
|
433
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(decodingConfig1);
|
|
434
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(decodingConfig2);
|
|
523
435
|
});
|
|
524
436
|
|
|
525
437
|
it('asks for persistent state and license for offline', async () => {
|
|
526
|
-
|
|
438
|
+
setDecodingInfoSpy([]);
|
|
527
439
|
|
|
528
440
|
const variants = manifest.variants;
|
|
529
441
|
await expectAsync(
|
|
530
|
-
drmEngine.initForStorage(variants, /* usePersistentLicense= */ true
|
|
531
|
-
|
|
442
|
+
drmEngine.initForStorage(variants, /* usePersistentLicense= */ true))
|
|
443
|
+
.toBeRejected();
|
|
532
444
|
|
|
533
445
|
expect(drmEngine.initialized()).toBe(false);
|
|
534
446
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
initDataType: 'cenc',
|
|
544
|
-
}),
|
|
447
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(2);
|
|
448
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
449
|
+
keySystemConfiguration: containing({
|
|
450
|
+
keySystem: 'drm.abc',
|
|
451
|
+
distinctiveIdentifier: 'optional',
|
|
452
|
+
persistentState: 'required',
|
|
453
|
+
sessionTypes: ['persistent-license'],
|
|
454
|
+
initDataType: 'cenc',
|
|
545
455
|
}),
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
456
|
+
}),
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
460
|
+
keySystemConfiguration: containing({
|
|
461
|
+
keySystem: 'drm.def',
|
|
462
|
+
distinctiveIdentifier: 'optional',
|
|
463
|
+
persistentState: 'required',
|
|
464
|
+
sessionTypes: ['persistent-license'],
|
|
465
|
+
initDataType: 'cenc',
|
|
556
466
|
}),
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(2);
|
|
560
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledWith('drm.abc', [
|
|
561
|
-
jasmine.objectContaining({
|
|
562
|
-
distinctiveIdentifier: 'optional',
|
|
563
|
-
persistentState: 'required',
|
|
564
|
-
sessionTypes: ['persistent-license'],
|
|
565
|
-
initDataTypes: ['cenc'],
|
|
566
|
-
}),
|
|
567
|
-
]);
|
|
568
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledWith('drm.def', [
|
|
569
|
-
jasmine.objectContaining({
|
|
570
|
-
distinctiveIdentifier: 'optional',
|
|
571
|
-
persistentState: 'required',
|
|
572
|
-
sessionTypes: ['persistent-license'],
|
|
573
|
-
initDataTypes: ['cenc'],
|
|
574
|
-
}),
|
|
575
|
-
]);
|
|
576
|
-
}
|
|
467
|
+
}),
|
|
468
|
+
);
|
|
577
469
|
});
|
|
578
470
|
|
|
579
471
|
it('honors distinctive identifier and persistent state', async () => {
|
|
580
|
-
|
|
472
|
+
setDecodingInfoSpy([]);
|
|
581
473
|
tweakDrmInfos((drmInfos) => {
|
|
582
474
|
drmInfos[0].distinctiveIdentifierRequired = true;
|
|
583
475
|
drmInfos[1].persistentStateRequired = true;
|
|
@@ -585,52 +477,36 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
585
477
|
|
|
586
478
|
const variants = manifest.variants;
|
|
587
479
|
await expectAsync(
|
|
588
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
589
|
-
|
|
480
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
481
|
+
.toBeRejected();
|
|
590
482
|
|
|
591
483
|
expect(drmEngine.initialized()).toBe(false);
|
|
592
484
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
sessionTypes: ['temporary'],
|
|
601
|
-
}),
|
|
485
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(2);
|
|
486
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
487
|
+
keySystemConfiguration: containing({
|
|
488
|
+
keySystem: 'drm.abc',
|
|
489
|
+
distinctiveIdentifier: 'required',
|
|
490
|
+
persistentState: 'optional',
|
|
491
|
+
sessionTypes: ['temporary'],
|
|
602
492
|
}),
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
493
|
+
}),
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
497
|
+
keySystemConfiguration: containing({
|
|
498
|
+
keySystem: 'drm.def',
|
|
499
|
+
distinctiveIdentifier: 'optional',
|
|
500
|
+
persistentState: 'required',
|
|
501
|
+
sessionTypes: ['temporary'],
|
|
612
502
|
}),
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(2);
|
|
616
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
617
|
-
.toHaveBeenCalledWith('drm.abc', [jasmine.objectContaining({
|
|
618
|
-
distinctiveIdentifier: 'required',
|
|
619
|
-
persistentState: 'optional',
|
|
620
|
-
sessionTypes: ['temporary'],
|
|
621
|
-
})]);
|
|
622
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
623
|
-
.toHaveBeenCalledWith('drm.def', [jasmine.objectContaining({
|
|
624
|
-
distinctiveIdentifier: 'optional',
|
|
625
|
-
persistentState: 'required',
|
|
626
|
-
sessionTypes: ['temporary'],
|
|
627
|
-
})]);
|
|
628
|
-
}
|
|
503
|
+
}),
|
|
504
|
+
);
|
|
629
505
|
});
|
|
630
506
|
|
|
631
507
|
it('makes no queries for key systems with clear content if no key config',
|
|
632
508
|
async () => {
|
|
633
|
-
|
|
509
|
+
setDecodingInfoSpy([]);
|
|
634
510
|
manifest.variants[0].video.drmInfos = [];
|
|
635
511
|
manifest.variants[0].audio.drmInfos = [];
|
|
636
512
|
config.servers = {};
|
|
@@ -638,24 +514,18 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
638
514
|
|
|
639
515
|
drmEngine.configure(config);
|
|
640
516
|
const variants = manifest.variants;
|
|
641
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
expect(variants[0].decodingInfos.length).toBe(1);
|
|
647
|
-
expect(variants[0].decodingInfos[0].keySystemAccess).toBeFalsy();
|
|
648
|
-
} else {
|
|
649
|
-
// Makes no queries for clear content.
|
|
650
|
-
expect(requestMediaKeySystemAccessSpy).not.toHaveBeenCalled();
|
|
651
|
-
}
|
|
517
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
518
|
+
|
|
519
|
+
// Gets decodingInfo for clear content with no keySystemAccess.
|
|
520
|
+
expect(variants[0].decodingInfos.length).toBe(1);
|
|
521
|
+
expect(variants[0].decodingInfos[0].keySystemAccess).toBeFalsy();
|
|
652
522
|
expect(
|
|
653
523
|
shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo())).toBe('');
|
|
654
524
|
expect(drmEngine.initialized()).toBe(true);
|
|
655
525
|
});
|
|
656
526
|
|
|
657
527
|
it('makes queries for clear content if key is configured', async () => {
|
|
658
|
-
|
|
528
|
+
setDecodingInfoSpy(['drm.abc']);
|
|
659
529
|
manifest.variants[0].video.drmInfos = [];
|
|
660
530
|
manifest.variants[0].audio.drmInfos = [];
|
|
661
531
|
config.servers = {
|
|
@@ -664,16 +534,11 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
664
534
|
|
|
665
535
|
drmEngine.configure(config);
|
|
666
536
|
const variants = manifest.variants;
|
|
667
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
668
|
-
useMediaCapabilities);
|
|
537
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
669
538
|
expect(drmEngine.initialized()).toBe(true);
|
|
670
539
|
expect(shaka.media.DrmEngine.keySystem(drmEngine.getDrmInfo()))
|
|
671
540
|
.toBe('drm.abc');
|
|
672
|
-
|
|
673
|
-
expect(variants[0].decodingInfos.length).toBe(1);
|
|
674
|
-
} else {
|
|
675
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
676
|
-
}
|
|
541
|
+
expect(variants[0].decodingInfos.length).toBe(1);
|
|
677
542
|
});
|
|
678
543
|
|
|
679
544
|
it('uses advanced config to fill in DrmInfo', async () => {
|
|
@@ -691,12 +556,13 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
691
556
|
});
|
|
692
557
|
});
|
|
693
558
|
|
|
694
|
-
|
|
559
|
+
setDecodingInfoSpy([]);
|
|
695
560
|
|
|
696
561
|
config.advanced['drm.abc'] = {
|
|
697
562
|
audioRobustness: 'good',
|
|
698
563
|
videoRobustness: 'really_really_ridiculously_good',
|
|
699
564
|
serverCertificate: null,
|
|
565
|
+
serverCertificateUri: '',
|
|
700
566
|
sessionType: 'persistent-license',
|
|
701
567
|
individualizationServer: '',
|
|
702
568
|
distinctiveIdentifierRequired: true,
|
|
@@ -706,44 +572,26 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
706
572
|
|
|
707
573
|
const variants = manifest.variants;
|
|
708
574
|
await expectAsync(
|
|
709
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
710
|
-
|
|
575
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
576
|
+
.toBeRejected();
|
|
711
577
|
|
|
712
578
|
expect(drmEngine.initialized()).toBe(false);
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
audio: containing({
|
|
724
|
-
robustness: 'good',
|
|
725
|
-
}),
|
|
726
|
-
video: containing({
|
|
727
|
-
robustness: 'really_really_ridiculously_good',
|
|
728
|
-
}),
|
|
579
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(1);
|
|
580
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
581
|
+
keySystemConfiguration: containing({
|
|
582
|
+
keySystem: 'drm.abc',
|
|
583
|
+
distinctiveIdentifier: 'required',
|
|
584
|
+
persistentState: 'required',
|
|
585
|
+
sessionTypes: ['persistent-license'],
|
|
586
|
+
initDataType: 'cenc',
|
|
587
|
+
audio: containing({
|
|
588
|
+
robustness: 'good',
|
|
729
589
|
}),
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
audioCapabilities: [jasmine.objectContaining({
|
|
736
|
-
robustness: 'good',
|
|
737
|
-
})],
|
|
738
|
-
videoCapabilities: [jasmine.objectContaining({
|
|
739
|
-
robustness: 'really_really_ridiculously_good',
|
|
740
|
-
})],
|
|
741
|
-
distinctiveIdentifier: 'required',
|
|
742
|
-
persistentState: 'required',
|
|
743
|
-
sessionTypes: ['persistent-license'],
|
|
744
|
-
initDataTypes: ['cenc'],
|
|
745
|
-
})]);
|
|
746
|
-
}
|
|
590
|
+
video: containing({
|
|
591
|
+
robustness: 'really_really_ridiculously_good',
|
|
592
|
+
}),
|
|
593
|
+
}),
|
|
594
|
+
}));
|
|
747
595
|
});
|
|
748
596
|
|
|
749
597
|
it('prefers advanced config from manifest if present', async () => {
|
|
@@ -761,7 +609,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
761
609
|
});
|
|
762
610
|
});
|
|
763
611
|
|
|
764
|
-
|
|
612
|
+
setDecodingInfoSpy([]);
|
|
765
613
|
|
|
766
614
|
// DrmInfo directly sets advanced settings.
|
|
767
615
|
tweakDrmInfos((drmInfos) => {
|
|
@@ -775,6 +623,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
775
623
|
audioRobustness: 'bad',
|
|
776
624
|
videoRobustness: 'so_bad_it_hurts',
|
|
777
625
|
serverCertificate: null,
|
|
626
|
+
serverCertificateUri: '',
|
|
778
627
|
sessionType: '',
|
|
779
628
|
individualizationServer: '',
|
|
780
629
|
distinctiveIdentifierRequired: false,
|
|
@@ -784,42 +633,26 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
784
633
|
|
|
785
634
|
const variants = manifest.variants;
|
|
786
635
|
await expectAsync(
|
|
787
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
788
|
-
|
|
636
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
637
|
+
.toBeRejected();
|
|
789
638
|
|
|
790
639
|
expect(drmEngine.initialized()).toBe(false);
|
|
791
640
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
robustness: 'good',
|
|
799
|
-
}),
|
|
800
|
-
video: containing({
|
|
801
|
-
robustness: 'really_really_ridiculously_good',
|
|
802
|
-
}),
|
|
803
|
-
distinctiveIdentifier: 'required',
|
|
804
|
-
persistentState: 'required',
|
|
805
|
-
initDataType: 'cenc',
|
|
641
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(1);
|
|
642
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
643
|
+
keySystemConfiguration: containing({
|
|
644
|
+
keySystem: 'drm.abc',
|
|
645
|
+
audio: containing({
|
|
646
|
+
robustness: 'good',
|
|
806
647
|
}),
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
videoCapabilities: [jasmine.objectContaining({
|
|
816
|
-
robustness: 'really_really_ridiculously_good',
|
|
817
|
-
})],
|
|
818
|
-
distinctiveIdentifier: 'required',
|
|
819
|
-
persistentState: 'required',
|
|
820
|
-
initDataTypes: ['cenc'],
|
|
821
|
-
})]);
|
|
822
|
-
}
|
|
648
|
+
video: containing({
|
|
649
|
+
robustness: 'really_really_ridiculously_good',
|
|
650
|
+
}),
|
|
651
|
+
distinctiveIdentifier: 'required',
|
|
652
|
+
persistentState: 'required',
|
|
653
|
+
initDataType: 'cenc',
|
|
654
|
+
}),
|
|
655
|
+
}));
|
|
823
656
|
});
|
|
824
657
|
|
|
825
658
|
it('sets unique initDataTypes if specified from the initData', async () => {
|
|
@@ -834,30 +667,21 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
834
667
|
|
|
835
668
|
const variants = manifest.variants;
|
|
836
669
|
|
|
837
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
838
|
-
useMediaCapabilities);
|
|
670
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
839
671
|
|
|
840
672
|
expect(drmEngine.initialized()).toBe(true);
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
initDataType: 'very_nice',
|
|
847
|
-
}),
|
|
673
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(2);
|
|
674
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(containing({
|
|
675
|
+
keySystemConfiguration: containing({
|
|
676
|
+
keySystem: 'drm.abc',
|
|
677
|
+
initDataType: 'very_nice',
|
|
848
678
|
}),
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
852
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
853
|
-
.toHaveBeenCalledWith('drm.abc', [jasmine.objectContaining({
|
|
854
|
-
initDataTypes: ['very_nice'],
|
|
855
|
-
})]);
|
|
856
|
-
}
|
|
679
|
+
}),
|
|
680
|
+
);
|
|
857
681
|
});
|
|
858
682
|
|
|
859
683
|
it('fails if license server is not configured', async () => {
|
|
860
|
-
|
|
684
|
+
setDecodingInfoSpy(['drm.abc']);
|
|
861
685
|
|
|
862
686
|
config.servers = {};
|
|
863
687
|
drmEngine.configure(config);
|
|
@@ -869,8 +693,8 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
869
693
|
'drm.abc'));
|
|
870
694
|
const variants = manifest.variants;
|
|
871
695
|
await expectAsync(
|
|
872
|
-
drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
873
|
-
|
|
696
|
+
drmEngine.initForPlayback(variants, manifest.offlineSessionIds))
|
|
697
|
+
.toBeRejectedWith(expected);
|
|
874
698
|
});
|
|
875
699
|
|
|
876
700
|
it('maps TS MIME types through the transmuxer', async () => {
|
|
@@ -896,38 +720,26 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
896
720
|
};
|
|
897
721
|
});
|
|
898
722
|
|
|
899
|
-
|
|
723
|
+
setDecodingInfoSpy(['drm.abc']);
|
|
900
724
|
|
|
901
725
|
const variants = manifest.variants;
|
|
902
726
|
variants[0].video.mimeType = 'video/mp2t';
|
|
903
727
|
variants[0].audio.mimeType = 'video/mp2t';
|
|
904
728
|
|
|
905
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
906
|
-
useMediaCapabilities);
|
|
729
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
907
730
|
expect(drmEngine.initialized()).toBe(true);
|
|
908
731
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
} else {
|
|
921
|
-
expect(requestMediaKeySystemAccessSpy)
|
|
922
|
-
.toHaveBeenCalledWith('drm.abc', [jasmine.objectContaining({
|
|
923
|
-
audioCapabilities: [jasmine.objectContaining({
|
|
924
|
-
contentType: 'audio/mp4; codecs="abar"',
|
|
925
|
-
})],
|
|
926
|
-
videoCapabilities: [jasmine.objectContaining({
|
|
927
|
-
contentType: 'video/mp4; codecs="vbar"',
|
|
928
|
-
})],
|
|
929
|
-
})]);
|
|
930
|
-
}
|
|
732
|
+
const decodingConfig = containing({
|
|
733
|
+
video: containing({
|
|
734
|
+
contentType: 'video/mp4; codecs="vbar"',
|
|
735
|
+
}),
|
|
736
|
+
audio: containing({
|
|
737
|
+
contentType: 'audio/mp4; codecs="abar"',
|
|
738
|
+
}),
|
|
739
|
+
});
|
|
740
|
+
expect(decodingInfoSpy).toHaveBeenCalledTimes(2);
|
|
741
|
+
expect(decodingInfoSpy).toHaveBeenCalledWith(decodingConfig);
|
|
742
|
+
|
|
931
743
|
expect(drmEngine.supportsVariant(variants[0])).toBeTruthy();
|
|
932
744
|
} finally {
|
|
933
745
|
// Restore the mock.
|
|
@@ -954,7 +766,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
954
766
|
});
|
|
955
767
|
|
|
956
768
|
it('does nothing for unencrypted content', async () => {
|
|
957
|
-
|
|
769
|
+
setDecodingInfoSpy([]);
|
|
958
770
|
manifest.variants[0].video.drmInfos = [];
|
|
959
771
|
manifest.variants[0].audio.drmInfos = [];
|
|
960
772
|
config.servers = {};
|
|
@@ -972,16 +784,75 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
972
784
|
it('sets server certificate if present in config', async () => {
|
|
973
785
|
const cert = new Uint8Array(1);
|
|
974
786
|
config.advanced['drm.abc'] = createAdvancedConfig(cert);
|
|
787
|
+
config.advanced['drm.abc'].serverCertificateUri =
|
|
788
|
+
'https://drm-service.com/certificate';
|
|
975
789
|
drmEngine.configure(config);
|
|
976
790
|
|
|
977
791
|
const variants = manifest.variants;
|
|
978
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
979
|
-
useMediaCapabilities);
|
|
792
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
980
793
|
|
|
794
|
+
expect(fakeNetEngine.request).not.toHaveBeenCalled();
|
|
981
795
|
// Should be set merely after init, without waiting for attach.
|
|
982
796
|
expect(mockMediaKeys.setServerCertificate).toHaveBeenCalledWith(cert);
|
|
983
797
|
});
|
|
984
798
|
|
|
799
|
+
it('fetches and sets server certificate from uri', async () => {
|
|
800
|
+
const cert = new Uint8Array(0);
|
|
801
|
+
const serverCertificateUri = 'https://drm-service.com/certificate';
|
|
802
|
+
config.advanced['drm.abc'] = createAdvancedConfig(cert);
|
|
803
|
+
config.advanced['drm.abc'].serverCertificateUri = serverCertificateUri;
|
|
804
|
+
|
|
805
|
+
fakeNetEngine.setResponseValue(
|
|
806
|
+
serverCertificateUri,
|
|
807
|
+
shaka.util.BufferUtils.toArrayBuffer(new Uint8Array(1)));
|
|
808
|
+
|
|
809
|
+
drmEngine.configure(config);
|
|
810
|
+
|
|
811
|
+
const variants = manifest.variants;
|
|
812
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
813
|
+
|
|
814
|
+
fakeNetEngine.expectRequest(
|
|
815
|
+
serverCertificateUri,
|
|
816
|
+
shaka.net.NetworkingEngine.RequestType.SERVER_CERTIFICATE);
|
|
817
|
+
|
|
818
|
+
// Should be set merely after init, without waiting for attach.
|
|
819
|
+
expect(mockMediaKeys.setServerCertificate).toHaveBeenCalledWith(
|
|
820
|
+
new Uint8Array(1));
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
it('fetches server certificate from uri and triggers error', async () => {
|
|
824
|
+
const cert = new Uint8Array(0);
|
|
825
|
+
const serverCertificateUri = 'https://drm-service.com/certificate';
|
|
826
|
+
config.advanced['drm.abc'] = createAdvancedConfig(cert);
|
|
827
|
+
config.advanced['drm.abc'].serverCertificateUri = serverCertificateUri;
|
|
828
|
+
|
|
829
|
+
// Simulate a permission error from the web server.
|
|
830
|
+
const netError = new shaka.util.Error(
|
|
831
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
832
|
+
shaka.util.Error.Category.NETWORK,
|
|
833
|
+
shaka.util.Error.Code.BAD_HTTP_STATUS,
|
|
834
|
+
serverCertificateUri, 403);
|
|
835
|
+
const operation = shaka.util.AbortableOperation.failed(netError);
|
|
836
|
+
fakeNetEngine.request.and.returnValue(operation);
|
|
837
|
+
|
|
838
|
+
drmEngine.configure(config);
|
|
839
|
+
|
|
840
|
+
const expected = Util.jasmineError(new shaka.util.Error(
|
|
841
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
842
|
+
shaka.util.Error.Category.DRM,
|
|
843
|
+
shaka.util.Error.Code.SERVER_CERTIFICATE_REQUEST_FAILED,
|
|
844
|
+
netError));
|
|
845
|
+
|
|
846
|
+
await expectAsync(initAndAttach()).toBeRejectedWith(expected);
|
|
847
|
+
|
|
848
|
+
fakeNetEngine.expectRequest(
|
|
849
|
+
serverCertificateUri,
|
|
850
|
+
shaka.net.NetworkingEngine.RequestType.SERVER_CERTIFICATE);
|
|
851
|
+
|
|
852
|
+
// Should be set merely after init, without waiting for attach.
|
|
853
|
+
expect(mockMediaKeys.setServerCertificate).not.toHaveBeenCalled();
|
|
854
|
+
});
|
|
855
|
+
|
|
985
856
|
it('prefers server certificate from DrmInfo', async () => {
|
|
986
857
|
const cert1 = new Uint8Array(5);
|
|
987
858
|
const cert2 = new Uint8Array(1);
|
|
@@ -1065,7 +936,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1065
936
|
});
|
|
1066
937
|
|
|
1067
938
|
await drmEngine.initForPlayback(
|
|
1068
|
-
manifest.variants, manifest.offlineSessionIds
|
|
939
|
+
manifest.variants, manifest.offlineSessionIds);
|
|
1069
940
|
drmEngine.newInitData('cenc', initData);
|
|
1070
941
|
await drmEngine.attach(mockVideo);
|
|
1071
942
|
|
|
@@ -1078,7 +949,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1078
949
|
drmInfos[0].keySystem = 'com.fake.NOT.clearkey';
|
|
1079
950
|
});
|
|
1080
951
|
|
|
1081
|
-
|
|
952
|
+
setDecodingInfoSpy(['org.w3.clearkey']);
|
|
1082
953
|
|
|
1083
954
|
// Configure clear keys (map of hex key IDs to keys)
|
|
1084
955
|
config.clearKeys = {
|
|
@@ -1124,7 +995,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1124
995
|
// Make it so that clear key setup fails by pretending we don't have it.
|
|
1125
996
|
// In reality, it was failing because of missing codec info, but any
|
|
1126
997
|
// failure should do for testing purposes.
|
|
1127
|
-
|
|
998
|
+
setDecodingInfoSpy([]);
|
|
1128
999
|
|
|
1129
1000
|
// Configure clear keys (map of hex key IDs to keys)
|
|
1130
1001
|
config.clearKeys = {
|
|
@@ -1139,8 +1010,8 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1139
1010
|
shaka.util.Error.Severity.CRITICAL,
|
|
1140
1011
|
shaka.util.Error.Category.DRM,
|
|
1141
1012
|
shaka.util.Error.Code.REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE));
|
|
1142
|
-
await expectAsync(drmEngine.initForPlayback(variants, []
|
|
1143
|
-
|
|
1013
|
+
await expectAsync(drmEngine.initForPlayback(variants, []))
|
|
1014
|
+
.toBeRejectedWith(expected);
|
|
1144
1015
|
});
|
|
1145
1016
|
|
|
1146
1017
|
it('fails with an error if setMediaKeys fails', async () => {
|
|
@@ -1635,7 +1506,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1635
1506
|
tweakDrmInfos((drmInfos) => {
|
|
1636
1507
|
drmInfos[0].keySystem = 'com.fake.NOT.clearkey';
|
|
1637
1508
|
});
|
|
1638
|
-
|
|
1509
|
+
setDecodingInfoSpy(['org.w3.clearkey']);
|
|
1639
1510
|
|
|
1640
1511
|
// Configure clear keys (map of hex key IDs to keys)
|
|
1641
1512
|
config.clearKeys = {
|
|
@@ -1819,32 +1690,19 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1819
1690
|
// Hold the MediaKeys query.
|
|
1820
1691
|
/** @type {!shaka.util.PublicPromise} */
|
|
1821
1692
|
const p = new shaka.util.PublicPromise();
|
|
1822
|
-
requestMediaKeySystemAccessSpy.and.returnValue(p);
|
|
1823
1693
|
decodingInfoSpy.and.returnValue(p);
|
|
1824
1694
|
|
|
1825
1695
|
const variants = manifest.variants;
|
|
1826
1696
|
const init = drmEngine.initForPlayback(
|
|
1827
|
-
variants, manifest.offlineSessionIds
|
|
1697
|
+
variants, manifest.offlineSessionIds);
|
|
1828
1698
|
|
|
1829
1699
|
// This flow should still return "success" when DrmEngine is destroyed.
|
|
1830
1700
|
await shaka.test.Util.shortDelay();
|
|
1831
1701
|
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
await expectAsync(init).toBeRejected();
|
|
1837
|
-
} else {
|
|
1838
|
-
// The first query has been made, which we are blocking.
|
|
1839
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
1840
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledWith(
|
|
1841
|
-
'drm.abc', jasmine.any(Array));
|
|
1842
|
-
await drmEngine.destroy();
|
|
1843
|
-
p.reject(new Error('')); // Fail drm.abc.
|
|
1844
|
-
await expectAsync(init).toBeRejected();
|
|
1845
|
-
// A second query was not made.
|
|
1846
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
1847
|
-
}
|
|
1702
|
+
expect(variants[0].decodingInfos.length).toBe(0);
|
|
1703
|
+
await drmEngine.destroy();
|
|
1704
|
+
p.reject(new Error('')); // Fail drm.abc.
|
|
1705
|
+
await expectAsync(init).toBeRejected();
|
|
1848
1706
|
expect(drmEngine.initialized()).toBe(false);
|
|
1849
1707
|
});
|
|
1850
1708
|
|
|
@@ -1852,23 +1710,14 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1852
1710
|
// Hold the MediaKeys query:
|
|
1853
1711
|
/** @type {!shaka.util.PublicPromise} */
|
|
1854
1712
|
const p = new shaka.util.PublicPromise();
|
|
1855
|
-
requestMediaKeySystemAccessSpy.and.returnValue(p);
|
|
1856
1713
|
decodingInfoSpy.and.returnValue(p);
|
|
1857
1714
|
|
|
1858
1715
|
const variants = manifest.variants;
|
|
1859
1716
|
const init = drmEngine.initForPlayback(
|
|
1860
|
-
variants, manifest.offlineSessionIds
|
|
1717
|
+
variants, manifest.offlineSessionIds);
|
|
1861
1718
|
|
|
1862
1719
|
await shaka.test.Util.shortDelay();
|
|
1863
|
-
|
|
1864
|
-
if (useMediaCapabilities) {
|
|
1865
|
-
expect(variants[0].decodingInfos.length).toBe(0);
|
|
1866
|
-
} else {
|
|
1867
|
-
// The first query has been made, which we are blocking.
|
|
1868
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledTimes(1);
|
|
1869
|
-
expect(requestMediaKeySystemAccessSpy).toHaveBeenCalledWith(
|
|
1870
|
-
'drm.abc', jasmine.any(Array));
|
|
1871
|
-
}
|
|
1720
|
+
expect(variants[0].decodingInfos.length).toBe(0);
|
|
1872
1721
|
await drmEngine.destroy();
|
|
1873
1722
|
p.resolve(); // Success for drm.abc.
|
|
1874
1723
|
await expectAsync(init).toBeRejected();
|
|
@@ -1885,7 +1734,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
1885
1734
|
|
|
1886
1735
|
const variants = manifest.variants;
|
|
1887
1736
|
const init = drmEngine.initForPlayback(
|
|
1888
|
-
variants, manifest.offlineSessionIds
|
|
1737
|
+
variants, manifest.offlineSessionIds);
|
|
1889
1738
|
|
|
1890
1739
|
await shaka.test.Util.shortDelay();
|
|
1891
1740
|
// We are blocked on createMediaKeys:
|
|
@@ -2164,6 +2013,26 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2164
2013
|
});
|
|
2165
2014
|
});
|
|
2166
2015
|
|
|
2016
|
+
describe('isFairPlayKeySystem', () => {
|
|
2017
|
+
it('should return true for FairPlay', () => {
|
|
2018
|
+
expect(shaka.media.DrmEngine.isFairPlayKeySystem(
|
|
2019
|
+
'com.apple.fps')).toBe(true);
|
|
2020
|
+
expect(shaka.media.DrmEngine.isFairPlayKeySystem(
|
|
2021
|
+
'com.apple.fps.1_0')).toBe(true);
|
|
2022
|
+
expect(shaka.media.DrmEngine.isFairPlayKeySystem(
|
|
2023
|
+
'com.apple.fps.2_0')).toBe(true);
|
|
2024
|
+
expect(shaka.media.DrmEngine.isFairPlayKeySystem(
|
|
2025
|
+
'com.apple.fps.3_0')).toBe(true);
|
|
2026
|
+
});
|
|
2027
|
+
|
|
2028
|
+
it('should return false for non-FairPlay key systems', () => {
|
|
2029
|
+
expect(shaka.media.DrmEngine.isFairPlayKeySystem(
|
|
2030
|
+
'com.widevine.alpha')).toBe(false);
|
|
2031
|
+
expect(shaka.media.DrmEngine.isFairPlayKeySystem(
|
|
2032
|
+
'com.abc.playready')).toBe(false);
|
|
2033
|
+
});
|
|
2034
|
+
});
|
|
2035
|
+
|
|
2167
2036
|
describe('getDrmInfo', () => {
|
|
2168
2037
|
it('includes correct info', async () => {
|
|
2169
2038
|
// Leave only one drmInfo
|
|
@@ -2179,7 +2048,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2179
2048
|
});
|
|
2180
2049
|
});
|
|
2181
2050
|
});
|
|
2182
|
-
|
|
2051
|
+
setDecodingInfoSpy(['drm.abc']);
|
|
2183
2052
|
|
|
2184
2053
|
// Key IDs in manifest
|
|
2185
2054
|
tweakDrmInfos((drmInfos) => {
|
|
@@ -2191,6 +2060,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2191
2060
|
videoRobustness: 'really_really_ridiculously_good',
|
|
2192
2061
|
distinctiveIdentifierRequired: true,
|
|
2193
2062
|
serverCertificate: null,
|
|
2063
|
+
serverCertificateUri: '',
|
|
2194
2064
|
sessionType: '',
|
|
2195
2065
|
individualizationServer: '',
|
|
2196
2066
|
persistentStateRequired: true,
|
|
@@ -2198,8 +2068,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2198
2068
|
drmEngine.configure(config);
|
|
2199
2069
|
|
|
2200
2070
|
const variants = manifest.variants;
|
|
2201
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
2202
|
-
useMediaCapabilities);
|
|
2071
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
2203
2072
|
expect(drmEngine.initialized()).toBe(true);
|
|
2204
2073
|
const drmInfo = drmEngine.getDrmInfo();
|
|
2205
2074
|
expect(drmInfo).toEqual({
|
|
@@ -2210,6 +2079,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2210
2079
|
audioRobustness: 'good',
|
|
2211
2080
|
videoRobustness: 'really_really_ridiculously_good',
|
|
2212
2081
|
serverCertificate: undefined,
|
|
2082
|
+
serverCertificateUri: '',
|
|
2213
2083
|
sessionType: 'temporary',
|
|
2214
2084
|
initData: [],
|
|
2215
2085
|
keyIds: new Set(['deadbeefdeadbeefdeadbeefdeadbeef']),
|
|
@@ -2227,6 +2097,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2227
2097
|
audioRobustness: 'good',
|
|
2228
2098
|
videoRobustness: 'really_really_ridiculously_good',
|
|
2229
2099
|
serverCertificate: undefined,
|
|
2100
|
+
serverCertificateUri: '',
|
|
2230
2101
|
initData: [],
|
|
2231
2102
|
keyIds: new Set(['deadbeefdeadbeefdeadbeefdeadbeef']),
|
|
2232
2103
|
};
|
|
@@ -2247,6 +2118,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2247
2118
|
persistentStateRequired: true,
|
|
2248
2119
|
videoRobustness: 'really_really_ridiculously_good',
|
|
2249
2120
|
serverCertificate: serverCert,
|
|
2121
|
+
serverCertificateUri: '',
|
|
2250
2122
|
initData: ['blah'],
|
|
2251
2123
|
keyIds: new Set(['deadbeefdeadbeefdeadbeefdeadbeef']),
|
|
2252
2124
|
};
|
|
@@ -2257,6 +2129,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2257
2129
|
persistentStateRequired: false,
|
|
2258
2130
|
audioRobustness: 'good',
|
|
2259
2131
|
serverCertificate: undefined,
|
|
2132
|
+
serverCertificateUri: '',
|
|
2260
2133
|
initData: ['init data'],
|
|
2261
2134
|
keyIds: new Set(['eadbeefdeadbeefdeadbeefdeadbeefd']),
|
|
2262
2135
|
};
|
|
@@ -2268,6 +2141,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2268
2141
|
audioRobustness: 'good',
|
|
2269
2142
|
videoRobustness: 'really_really_ridiculously_good',
|
|
2270
2143
|
serverCertificate: serverCert,
|
|
2144
|
+
serverCertificateUri: '',
|
|
2271
2145
|
initData: ['blah', 'init data'],
|
|
2272
2146
|
keyIds: new Set([
|
|
2273
2147
|
'deadbeefdeadbeefdeadbeefdeadbeef',
|
|
@@ -2278,6 +2152,50 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2278
2152
|
[drmInfoAudio]);
|
|
2279
2153
|
expect(returned).toEqual([drmInfoDesired]);
|
|
2280
2154
|
});
|
|
2155
|
+
|
|
2156
|
+
it('dedupes the merged init data based on keyId matching', () => {
|
|
2157
|
+
const serverCert = new Uint8Array(0);
|
|
2158
|
+
const drmInfoVideo = {
|
|
2159
|
+
keySystem: 'drm.abc',
|
|
2160
|
+
licenseServerUri: 'http://abc.drm/license',
|
|
2161
|
+
distinctiveIdentifierRequired: false,
|
|
2162
|
+
persistentStateRequired: true,
|
|
2163
|
+
videoRobustness: 'really_really_ridiculously_good',
|
|
2164
|
+
serverCertificate: serverCert,
|
|
2165
|
+
serverCertificateUri: '',
|
|
2166
|
+
initData: [{keyId: 'v-init'}],
|
|
2167
|
+
keyIds: new Set(['deadbeefdeadbeefdeadbeefdeadbeef']),
|
|
2168
|
+
};
|
|
2169
|
+
const drmInfoAudio = {
|
|
2170
|
+
keySystem: 'drm.abc',
|
|
2171
|
+
licenseServerUri: undefined,
|
|
2172
|
+
distinctiveIdentifierRequired: true,
|
|
2173
|
+
persistentStateRequired: false,
|
|
2174
|
+
audioRobustness: 'good',
|
|
2175
|
+
serverCertificate: undefined,
|
|
2176
|
+
serverCertificateUri: '',
|
|
2177
|
+
initData: [{keyId: 'v-init'}, {keyId: 'a-init'}],
|
|
2178
|
+
keyIds: new Set(['eadbeefdeadbeefdeadbeefdeadbeefd']),
|
|
2179
|
+
};
|
|
2180
|
+
const drmInfoDesired = {
|
|
2181
|
+
keySystem: 'drm.abc',
|
|
2182
|
+
licenseServerUri: 'http://abc.drm/license',
|
|
2183
|
+
distinctiveIdentifierRequired: true,
|
|
2184
|
+
persistentStateRequired: true,
|
|
2185
|
+
audioRobustness: 'good',
|
|
2186
|
+
videoRobustness: 'really_really_ridiculously_good',
|
|
2187
|
+
serverCertificate: serverCert,
|
|
2188
|
+
serverCertificateUri: '',
|
|
2189
|
+
initData: [{keyId: 'v-init'}, {keyId: 'a-init'}],
|
|
2190
|
+
keyIds: new Set([
|
|
2191
|
+
'deadbeefdeadbeefdeadbeefdeadbeef',
|
|
2192
|
+
'eadbeefdeadbeefdeadbeefdeadbeefd',
|
|
2193
|
+
]),
|
|
2194
|
+
};
|
|
2195
|
+
const returned = shaka.media.DrmEngine.getCommonDrmInfos([drmInfoVideo],
|
|
2196
|
+
[drmInfoAudio]);
|
|
2197
|
+
expect(returned).toEqual([drmInfoDesired]);
|
|
2198
|
+
});
|
|
2281
2199
|
}); // describe('getCommonDrmInfos')
|
|
2282
2200
|
|
|
2283
2201
|
describe('configure', () => {
|
|
@@ -2371,8 +2289,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2371
2289
|
});
|
|
2372
2290
|
|
|
2373
2291
|
const variants = manifest.variants;
|
|
2374
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
2375
|
-
useMediaCapabilities);
|
|
2292
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
2376
2293
|
});
|
|
2377
2294
|
|
|
2378
2295
|
it('waits until update() is complete', async () => {
|
|
@@ -2478,25 +2395,10 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2478
2395
|
|
|
2479
2396
|
async function initAndAttach() {
|
|
2480
2397
|
const variants = manifest.variants;
|
|
2481
|
-
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds
|
|
2482
|
-
useMediaCapabilities);
|
|
2398
|
+
await drmEngine.initForPlayback(variants, manifest.offlineSessionIds);
|
|
2483
2399
|
await drmEngine.attach(mockVideo);
|
|
2484
2400
|
}
|
|
2485
2401
|
|
|
2486
|
-
function setRequestMediaKeySystemAccessSpy(acceptableKeySystems) {
|
|
2487
|
-
// TODO: Setting both the requestMediaKeySystemAccessSpy and decodingInfoSpy
|
|
2488
|
-
// as a temporary solution. Only decodingInfoSpy is needed once we use
|
|
2489
|
-
// decodingInfo API to get mediaKeySystemAccess.
|
|
2490
|
-
setDecodingInfoSpy(acceptableKeySystems);
|
|
2491
|
-
requestMediaKeySystemAccessSpy.and.callFake((keySystem) => {
|
|
2492
|
-
if (!acceptableKeySystems.includes(keySystem)) {
|
|
2493
|
-
return Promise.reject(new Error(''));
|
|
2494
|
-
}
|
|
2495
|
-
mockMediaKeySystemAccess.keySystem = keySystem;
|
|
2496
|
-
return Promise.resolve(mockMediaKeySystemAccess);
|
|
2497
|
-
});
|
|
2498
|
-
}
|
|
2499
|
-
|
|
2500
2402
|
function setDecodingInfoSpy(acceptableKeySystems) {
|
|
2501
2403
|
decodingInfoSpy.and.callFake((config) => {
|
|
2502
2404
|
const keySystem = config && config.keySystemConfiguration ?
|
|
@@ -2588,6 +2490,7 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2588
2490
|
distinctiveIdentifierRequired: false,
|
|
2589
2491
|
persistentStateRequired: false,
|
|
2590
2492
|
serverCertificate: serverCert,
|
|
2493
|
+
serverCertificateUri: '',
|
|
2591
2494
|
individualizationServer: '',
|
|
2592
2495
|
sessionType: '',
|
|
2593
2496
|
videoRobustness: '',
|
|
@@ -2613,4 +2516,4 @@ function testDrmEngine(useMediaCapabilities) {
|
|
|
2613
2516
|
callback(manifest.variants[0].audio.drmInfos);
|
|
2614
2517
|
}
|
|
2615
2518
|
}
|
|
2616
|
-
}
|
|
2519
|
+
});
|