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
|
@@ -101,6 +101,7 @@ describe('ManifestConverter', () => {
|
|
|
101
101
|
audioRobustness: 'very',
|
|
102
102
|
videoRobustness: 'kinda_sorta',
|
|
103
103
|
serverCertificate: new Uint8Array([1, 2, 3]),
|
|
104
|
+
serverCertificateUri: '',
|
|
104
105
|
sessionType: '',
|
|
105
106
|
initData: [{
|
|
106
107
|
initData: new Uint8Array([4, 5, 6]),
|
|
@@ -316,6 +317,7 @@ describe('ManifestConverter', () => {
|
|
|
316
317
|
appendWindowStart: 0,
|
|
317
318
|
appendWindowEnd: Infinity,
|
|
318
319
|
timestampOffset: 0,
|
|
320
|
+
tilesLayout: '',
|
|
319
321
|
};
|
|
320
322
|
|
|
321
323
|
return segment;
|
|
@@ -147,15 +147,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
147
147
|
}
|
|
148
148
|
});
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
|
|
152
|
-
filterDescribe('persistent license with MediaCapabilities ' + isEnabled,
|
|
153
|
-
drmStorageSupport, () => {
|
|
154
|
-
testPersistentLicense(useMediaCapabilities);
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function testPersistentLicense(useMediaCapabilities) {
|
|
150
|
+
filterDescribe('persistent license', drmStorageSupport, () => {
|
|
159
151
|
/** @type {!shaka.Player} */
|
|
160
152
|
let player;
|
|
161
153
|
/** @type {!shaka.offline.Storage} */
|
|
@@ -166,7 +158,6 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
166
158
|
// networking engine. This allows us to use Player.configure in these
|
|
167
159
|
// tests.
|
|
168
160
|
player = new shaka.Player();
|
|
169
|
-
player.configure({'useMediaCapabilities': useMediaCapabilities});
|
|
170
161
|
storage = new shaka.offline.Storage(player);
|
|
171
162
|
});
|
|
172
163
|
|
|
@@ -201,7 +192,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
201
192
|
expect(manifest.offlineSessionIds.length).toBeTruthy();
|
|
202
193
|
|
|
203
194
|
// PART 2 - Check that the licences are stored.
|
|
204
|
-
await withDrm(player, manifest,
|
|
195
|
+
await withDrm(player, manifest, (drm) => {
|
|
205
196
|
return Promise.all(manifest.offlineSessionIds.map(async (session) => {
|
|
206
197
|
const foundSession = await loadOfflineSession(drm, session);
|
|
207
198
|
expect(foundSession).toBeTruthy();
|
|
@@ -213,7 +204,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
213
204
|
await storage.remove(uri.toString());
|
|
214
205
|
|
|
215
206
|
// PART 4 - Check that the licenses were removed.
|
|
216
|
-
const p = withDrm(player, manifest,
|
|
207
|
+
const p = withDrm(player, manifest, (drm) => {
|
|
217
208
|
return Promise.all(manifest.offlineSessionIds.map(async (session) => {
|
|
218
209
|
const notFoundSession = await loadOfflineSession(drm, session);
|
|
219
210
|
expect(notFoundSession).toBeFalsy();
|
|
@@ -257,7 +248,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
257
248
|
const storedContents = await storage.list();
|
|
258
249
|
expect(storedContents).toEqual([]);
|
|
259
250
|
|
|
260
|
-
await withDrm(player, manifest,
|
|
251
|
+
await withDrm(player, manifest, (drm) => {
|
|
261
252
|
return Promise.all(manifest.offlineSessionIds.map(async (session) => {
|
|
262
253
|
const foundSession = await loadOfflineSession(drm, session);
|
|
263
254
|
expect(foundSession).toBeTruthy();
|
|
@@ -270,7 +261,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
270
261
|
expect(didRemoveAll).toBe(true);
|
|
271
262
|
|
|
272
263
|
// PART 6 - Check that the licenses were removed.
|
|
273
|
-
const p = withDrm(player, manifest,
|
|
264
|
+
const p = withDrm(player, manifest, (drm) => {
|
|
274
265
|
return Promise.all(manifest.offlineSessionIds.map(async (session) => {
|
|
275
266
|
const notFoundSession = await loadOfflineSession(drm, session);
|
|
276
267
|
expect(notFoundSession).toBeFalsy();
|
|
@@ -282,7 +273,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
282
273
|
shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));
|
|
283
274
|
await expectAsync(p).toBeRejectedWith(expected);
|
|
284
275
|
});
|
|
285
|
-
}
|
|
276
|
+
});
|
|
286
277
|
|
|
287
278
|
describe('default track selection callback', () => {
|
|
288
279
|
const PlayerConfiguration = shaka.util.PlayerConfiguration;
|
|
@@ -1598,6 +1589,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
1598
1589
|
keyIds: null,
|
|
1599
1590
|
sessionType: 'temporary',
|
|
1600
1591
|
serverCertificate: null,
|
|
1592
|
+
serverCertificateUri: '',
|
|
1601
1593
|
audioRobustness: 'HARDY',
|
|
1602
1594
|
videoRobustness: 'OTHER',
|
|
1603
1595
|
};
|
|
@@ -1681,11 +1673,10 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
1681
1673
|
/**
|
|
1682
1674
|
* @param {!shaka.Player} player
|
|
1683
1675
|
* @param {shaka.extern.Manifest} manifest
|
|
1684
|
-
* @param {boolean} useMediaCapabilities
|
|
1685
1676
|
* @param {function(!shaka.media.DrmEngine):Promise} action
|
|
1686
1677
|
* @return {!Promise}
|
|
1687
1678
|
*/
|
|
1688
|
-
async function withDrm(player, manifest,
|
|
1679
|
+
async function withDrm(player, manifest, action) {
|
|
1689
1680
|
const net = player.getNetworkingEngine();
|
|
1690
1681
|
goog.asserts.assert(net, 'Player should have a net engine right now');
|
|
1691
1682
|
|
|
@@ -1703,8 +1694,7 @@ filterDescribe('Storage', storageSupport, () => {
|
|
|
1703
1694
|
try {
|
|
1704
1695
|
drm.configure(player.getConfiguration().drm);
|
|
1705
1696
|
const variants = manifest.variants;
|
|
1706
|
-
await drm.initForStorage(variants, /* usePersistentLicenses= */ true
|
|
1707
|
-
useMediaCapabilities);
|
|
1697
|
+
await drm.initForStorage(variants, /* usePersistentLicenses= */ true);
|
|
1708
1698
|
await action(drm);
|
|
1709
1699
|
} finally {
|
|
1710
1700
|
await drm.destroy();
|
|
@@ -652,6 +652,44 @@ describe('Player', () => {
|
|
|
652
652
|
});
|
|
653
653
|
});
|
|
654
654
|
|
|
655
|
+
describe('seek range', () => {
|
|
656
|
+
// Regression test for Issue #3675.
|
|
657
|
+
it('has a reasonable seek range after going from live to VOD', async () => {
|
|
658
|
+
const netEngine = player.getNetworkingEngine();
|
|
659
|
+
const startTime = Date.now();
|
|
660
|
+
netEngine.registerRequestFilter((type, request) => {
|
|
661
|
+
if (type != shaka.net.NetworkingEngine.RequestType.MANIFEST) {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
// Simulate a live stream by providing different manifests over time.
|
|
665
|
+
const time = (Date.now() - startTime) / 1000;
|
|
666
|
+
const manifestNumber = Math.min(5, Math.floor(0.5 + time / 2));
|
|
667
|
+
request.uris = [
|
|
668
|
+
'/base/test/test/assets/3675/dash_' + manifestNumber + '.mpd',
|
|
669
|
+
];
|
|
670
|
+
console.log('getting manifest', request.uris);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
// Play the stream.
|
|
674
|
+
await player.load('/base/test/test/assets/3675/dash_0.mpd');
|
|
675
|
+
video.play();
|
|
676
|
+
|
|
677
|
+
// Wait for the stream to be over.
|
|
678
|
+
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
679
|
+
/** @type {shaka.test.Waiter} */
|
|
680
|
+
const waiter = new shaka.test.Waiter(eventManager)
|
|
681
|
+
.timeoutAfter(20).failOnTimeout(true);
|
|
682
|
+
await waiter.waitForEnd(video);
|
|
683
|
+
|
|
684
|
+
// The stream should have transitioned to VOD by now.
|
|
685
|
+
expect(player.isLive()).toBe(false);
|
|
686
|
+
|
|
687
|
+
// Check that the final seek range is as expected.
|
|
688
|
+
const seekRange = player.seekRange();
|
|
689
|
+
expect(seekRange.end).toBe(14);
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
|
|
655
693
|
describe('buffering', () => {
|
|
656
694
|
const startBuffering = jasmine.objectContaining({buffering: true});
|
|
657
695
|
const endBuffering = jasmine.objectContaining({buffering: false});
|
|
@@ -921,4 +959,56 @@ describe('Player', () => {
|
|
|
921
959
|
}
|
|
922
960
|
});
|
|
923
961
|
}); // describe('unloading')
|
|
962
|
+
|
|
963
|
+
describe('chapters', () => {
|
|
964
|
+
it('add external chapters in vtt format', async () => {
|
|
965
|
+
await player.load('test:sintel_no_text_compiled');
|
|
966
|
+
const locationUri = new goog.Uri(location.href);
|
|
967
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
968
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
969
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
970
|
+
|
|
971
|
+
await shaka.test.Util.delay(1.5);
|
|
972
|
+
|
|
973
|
+
const chapters = player.getChapters('en');
|
|
974
|
+
expect(chapters.length).toBe(3);
|
|
975
|
+
const chapter1 = chapters[0];
|
|
976
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
977
|
+
expect(chapter1.startTime).toBe(0);
|
|
978
|
+
expect(chapter1.endTime).toBe(5);
|
|
979
|
+
const chapter2 = chapters[1];
|
|
980
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
981
|
+
expect(chapter2.startTime).toBe(5);
|
|
982
|
+
expect(chapter2.endTime).toBe(30);
|
|
983
|
+
const chapter3 = chapters[2];
|
|
984
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
985
|
+
expect(chapter3.startTime).toBe(30);
|
|
986
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
987
|
+
});
|
|
988
|
+
|
|
989
|
+
it('add external chapters in srt format', async () => {
|
|
990
|
+
await player.load('test:sintel_no_text_compiled');
|
|
991
|
+
const locationUri = new goog.Uri(location.href);
|
|
992
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
993
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
994
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
995
|
+
|
|
996
|
+
await shaka.test.Util.delay(1.5);
|
|
997
|
+
|
|
998
|
+
const chapters = player.getChapters('en');
|
|
999
|
+
expect(chapters.length).toBe(3);
|
|
1000
|
+
const chapter1 = chapters[0];
|
|
1001
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
1002
|
+
expect(chapter1.startTime).toBe(0);
|
|
1003
|
+
expect(chapter1.endTime).toBe(5);
|
|
1004
|
+
const chapter2 = chapters[1];
|
|
1005
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
1006
|
+
expect(chapter2.startTime).toBe(5);
|
|
1007
|
+
expect(chapter2.endTime).toBe(30);
|
|
1008
|
+
const chapter3 = chapters[2];
|
|
1009
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
1010
|
+
expect(chapter3.startTime).toBe(30);
|
|
1011
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
1012
|
+
});
|
|
1013
|
+
}); // describe('chapters')
|
|
924
1014
|
});
|
|
@@ -326,6 +326,58 @@ describe('Player Src Equals', () => {
|
|
|
326
326
|
expect(newTrack).toBeTruthy();
|
|
327
327
|
});
|
|
328
328
|
|
|
329
|
+
it('add external chapters in vtt format', async () => {
|
|
330
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
331
|
+
|
|
332
|
+
const locationUri = new goog.Uri(location.href);
|
|
333
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
334
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
335
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
336
|
+
|
|
337
|
+
await shaka.test.Util.delay(1.5);
|
|
338
|
+
|
|
339
|
+
const chapters = player.getChapters('en');
|
|
340
|
+
expect(chapters.length).toBe(3);
|
|
341
|
+
const chapter1 = chapters[0];
|
|
342
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
343
|
+
expect(chapter1.startTime).toBe(0);
|
|
344
|
+
expect(chapter1.endTime).toBe(5);
|
|
345
|
+
const chapter2 = chapters[1];
|
|
346
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
347
|
+
expect(chapter2.startTime).toBe(5);
|
|
348
|
+
expect(chapter2.endTime).toBe(30);
|
|
349
|
+
const chapter3 = chapters[2];
|
|
350
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
351
|
+
expect(chapter3.startTime).toBe(30);
|
|
352
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('add external chapters in srt format', async () => {
|
|
356
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
357
|
+
|
|
358
|
+
const locationUri = new goog.Uri(location.href);
|
|
359
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
360
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
361
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'en');
|
|
362
|
+
|
|
363
|
+
await shaka.test.Util.delay(1.5);
|
|
364
|
+
|
|
365
|
+
const chapters = player.getChapters('en');
|
|
366
|
+
expect(chapters.length).toBe(3);
|
|
367
|
+
const chapter1 = chapters[0];
|
|
368
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
369
|
+
expect(chapter1.startTime).toBe(0);
|
|
370
|
+
expect(chapter1.endTime).toBe(5);
|
|
371
|
+
const chapter2 = chapters[1];
|
|
372
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
373
|
+
expect(chapter2.startTime).toBe(5);
|
|
374
|
+
expect(chapter2.endTime).toBe(30);
|
|
375
|
+
const chapter3 = chapters[2];
|
|
376
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
377
|
+
expect(chapter3.startTime).toBe(30);
|
|
378
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
379
|
+
});
|
|
380
|
+
|
|
329
381
|
// Since we are not in-charge of streaming, calling |retryStreaming| should
|
|
330
382
|
// have no effect.
|
|
331
383
|
it('requesting streaming retry does nothing', async () => {
|
package/test/player_unit.js
CHANGED
|
@@ -2809,16 +2809,7 @@ describe('Player', () => {
|
|
|
2809
2809
|
expect(tracks[0].id).toBe(4);
|
|
2810
2810
|
});
|
|
2811
2811
|
|
|
2812
|
-
|
|
2813
|
-
for (const useMediaCapabilities of [true, false]) {
|
|
2814
|
-
const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
|
|
2815
|
-
it('removes if key system does not support codec with ' +
|
|
2816
|
-
'MediaCapabilities ' + isEnabled, async () => {
|
|
2817
|
-
await testWithUnsupportedCodec(useMediaCapabilities);
|
|
2818
|
-
});
|
|
2819
|
-
}
|
|
2820
|
-
|
|
2821
|
-
async function testWithUnsupportedCodec(useMediaCapabilities) {
|
|
2812
|
+
it('removes if key system does not support codec', async () => {
|
|
2822
2813
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
2823
2814
|
manifest.addVariant(0, (variant) => {
|
|
2824
2815
|
variant.addVideo(1, (stream) => {
|
|
@@ -2836,35 +2827,22 @@ describe('Player', () => {
|
|
|
2836
2827
|
});
|
|
2837
2828
|
});
|
|
2838
2829
|
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
if (videoType.includes('video') &&
|
|
2830
|
+
window.shakaMediaCapabilities.decodingInfo = async (config) => {
|
|
2831
|
+
await Promise.resolve();
|
|
2832
|
+
const videoType = config['video'] ? config['video'].contentType : '';
|
|
2833
|
+
if (videoType.includes('video') &&
|
|
2844
2834
|
videoType.includes('unsupported')) {
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
} else {
|
|
2851
|
-
// We must be careful that our video/unsupported was not filtered out
|
|
2852
|
-
// because of MSE support. We are specifically testing EME-based
|
|
2853
|
-
// filtering of codecs.
|
|
2854
|
-
expect(MediaSource.isTypeSupported('video/unsupported')).toBe(true);
|
|
2855
|
-
// Make sure that drm engine will reject the variant with an unsupported
|
|
2856
|
-
// video mime type.
|
|
2857
|
-
drmEngine.supportsVariant.and.callFake((variant) => {
|
|
2858
|
-
return variant.video.codecs != 'unsupported';
|
|
2859
|
-
});
|
|
2860
|
-
}
|
|
2835
|
+
return {supported: false};
|
|
2836
|
+
} else {
|
|
2837
|
+
return {supported: true};
|
|
2838
|
+
}
|
|
2839
|
+
};
|
|
2861
2840
|
|
|
2862
|
-
player.configure({useMediaCapabilities: useMediaCapabilities});
|
|
2863
2841
|
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
2864
2842
|
const tracks = player.getVariantTracks();
|
|
2865
2843
|
expect(tracks.length).toBe(1);
|
|
2866
2844
|
expect(tracks[0].id).toBe(1);
|
|
2867
|
-
}
|
|
2845
|
+
});
|
|
2868
2846
|
|
|
2869
2847
|
it('removes based on bandwidth', async () => {
|
|
2870
2848
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:29.744Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:31.750Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" r="1" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:35.752Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" r="3" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:37.752Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="0" d="30720" r="4" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="dynamic"
|
|
8
|
+
minimumUpdatePeriod="PT2S"
|
|
9
|
+
suggestedPresentationDelay="PT2S"
|
|
10
|
+
availabilityStartTime="2021-10-28T07:36:27.755Z"
|
|
11
|
+
publishTime="2021-10-28T07:36:41.751Z"
|
|
12
|
+
timeShiftBufferDepth="PT10.0S"
|
|
13
|
+
maxSegmentDuration="PT2.0S"
|
|
14
|
+
minBufferTime="PT4.0S">
|
|
15
|
+
<ProgramInformation>
|
|
16
|
+
</ProgramInformation>
|
|
17
|
+
<ServiceDescription id="0">
|
|
18
|
+
</ServiceDescription>
|
|
19
|
+
<Period id="0" start="PT0.0S">
|
|
20
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
21
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
22
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
|
|
23
|
+
<SegmentTimeline>
|
|
24
|
+
<S t="61440" d="30720" r="4" />
|
|
25
|
+
</SegmentTimeline>
|
|
26
|
+
</SegmentTemplate>
|
|
27
|
+
</Representation>
|
|
28
|
+
</AdaptationSet>
|
|
29
|
+
</Period>
|
|
30
|
+
</MPD>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
|
4
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
5
|
+
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
|
6
|
+
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
|
7
|
+
type="static"
|
|
8
|
+
mediaPresentationDuration="PT14.0S"
|
|
9
|
+
maxSegmentDuration="PT2.0S"
|
|
10
|
+
minBufferTime="PT4.0S">
|
|
11
|
+
<ProgramInformation>
|
|
12
|
+
</ProgramInformation>
|
|
13
|
+
<ServiceDescription id="0">
|
|
14
|
+
</ServiceDescription>
|
|
15
|
+
<Period id="0" start="PT0.0S">
|
|
16
|
+
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
|
|
17
|
+
<Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
|
|
18
|
+
<SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
|
|
19
|
+
<SegmentTimeline>
|
|
20
|
+
<S t="61440" d="30720" r="4" />
|
|
21
|
+
</SegmentTimeline>
|
|
22
|
+
</SegmentTemplate>
|
|
23
|
+
</Representation>
|
|
24
|
+
</AdaptationSet>
|
|
25
|
+
</Period>
|
|
26
|
+
</MPD>
|
|
Binary file
|
|
@@ -16,9 +16,9 @@ goog.require('shaka.text.Cue');
|
|
|
16
16
|
shaka.test.CeaUtils = class {
|
|
17
17
|
/**
|
|
18
18
|
* Returns a cue with no underline/italics, and default colors
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {
|
|
19
|
+
* @param {number} startTime
|
|
20
|
+
* @param {number} endTime
|
|
21
|
+
* @param {string} payload
|
|
22
22
|
*/
|
|
23
23
|
static createDefaultCue(startTime, endTime, payload) {
|
|
24
24
|
const cue = new shaka.text.Cue(startTime, endTime, payload);
|
|
@@ -29,13 +29,13 @@ shaka.test.CeaUtils = class {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Returns a cue with custom underline, italics, color, background color.
|
|
32
|
-
* @param {
|
|
33
|
-
* @param {
|
|
34
|
-
* @param {
|
|
35
|
-
* @param {
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {
|
|
38
|
-
* @param {
|
|
32
|
+
* @param {number} startTime
|
|
33
|
+
* @param {number} endTime
|
|
34
|
+
* @param {string} payload
|
|
35
|
+
* @param {boolean} underline
|
|
36
|
+
* @param {boolean} italics
|
|
37
|
+
* @param {string} textColor
|
|
38
|
+
* @param {string} backgroundColor
|
|
39
39
|
* @return {!shaka.text.Cue}
|
|
40
40
|
*/
|
|
41
41
|
static createStyledCue(startTime, endTime, payload, underline,
|
|
@@ -54,8 +54,8 @@ shaka.test.CeaUtils = class {
|
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Returns a cue that corresponds to a linebreak.
|
|
57
|
-
* @param {
|
|
58
|
-
* @param {
|
|
57
|
+
* @param {number} startTime
|
|
58
|
+
* @param {number} endTime
|
|
59
59
|
* @return {!shaka.text.Cue}
|
|
60
60
|
*/
|
|
61
61
|
static createLineBreakCue(startTime, endTime) {
|
|
@@ -53,6 +53,13 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
|
|
|
53
53
|
/** @override */
|
|
54
54
|
replaceServerSideAdTagParameters(adTagParameters) {}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @override
|
|
58
|
+
*/
|
|
59
|
+
getServerSideCuePoints() {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
/** @override */
|
|
57
64
|
getStats() {
|
|
58
65
|
return this.stats_;
|
|
@@ -78,7 +85,7 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
|
|
|
78
85
|
*/
|
|
79
86
|
startAd(ad) {
|
|
80
87
|
const event = new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED,
|
|
81
|
-
|
|
88
|
+
(new Map()).set('ad', ad));
|
|
82
89
|
|
|
83
90
|
this.dispatchEvent(event);
|
|
84
91
|
}
|
|
@@ -407,6 +407,8 @@ shaka.test.ManifestGenerator.DrmInfo = class {
|
|
|
407
407
|
this.keyIds = new Set();
|
|
408
408
|
/** @type {string} */
|
|
409
409
|
this.sessionType = '';
|
|
410
|
+
/** @type {string} */
|
|
411
|
+
this.serverCertificateUri = '';
|
|
410
412
|
|
|
411
413
|
/** @type {shaka.extern.DrmInfo} */
|
|
412
414
|
const foo = this;
|