shaka-player 3.3.4 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build-and-test.yaml +0 -1
- package/.github/workflows/demo-version-index.yaml +8 -0
- package/.github/workflows/release-please.yaml +23 -2
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/.github/workflows/sync-labels.yaml +33 -0
- package/.github/workflows/update-issues.yaml +29 -0
- package/.github/workflows/validate-pr-title.yaml +35 -0
- package/AUTHORS +1 -0
- package/CHANGELOG.md +198 -32
- package/CONTRIBUTORS +1 -0
- package/README.md +10 -7
- package/app-engine/demo-version-index/README.md +3 -3
- package/app-engine/demo-version-index/app.yaml +27 -1
- package/app-engine/demo-version-index/generate.py +164 -0
- package/app-engine/demo-version-index/main.py +4 -155
- package/app-engine/demo-version-index/requirements.txt +0 -1
- package/build/README.md +2 -2
- package/build/compiler.py +1 -1
- package/build/generateTsDefs.py +0 -2
- package/build/shaka-lab.yaml +0 -2
- package/build/test.py +7 -1
- package/build/types/core +0 -1
- package/build/types/polyfill +0 -3
- package/demo/common/asset.js +17 -1
- package/demo/common/assets.js +29 -0
- package/demo/common/message_ids.js +6 -3
- package/demo/config.js +10 -11
- package/demo/custom.js +39 -0
- package/demo/demo_utils.js +0 -1
- package/demo/locales/en.json +6 -3
- package/demo/locales/source.json +22 -10
- package/demo/main.js +9 -6
- package/demo/search.js +2 -1
- package/dist/controls.css +1 -1
- package/dist/demo.compiled.debug.js +71 -64
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +71 -64
- package/dist/demo.compiled.map +3 -3
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +16 -20
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +32 -28
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +32 -28
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +78 -83
- package/dist/shaka-player.compiled.debug.d.ts +78 -83
- package/dist/shaka-player.compiled.debug.externs.js +126 -126
- package/dist/shaka-player.compiled.debug.js +426 -483
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +126 -126
- package/dist/shaka-player.compiled.js +838 -856
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +80 -83
- package/dist/shaka-player.ui.debug.d.ts +80 -83
- package/dist/shaka-player.ui.debug.externs.js +134 -126
- package/dist/shaka-player.ui.debug.js +488 -543
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +134 -126
- package/dist/shaka-player.ui.js +980 -994
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/config.md +0 -2
- package/docs/tutorials/drm-config.md +5 -0
- package/docs/tutorials/fairplay.md +7 -22
- package/docs/tutorials/faq.md +0 -11
- package/docs/tutorials/index.json +2 -8
- package/docs/tutorials/plugins.md +1 -3
- package/docs/tutorials/upgrade.md +83 -11
- package/externs/polyfill.js +15 -0
- package/externs/shaka/manifest.js +5 -1
- package/externs/shaka/net.js +12 -0
- package/externs/shaka/offline.js +5 -1
- package/externs/shaka/player.js +39 -32
- package/externs/shaka/text.js +12 -12
- package/externs/sourcebuffer.js +15 -0
- package/lib/ads/client_side_ad.js +13 -2
- package/lib/ads/client_side_ad_manager.js +22 -4
- package/lib/cast/cast_utils.js +0 -1
- package/lib/dash/content_protection.js +85 -5
- package/lib/dash/dash_parser.js +1 -1
- package/lib/hls/hls_parser.js +378 -743
- package/lib/hls/manifest_text_parser.js +2 -3
- package/lib/media/drm_engine.js +102 -53
- package/lib/media/gap_jumping_controller.js +10 -45
- package/lib/media/media_source_engine.js +87 -15
- package/lib/media/playhead.js +2 -5
- package/lib/media/presentation_timeline.js +1 -2
- package/lib/media/segment_index.js +13 -46
- package/lib/media/segment_reference.js +47 -1
- package/lib/media/streaming_engine.js +29 -11
- package/lib/media/time_ranges_utils.js +4 -9
- package/lib/net/networking_engine.js +3 -0
- 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 +1 -0
- package/lib/offline/storage.js +100 -132
- package/lib/player.js +17 -201
- package/lib/polyfill/media_capabilities.js +12 -6
- package/lib/polyfill/mediasource.js +0 -28
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +2 -0
- package/lib/text/cue.js +0 -6
- package/lib/text/lrc_text_parser.js +8 -0
- package/lib/text/mp4_ttml_parser.js +8 -0
- package/lib/text/mp4_vtt_parser.js +8 -0
- package/lib/text/sbv_text_parser.js +8 -0
- package/lib/text/simple_text_displayer.js +1 -7
- package/lib/text/srt_text_parser.js +8 -0
- package/lib/text/ssa_text_parser.js +8 -0
- package/lib/text/text_engine.js +19 -3
- package/lib/text/ttml_text_parser.js +8 -0
- package/lib/text/ui_text_displayer.js +1 -7
- package/lib/text/vtt_text_parser.js +24 -2
- package/lib/text/web_vtt_generator.js +1 -7
- package/lib/util/error.js +9 -13
- package/lib/util/fairplay_utils.js +109 -0
- package/lib/util/functional.js +0 -42
- package/lib/util/mime_utils.js +2 -0
- package/lib/util/platform.js +45 -0
- package/lib/util/player_configuration.js +12 -6
- package/lib/util/pssh.js +23 -4
- package/lib/util/stream_utils.js +92 -22
- package/lib/util/uint8array_utils.js +0 -16
- package/lib/util/xml_utils.js +1 -1
- package/package.json +1 -1
- package/roadmap.md +19 -19
- package/shaka-player.uncompiled.js +0 -3
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_content_protection_unit.js +44 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- package/test/dash/dash_parser_segment_template_unit.js +3 -4
- package/test/demo/demo_unit.js +2 -1
- package/test/hls/hls_live_unit.js +99 -220
- package/test/hls/hls_parser_unit.js +515 -432
- package/test/media/drm_engine_unit.js +86 -120
- package/test/media/media_source_engine_integration.js +26 -3
- package/test/media/media_source_engine_unit.js +7 -6
- package/test/media/playhead_unit.js +27 -191
- package/test/media/segment_index_unit.js +15 -25
- package/test/media/streaming_engine_integration.js +4 -39
- package/test/media/streaming_engine_unit.js +3 -2
- package/test/media/time_ranges_utils_unit.js +0 -5
- package/test/offline/manifest_convert_unit.js +34 -4
- package/test/offline/offline_manifest_parser_unit.js +1 -0
- package/test/offline/storage_integration.js +5 -4
- package/test/player_external.js +0 -6
- package/test/player_integration.js +16 -0
- package/test/player_unit.js +26 -0
- package/test/test/util/fake_media_source_engine.js +11 -4
- package/test/test/util/manifest_generator.js +3 -1
- package/test/test/util/manifest_parser_util.js +4 -1
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +1 -0
- package/test/test/util/test_scheme.js +24 -1
- package/test/test/util/util.js +4 -4
- package/test/text/cue_integration.js +2 -2
- package/test/text/lrc_text_parser_unit.js +6 -7
- package/test/text/mp4_ttml_parser_unit.js +6 -4
- package/test/text/mp4_vtt_parser_unit.js +6 -5
- package/test/text/sbv_text_parser_unit.js +5 -6
- package/test/text/srt_text_parser_unit.js +5 -6
- package/test/text/ssa_text_parser_unit.js +17 -29
- package/test/text/text_engine_unit.js +45 -5
- package/test/text/ttml_text_parser_unit.js +77 -77
- package/test/text/vtt_text_parser_unit.js +55 -57
- package/test/ui/ui_integration.js +0 -16
- package/test/ui/ui_unit.js +27 -0
- package/test/util/cmcd_manager_unit.js +3 -0
- package/test/util/stream_utils_unit.js +23 -7
- package/ui/controls.js +65 -40
- package/ui/fullscreen_button.js +26 -6
- package/ui/less/containers.less +3 -3
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +5 -0
- package/ui/resolution_selection.js +31 -33
- package/ui/ui.js +0 -17
- package/docs/tutorials/upgrade-v2-5.md +0 -441
- package/docs/tutorials/upgrade-v3.md +0 -38
- package/lib/polyfill/mathround.js +0 -49
- package/lib/polyfill/patchedmediakeys_apple.js +0 -744
- package/lib/polyfill/patchedmediakeys_ms.js +0 -698
- package/lib/util/mutex.js +0 -52
- package/test/util/functional_unit.js +0 -82
|
@@ -756,11 +756,6 @@ describe('DrmEngine', () => {
|
|
|
756
756
|
expect(mockVideo.setMediaKeys).not.toHaveBeenCalled();
|
|
757
757
|
});
|
|
758
758
|
|
|
759
|
-
it('sets MediaKeys for encrypted content', async () => {
|
|
760
|
-
await initAndAttach();
|
|
761
|
-
expect(mockVideo.setMediaKeys).toHaveBeenCalledWith(mockMediaKeys);
|
|
762
|
-
});
|
|
763
|
-
|
|
764
759
|
it('sets server certificate if present in config', async () => {
|
|
765
760
|
const cert = new Uint8Array(1);
|
|
766
761
|
config.advanced['drm.abc'] = createAdvancedConfig(cert);
|
|
@@ -857,7 +852,7 @@ describe('DrmEngine', () => {
|
|
|
857
852
|
/** @type {!Uint8Array} */
|
|
858
853
|
const initData1 = new Uint8Array(5);
|
|
859
854
|
/** @type {!Uint8Array} */
|
|
860
|
-
const initData2 = new Uint8Array(
|
|
855
|
+
const initData2 = new Uint8Array(1);
|
|
861
856
|
/** @type {!Uint8Array} */
|
|
862
857
|
const initData3 = new Uint8Array(10);
|
|
863
858
|
|
|
@@ -999,12 +994,23 @@ describe('DrmEngine', () => {
|
|
|
999
994
|
mockVideo.setMediaKeys.and.returnValue(Promise.reject(
|
|
1000
995
|
new Error('whoops!')));
|
|
1001
996
|
|
|
1002
|
-
|
|
997
|
+
tweakDrmInfos((drmInfos) => {
|
|
998
|
+
drmInfos[0].initData = [
|
|
999
|
+
{initData: new Uint8Array(1), initDataType: 'cenc', keyId: null},
|
|
1000
|
+
];
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
onErrorSpy.and.stub();
|
|
1004
|
+
|
|
1005
|
+
await initAndAttach();
|
|
1006
|
+
|
|
1007
|
+
expect(onErrorSpy).toHaveBeenCalled();
|
|
1008
|
+
const error = onErrorSpy.calls.argsFor(0)[0];
|
|
1009
|
+
shaka.test.Util.expectToEqualError(error, new shaka.util.Error(
|
|
1003
1010
|
shaka.util.Error.Severity.CRITICAL,
|
|
1004
1011
|
shaka.util.Error.Category.DRM,
|
|
1005
1012
|
shaka.util.Error.Code.FAILED_TO_ATTACH_TO_VIDEO,
|
|
1006
1013
|
'whoops!'));
|
|
1007
|
-
await expectAsync(initAndAttach()).toBeRejectedWith(expected);
|
|
1008
1014
|
});
|
|
1009
1015
|
|
|
1010
1016
|
it('fails with an error if setServerCertificate fails', async () => {
|
|
@@ -1067,10 +1073,8 @@ describe('DrmEngine', () => {
|
|
|
1067
1073
|
const initData1 = new Uint8Array(1);
|
|
1068
1074
|
const initData2 = new Uint8Array(2);
|
|
1069
1075
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
mockVideo.on['encrypted'](
|
|
1073
|
-
{initDataType: 'cenc', initData: initData2, keyId: null});
|
|
1076
|
+
await sendEncryptedEvent('webm', initData1);
|
|
1077
|
+
await sendEncryptedEvent('cenc', initData2);
|
|
1074
1078
|
|
|
1075
1079
|
expect(mockMediaKeys.createSession).toHaveBeenCalledTimes(2);
|
|
1076
1080
|
expect(session1.generateRequest)
|
|
@@ -1081,32 +1085,23 @@ describe('DrmEngine', () => {
|
|
|
1081
1085
|
|
|
1082
1086
|
it('suppresses duplicate initDatas', async () => {
|
|
1083
1087
|
await initAndAttach();
|
|
1088
|
+
|
|
1084
1089
|
const initData1 = new Uint8Array(1);
|
|
1085
|
-
const initData2 = new Uint8Array(1); // identical to initData1
|
|
1086
1090
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
mockVideo.on['encrypted'](
|
|
1090
|
-
{initDataType: 'cenc', initData: initData2, keyId: null});
|
|
1091
|
+
await sendEncryptedEvent('webm', initData1);
|
|
1092
|
+
await sendEncryptedEvent('cenc'); // identical to webm initData
|
|
1091
1093
|
|
|
1092
1094
|
expect(mockMediaKeys.createSession).toHaveBeenCalledTimes(1);
|
|
1093
1095
|
expect(session1.generateRequest)
|
|
1094
1096
|
.toHaveBeenCalledWith('webm', initData1);
|
|
1095
1097
|
});
|
|
1096
1098
|
|
|
1097
|
-
it('
|
|
1098
|
-
// Set up an init data override in the manifest:
|
|
1099
|
-
tweakDrmInfos((drmInfos) => {
|
|
1100
|
-
drmInfos[0].initData = [
|
|
1101
|
-
{initData: new Uint8Array(0), initDataType: 'cenc', keyId: null},
|
|
1102
|
-
];
|
|
1103
|
-
});
|
|
1104
|
-
|
|
1099
|
+
it('set media keys when not already done at startup', async () => {
|
|
1105
1100
|
await initAndAttach();
|
|
1106
|
-
|
|
1101
|
+
await sendEncryptedEvent();
|
|
1102
|
+
|
|
1103
|
+
expect(mockVideo.setMediaKeys).toHaveBeenCalledTimes(1);
|
|
1107
1104
|
expect(mockMediaKeys.createSession).toHaveBeenCalledTimes(1);
|
|
1108
|
-
// We aren't even listening for 'encrypted' events.
|
|
1109
|
-
expect(mockVideo.on['encrypted']).toBe(undefined);
|
|
1110
1105
|
});
|
|
1111
1106
|
|
|
1112
1107
|
it('dispatches an error if createSession fails', async () => {
|
|
@@ -1114,9 +1109,7 @@ describe('DrmEngine', () => {
|
|
|
1114
1109
|
onErrorSpy.and.stub();
|
|
1115
1110
|
|
|
1116
1111
|
await initAndAttach();
|
|
1117
|
-
|
|
1118
|
-
mockVideo.on['encrypted'](
|
|
1119
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1112
|
+
await sendEncryptedEvent();
|
|
1120
1113
|
|
|
1121
1114
|
expect(onErrorSpy).toHaveBeenCalled();
|
|
1122
1115
|
const error = onErrorSpy.calls.argsFor(0)[0];
|
|
@@ -1136,9 +1129,7 @@ describe('DrmEngine', () => {
|
|
|
1136
1129
|
onErrorSpy.and.stub();
|
|
1137
1130
|
|
|
1138
1131
|
await initAndAttach();
|
|
1139
|
-
|
|
1140
|
-
mockVideo.on['encrypted'](
|
|
1141
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1132
|
+
await sendEncryptedEvent();
|
|
1142
1133
|
|
|
1143
1134
|
expect(onErrorSpy).toHaveBeenCalled();
|
|
1144
1135
|
const error = onErrorSpy.calls.argsFor(0)[0];
|
|
@@ -1152,9 +1143,7 @@ describe('DrmEngine', () => {
|
|
|
1152
1143
|
describe('message', () => {
|
|
1153
1144
|
it('is listened for', async () => {
|
|
1154
1145
|
await initAndAttach();
|
|
1155
|
-
|
|
1156
|
-
mockVideo.on['encrypted'](
|
|
1157
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1146
|
+
await sendEncryptedEvent();
|
|
1158
1147
|
|
|
1159
1148
|
expect(session1.addEventListener).toHaveBeenCalledWith(
|
|
1160
1149
|
'message', jasmine.any(Function), jasmine.anything());
|
|
@@ -1194,9 +1183,7 @@ describe('DrmEngine', () => {
|
|
|
1194
1183
|
onErrorSpy.and.stub();
|
|
1195
1184
|
|
|
1196
1185
|
await initAndAttach();
|
|
1197
|
-
|
|
1198
|
-
mockVideo.on['encrypted'](
|
|
1199
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1186
|
+
await sendEncryptedEvent();
|
|
1200
1187
|
|
|
1201
1188
|
// Simulate a permission error from the web server.
|
|
1202
1189
|
const netError = new shaka.util.Error(
|
|
@@ -1232,9 +1219,7 @@ describe('DrmEngine', () => {
|
|
|
1232
1219
|
async function sendMessageTest(
|
|
1233
1220
|
expectedUrl, messageType = 'license-request') {
|
|
1234
1221
|
await initAndAttach();
|
|
1235
|
-
|
|
1236
|
-
mockVideo.on['encrypted'](
|
|
1237
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1222
|
+
await sendEncryptedEvent();
|
|
1238
1223
|
|
|
1239
1224
|
const operation = shaka.util.AbortableOperation.completed({});
|
|
1240
1225
|
fakeNetEngine.request.and.returnValue(operation);
|
|
@@ -1256,9 +1241,7 @@ describe('DrmEngine', () => {
|
|
|
1256
1241
|
describe('keystatuseschange', () => {
|
|
1257
1242
|
it('is listened for', async () => {
|
|
1258
1243
|
await initAndAttach();
|
|
1259
|
-
|
|
1260
|
-
mockVideo.on['encrypted'](
|
|
1261
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1244
|
+
await sendEncryptedEvent();
|
|
1262
1245
|
|
|
1263
1246
|
expect(session1.addEventListener).toHaveBeenCalledWith(
|
|
1264
1247
|
'keystatuseschange', jasmine.any(Function), jasmine.anything());
|
|
@@ -1266,9 +1249,7 @@ describe('DrmEngine', () => {
|
|
|
1266
1249
|
|
|
1267
1250
|
it('triggers callback', async () => {
|
|
1268
1251
|
await initAndAttach();
|
|
1269
|
-
|
|
1270
|
-
mockVideo.on['encrypted'](
|
|
1271
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1252
|
+
await sendEncryptedEvent();
|
|
1272
1253
|
|
|
1273
1254
|
const keyId1 = makeKeyId(1);
|
|
1274
1255
|
const keyId2 = makeKeyId(2);
|
|
@@ -1294,10 +1275,7 @@ describe('DrmEngine', () => {
|
|
|
1294
1275
|
// See https://github.com/shaka-project/shaka-player/issues/1541
|
|
1295
1276
|
it('does not update public key statuses before callback', async () => {
|
|
1296
1277
|
await initAndAttach();
|
|
1297
|
-
|
|
1298
|
-
const initData = new Uint8Array(0);
|
|
1299
|
-
mockVideo.on['encrypted'](
|
|
1300
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1278
|
+
await sendEncryptedEvent();
|
|
1301
1279
|
|
|
1302
1280
|
const keyId1 = makeKeyId(1);
|
|
1303
1281
|
const keyId2 = makeKeyId(2);
|
|
@@ -1374,9 +1352,7 @@ describe('DrmEngine', () => {
|
|
|
1374
1352
|
await initAndAttach();
|
|
1375
1353
|
expect(onErrorSpy).not.toHaveBeenCalled();
|
|
1376
1354
|
|
|
1377
|
-
|
|
1378
|
-
mockVideo.on['encrypted'](
|
|
1379
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1355
|
+
await sendEncryptedEvent();
|
|
1380
1356
|
|
|
1381
1357
|
const keyId1 = makeKeyId(1);
|
|
1382
1358
|
const keyId2 = makeKeyId(2);
|
|
@@ -1423,9 +1399,7 @@ describe('DrmEngine', () => {
|
|
|
1423
1399
|
await initAndAttach();
|
|
1424
1400
|
expect(onErrorSpy).not.toHaveBeenCalled();
|
|
1425
1401
|
|
|
1426
|
-
|
|
1427
|
-
mockVideo.on['encrypted'](
|
|
1428
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1402
|
+
await sendEncryptedEvent();
|
|
1429
1403
|
|
|
1430
1404
|
const keyId1 = makeKeyId(1);
|
|
1431
1405
|
const keyId2 = makeKeyId(2);
|
|
@@ -1469,9 +1443,7 @@ describe('DrmEngine', () => {
|
|
|
1469
1443
|
const license = new Uint8Array(0);
|
|
1470
1444
|
|
|
1471
1445
|
await initAndAttach();
|
|
1472
|
-
|
|
1473
|
-
mockVideo.on['encrypted'](
|
|
1474
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1446
|
+
await sendEncryptedEvent();
|
|
1475
1447
|
|
|
1476
1448
|
fakeNetEngine.setResponseValue('http://abc.drm/license', license);
|
|
1477
1449
|
const message = new Uint8Array(0);
|
|
@@ -1530,9 +1502,8 @@ describe('DrmEngine', () => {
|
|
|
1530
1502
|
|
|
1531
1503
|
it('publishes an event if update succeeds', async () => {
|
|
1532
1504
|
await initAndAttach();
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1505
|
+
await sendEncryptedEvent();
|
|
1506
|
+
|
|
1536
1507
|
const message = new Uint8Array(0);
|
|
1537
1508
|
session1.on['message']({target: session1, message: message});
|
|
1538
1509
|
session1.update.and.returnValue(Promise.resolve());
|
|
@@ -1548,9 +1519,7 @@ describe('DrmEngine', () => {
|
|
|
1548
1519
|
const license = new Uint8Array(0);
|
|
1549
1520
|
|
|
1550
1521
|
await initAndAttach();
|
|
1551
|
-
|
|
1552
|
-
mockVideo.on['encrypted'](
|
|
1553
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
1522
|
+
await sendEncryptedEvent();
|
|
1554
1523
|
|
|
1555
1524
|
fakeNetEngine.setResponseValue('http://abc.drm/license', license);
|
|
1556
1525
|
const message = new Uint8Array(0);
|
|
@@ -1571,12 +1540,9 @@ describe('DrmEngine', () => {
|
|
|
1571
1540
|
describe('destroy', () => {
|
|
1572
1541
|
it('tears down MediaKeys and active sessions', async () => {
|
|
1573
1542
|
await initAndAttach();
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1578
|
-
mockVideo.on['encrypted'](
|
|
1579
|
-
{initDataType: 'webm', initData: initData2, keyId: null});
|
|
1543
|
+
|
|
1544
|
+
await sendEncryptedEvent('webm');
|
|
1545
|
+
await sendEncryptedEvent('cenc', new Uint8Array(2));
|
|
1580
1546
|
|
|
1581
1547
|
const message = new Uint8Array(0);
|
|
1582
1548
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1601,12 +1567,8 @@ describe('DrmEngine', () => {
|
|
|
1601
1567
|
drmEngine.configure(config);
|
|
1602
1568
|
|
|
1603
1569
|
await initAndAttach();
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
mockVideo.on['encrypted'](
|
|
1607
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1608
|
-
mockVideo.on['encrypted'](
|
|
1609
|
-
{initDataType: 'webm', initData: initData2, keyId: null});
|
|
1570
|
+
await sendEncryptedEvent('webm');
|
|
1571
|
+
await sendEncryptedEvent('cenc', new Uint8Array(2));
|
|
1610
1572
|
|
|
1611
1573
|
const message = new Uint8Array(0);
|
|
1612
1574
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1627,12 +1589,8 @@ describe('DrmEngine', () => {
|
|
|
1627
1589
|
|
|
1628
1590
|
it('swallows errors when closing sessions', async () => {
|
|
1629
1591
|
await initAndAttach();
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
mockVideo.on['encrypted'](
|
|
1633
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1634
|
-
mockVideo.on['encrypted'](
|
|
1635
|
-
{initDataType: 'webm', initData: initData2, keyId: null});
|
|
1592
|
+
await sendEncryptedEvent('webm');
|
|
1593
|
+
await sendEncryptedEvent('cenc', new Uint8Array(2));
|
|
1636
1594
|
|
|
1637
1595
|
const message = new Uint8Array(0);
|
|
1638
1596
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1648,12 +1606,8 @@ describe('DrmEngine', () => {
|
|
|
1648
1606
|
|
|
1649
1607
|
it('swallows errors when clearing MediaKeys', async () => {
|
|
1650
1608
|
await initAndAttach();
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
mockVideo.on['encrypted'](
|
|
1654
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1655
|
-
mockVideo.on['encrypted'](
|
|
1656
|
-
{initDataType: 'webm', initData: initData2, keyId: null});
|
|
1609
|
+
await sendEncryptedEvent('webm');
|
|
1610
|
+
await sendEncryptedEvent('cenc', new Uint8Array(2));
|
|
1657
1611
|
|
|
1658
1612
|
const message = new Uint8Array(0);
|
|
1659
1613
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1732,6 +1686,14 @@ describe('DrmEngine', () => {
|
|
|
1732
1686
|
const p1 = new shaka.util.PublicPromise();
|
|
1733
1687
|
mockVideo.setMediaKeys.and.returnValue(p1);
|
|
1734
1688
|
|
|
1689
|
+
onErrorSpy.and.stub();
|
|
1690
|
+
|
|
1691
|
+
tweakDrmInfos((drmInfos) => {
|
|
1692
|
+
drmInfos[0].initData = [
|
|
1693
|
+
{initData: new Uint8Array(1), initDataType: 'cenc', keyId: null},
|
|
1694
|
+
];
|
|
1695
|
+
});
|
|
1696
|
+
|
|
1735
1697
|
const init = expectAsync(initAndAttach()).toBeRejected();
|
|
1736
1698
|
|
|
1737
1699
|
await shaka.test.Util.shortDelay();
|
|
@@ -1745,10 +1707,12 @@ describe('DrmEngine', () => {
|
|
|
1745
1707
|
const destroy = drmEngine.destroy();
|
|
1746
1708
|
const fail = async () => {
|
|
1747
1709
|
await shaka.test.Util.shortDelay();
|
|
1748
|
-
|
|
1710
|
+
shaka.log.warning('fail');
|
|
1711
|
+
p1.reject(new Error('titi'));
|
|
1749
1712
|
};
|
|
1750
1713
|
const success = async () => {
|
|
1751
1714
|
await shaka.test.Util.shortDelay();
|
|
1715
|
+
shaka.log.warning('success');
|
|
1752
1716
|
p2.resolve();
|
|
1753
1717
|
};
|
|
1754
1718
|
await Promise.all([init, destroy, fail(), success()]);
|
|
@@ -1760,6 +1724,12 @@ describe('DrmEngine', () => {
|
|
|
1760
1724
|
const p1 = new shaka.util.PublicPromise();
|
|
1761
1725
|
mockVideo.setMediaKeys.and.returnValue(p1);
|
|
1762
1726
|
|
|
1727
|
+
tweakDrmInfos((drmInfos) => {
|
|
1728
|
+
drmInfos[0].initData = [
|
|
1729
|
+
{initData: new Uint8Array(1), initDataType: 'cenc', keyId: null},
|
|
1730
|
+
];
|
|
1731
|
+
});
|
|
1732
|
+
|
|
1763
1733
|
const init = expectAsync(initAndAttach()).toBeRejected();
|
|
1764
1734
|
|
|
1765
1735
|
await shaka.test.Util.shortDelay();
|
|
@@ -1837,9 +1807,7 @@ describe('DrmEngine', () => {
|
|
|
1837
1807
|
session1.generateRequest.and.returnValue(p);
|
|
1838
1808
|
|
|
1839
1809
|
await initAndAttach();
|
|
1840
|
-
|
|
1841
|
-
mockVideo.on['encrypted'](
|
|
1842
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1810
|
+
await sendEncryptedEvent();
|
|
1843
1811
|
|
|
1844
1812
|
// We are now blocked on generateRequest:
|
|
1845
1813
|
expect(session1.generateRequest).toHaveBeenCalledTimes(1);
|
|
@@ -1858,9 +1826,7 @@ describe('DrmEngine', () => {
|
|
|
1858
1826
|
fakeNetEngine.request.and.returnValue(operation);
|
|
1859
1827
|
|
|
1860
1828
|
await initAndAttach();
|
|
1861
|
-
|
|
1862
|
-
mockVideo.on['encrypted'](
|
|
1863
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1829
|
+
await sendEncryptedEvent();
|
|
1864
1830
|
|
|
1865
1831
|
const message = new Uint8Array(0);
|
|
1866
1832
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1889,9 +1855,7 @@ describe('DrmEngine', () => {
|
|
|
1889
1855
|
fakeNetEngine.request.and.returnValue(operation);
|
|
1890
1856
|
|
|
1891
1857
|
await initAndAttach();
|
|
1892
|
-
|
|
1893
|
-
mockVideo.on['encrypted'](
|
|
1894
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1858
|
+
await sendEncryptedEvent();
|
|
1895
1859
|
|
|
1896
1860
|
const message = new Uint8Array(0);
|
|
1897
1861
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1919,9 +1883,7 @@ describe('DrmEngine', () => {
|
|
|
1919
1883
|
session1.update.and.returnValue(p);
|
|
1920
1884
|
|
|
1921
1885
|
await initAndAttach();
|
|
1922
|
-
|
|
1923
|
-
mockVideo.on['encrypted'](
|
|
1924
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1886
|
+
await sendEncryptedEvent();
|
|
1925
1887
|
|
|
1926
1888
|
const message = new Uint8Array(0);
|
|
1927
1889
|
session1.on['message']({target: session1, message: message});
|
|
@@ -1955,12 +1917,8 @@ describe('DrmEngine', () => {
|
|
|
1955
1917
|
session1.close.and.returnValue(rejected);
|
|
1956
1918
|
session2.close.and.returnValue(rejected);
|
|
1957
1919
|
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
mockVideo.on['encrypted'](
|
|
1961
|
-
{initDataType: 'webm', initData: initData1, keyId: null});
|
|
1962
|
-
mockVideo.on['encrypted'](
|
|
1963
|
-
{initDataType: 'webm', initData: initData2, keyId: null});
|
|
1920
|
+
await sendEncryptedEvent('webm');
|
|
1921
|
+
await sendEncryptedEvent('cenc', new Uint8Array(2));
|
|
1964
1922
|
|
|
1965
1923
|
// Still resolve these since we are mocking close and closed. This
|
|
1966
1924
|
// ensures DrmEngine is in the correct state.
|
|
@@ -2185,9 +2143,7 @@ describe('DrmEngine', () => {
|
|
|
2185
2143
|
mockVideo.paused = true;
|
|
2186
2144
|
|
|
2187
2145
|
await initAndAttach();
|
|
2188
|
-
|
|
2189
|
-
mockVideo.on['encrypted'](
|
|
2190
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
2146
|
+
await sendEncryptedEvent();
|
|
2191
2147
|
|
|
2192
2148
|
const operation = shaka.util.AbortableOperation.completed({});
|
|
2193
2149
|
fakeNetEngine.request.and.returnValue(operation);
|
|
@@ -2213,9 +2169,7 @@ describe('DrmEngine', () => {
|
|
|
2213
2169
|
mockVideo.paused = true;
|
|
2214
2170
|
|
|
2215
2171
|
await initAndAttach();
|
|
2216
|
-
|
|
2217
|
-
mockVideo.on['encrypted'](
|
|
2218
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
2172
|
+
await sendEncryptedEvent();
|
|
2219
2173
|
|
|
2220
2174
|
const operation = shaka.util.AbortableOperation.completed({});
|
|
2221
2175
|
fakeNetEngine.request.and.returnValue(operation);
|
|
@@ -2330,10 +2284,9 @@ describe('DrmEngine', () => {
|
|
|
2330
2284
|
session1.expiration = NaN;
|
|
2331
2285
|
|
|
2332
2286
|
await initAndAttach();
|
|
2333
|
-
|
|
2287
|
+
await sendEncryptedEvent();
|
|
2288
|
+
|
|
2334
2289
|
const message = new Uint8Array(0);
|
|
2335
|
-
mockVideo.on['encrypted'](
|
|
2336
|
-
{initDataType: 'webm', initData: initData, keyId: null});
|
|
2337
2290
|
session1.on['message']({target: session1, message: message});
|
|
2338
2291
|
session1.update.and.returnValue(Promise.resolve());
|
|
2339
2292
|
});
|
|
@@ -2496,4 +2449,17 @@ describe('DrmEngine', () => {
|
|
|
2496
2449
|
callback(manifest.variants[0].audio.drmInfos);
|
|
2497
2450
|
}
|
|
2498
2451
|
}
|
|
2452
|
+
|
|
2453
|
+
/**
|
|
2454
|
+
*
|
|
2455
|
+
* @param {string} initDataType
|
|
2456
|
+
* @param {Uint8Array} initData
|
|
2457
|
+
* @param {string|null} keyId
|
|
2458
|
+
*/
|
|
2459
|
+
async function sendEncryptedEvent(
|
|
2460
|
+
initDataType = 'cenc', initData = new Uint8Array(1), keyId = null) {
|
|
2461
|
+
mockVideo.on['encrypted']({initDataType, initData, keyId});
|
|
2462
|
+
|
|
2463
|
+
await Util.shortDelay();
|
|
2464
|
+
}
|
|
2499
2465
|
});
|
|
@@ -103,6 +103,7 @@ describe('MediaSourceEngine', () => {
|
|
|
103
103
|
return {
|
|
104
104
|
mimeType: streamMetadata.mimeType,
|
|
105
105
|
codecs: streamMetadata.codecs,
|
|
106
|
+
drmInfos: [],
|
|
106
107
|
};
|
|
107
108
|
}
|
|
108
109
|
|
|
@@ -288,7 +289,27 @@ describe('MediaSourceEngine', () => {
|
|
|
288
289
|
await mediaSourceEngine.setStreamProperties(ContentType.VIDEO,
|
|
289
290
|
/* timestampOffset= */ 0,
|
|
290
291
|
/* appendWindowStart= */ 5,
|
|
291
|
-
/* appendWindowEnd= */ 18
|
|
292
|
+
/* appendWindowEnd= */ 18,
|
|
293
|
+
/* sequenceMode= */ false);
|
|
294
|
+
expect(buffered(ContentType.VIDEO, 0)).toBe(0);
|
|
295
|
+
await append(ContentType.VIDEO, 0);
|
|
296
|
+
expect(bufferStart(ContentType.VIDEO)).toBeCloseTo(5, 1);
|
|
297
|
+
expect(buffered(ContentType.VIDEO, 5)).toBeCloseTo(5, 1);
|
|
298
|
+
await append(ContentType.VIDEO, 1);
|
|
299
|
+
expect(buffered(ContentType.VIDEO, 5)).toBeCloseTo(13, 1);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('does not initialize timestamp offset in sequence mode', async () => {
|
|
303
|
+
const initObject = new Map();
|
|
304
|
+
initObject.set(ContentType.VIDEO, getFakeStream(metadata.video));
|
|
305
|
+
await mediaSourceEngine.init(initObject, false);
|
|
306
|
+
await mediaSourceEngine.setDuration(presentationDuration);
|
|
307
|
+
await appendInit(ContentType.VIDEO);
|
|
308
|
+
await mediaSourceEngine.setStreamProperties(ContentType.VIDEO,
|
|
309
|
+
/* timestampOffset= */ 100,
|
|
310
|
+
/* appendWindowStart= */ 5,
|
|
311
|
+
/* appendWindowEnd= */ 18,
|
|
312
|
+
/* sequenceMode= */ true);
|
|
292
313
|
expect(buffered(ContentType.VIDEO, 0)).toBe(0);
|
|
293
314
|
await append(ContentType.VIDEO, 0);
|
|
294
315
|
expect(bufferStart(ContentType.VIDEO)).toBeCloseTo(5, 1);
|
|
@@ -307,7 +328,8 @@ describe('MediaSourceEngine', () => {
|
|
|
307
328
|
await mediaSourceEngine.setStreamProperties(ContentType.VIDEO,
|
|
308
329
|
/* timestampOffset= */ 0,
|
|
309
330
|
/* appendWindowStart= */ 0,
|
|
310
|
-
/* appendWindowEnd= */ 20
|
|
331
|
+
/* appendWindowEnd= */ 20,
|
|
332
|
+
/* sequenceMode= */ false);
|
|
311
333
|
await append(ContentType.VIDEO, 0);
|
|
312
334
|
await append(ContentType.VIDEO, 1);
|
|
313
335
|
expect(bufferStart(ContentType.VIDEO)).toBeCloseTo(0, 1);
|
|
@@ -319,7 +341,8 @@ describe('MediaSourceEngine', () => {
|
|
|
319
341
|
await mediaSourceEngine.setStreamProperties(ContentType.VIDEO,
|
|
320
342
|
/* timestampOffset= */ 15,
|
|
321
343
|
/* appendWindowStart= */ 20,
|
|
322
|
-
/* appendWindowEnd= */ 35
|
|
344
|
+
/* appendWindowEnd= */ 35,
|
|
345
|
+
/* sequenceMode= */ false);
|
|
323
346
|
await append(ContentType.VIDEO, 0);
|
|
324
347
|
await append(ContentType.VIDEO, 1);
|
|
325
348
|
expect(bufferStart(ContentType.VIDEO)).toBeCloseTo(0, 1);
|
|
@@ -49,10 +49,10 @@ describe('MediaSourceEngine', () => {
|
|
|
49
49
|
const buffer2 = /** @type {!ArrayBuffer} */ (/** @type {?} */ (2));
|
|
50
50
|
const buffer3 = /** @type {!ArrayBuffer} */ (/** @type {?} */ (3));
|
|
51
51
|
|
|
52
|
-
const fakeVideoStream = {mimeType: 'video/foo'};
|
|
53
|
-
const fakeAudioStream = {mimeType: 'audio/foo'};
|
|
54
|
-
const fakeTextStream = {mimeType: 'text/foo'};
|
|
55
|
-
const fakeTransportStream = {mimeType: 'tsMimetype'};
|
|
52
|
+
const fakeVideoStream = {mimeType: 'video/foo', drmInfos: []};
|
|
53
|
+
const fakeAudioStream = {mimeType: 'audio/foo', drmInfos: []};
|
|
54
|
+
const fakeTextStream = {mimeType: 'text/foo', drmInfos: []};
|
|
55
|
+
const fakeTransportStream = {mimeType: 'tsMimetype', drmInfos: []};
|
|
56
56
|
|
|
57
57
|
let audioSourceBuffer;
|
|
58
58
|
let videoSourceBuffer;
|
|
@@ -812,7 +812,8 @@ describe('MediaSourceEngine', () => {
|
|
|
812
812
|
await mediaSourceEngine.setStreamProperties(ContentType.TEXT,
|
|
813
813
|
/* timestampOffset= */ 10,
|
|
814
814
|
/* appendWindowStart= */ 0,
|
|
815
|
-
/* appendWindowEnd= */ 20
|
|
815
|
+
/* appendWindowEnd= */ 20,
|
|
816
|
+
/* sequenceMode= */ false);
|
|
816
817
|
expect(mockTextEngine.setTimestampOffset).toHaveBeenCalledWith(10);
|
|
817
818
|
expect(mockTextEngine.setAppendWindow).toHaveBeenCalledWith(0, 20);
|
|
818
819
|
});
|
|
@@ -1107,7 +1108,7 @@ describe('MediaSourceEngine', () => {
|
|
|
1107
1108
|
});
|
|
1108
1109
|
|
|
1109
1110
|
it('destroys text engines', async () => {
|
|
1110
|
-
mediaSourceEngine.reinitText('text/vtt');
|
|
1111
|
+
mediaSourceEngine.reinitText('text/vtt', false);
|
|
1111
1112
|
|
|
1112
1113
|
await mediaSourceEngine.destroy();
|
|
1113
1114
|
expect(mockTextEngine).toBeTruthy();
|