shaka-player 3.1.5 → 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +129 -6
- package/README.md +4 -4
- package/build/types/polyfill +1 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +10 -1
- 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/demo.compiled.debug.js +14 -14
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +14 -14
- package/dist/demo.compiled.map +2 -2
- package/dist/deps.js +21 -20
- package/dist/locales.js +30 -30
- package/dist/receiver.compiled.debug.js +8 -8
- package/dist/receiver.compiled.debug.map +2 -2
- package/dist/receiver.compiled.js +8 -8
- package/dist/receiver.compiled.map +2 -2
- package/dist/shaka-player.compiled.d.ts +63 -10
- package/dist/shaka-player.compiled.debug.d.ts +63 -10
- package/dist/shaka-player.compiled.debug.externs.js +786 -716
- package/dist/shaka-player.compiled.debug.js +563 -534
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +786 -716
- package/dist/shaka-player.compiled.js +820 -809
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +63 -10
- package/dist/shaka-player.ui.debug.d.ts +63 -10
- package/dist/shaka-player.ui.debug.externs.js +542 -472
- package/dist/shaka-player.ui.debug.js +594 -566
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +542 -472
- package/dist/shaka-player.ui.js +938 -927
- package/dist/shaka-player.ui.map +4 -4
- 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 +61 -9
- package/externs/shaka/text.js +10 -10
- package/externs/texttrack.js +3 -0
- package/lib/ads/ad_manager.js +16 -15
- package/lib/ads/client_side_ad_manager.js +6 -2
- package/lib/ads/server_side_ad_manager.js +19 -2
- package/lib/cast/cast_proxy.js +8 -0
- 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 +5 -0
- package/lib/hls/hls_parser.js +159 -12
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +162 -192
- package/lib/media/segment_index.js +4 -1
- package/lib/media/segment_reference.js +37 -2
- package/lib/media/streaming_engine.js +6 -6
- package/lib/net/networking_engine.js +1 -0
- 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 +426 -149
- package/lib/polyfill/aria.js +82 -0
- package/lib/routing/walker.js +2 -3
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +2 -2
- 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/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/player_configuration.js +13 -1
- package/lib/util/stream_utils.js +168 -88
- 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_utils_unit.js +1 -0
- 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 +43 -1
- package/test/hls/hls_parser_unit.js +250 -0
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +310 -450
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +9 -19
- package/test/player_integration.js +85 -0
- package/test/player_src_equals_integration.js +85 -0
- package/test/player_unit.js +25 -37
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/assets/chapters2.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/fake_ad_manager.js +7 -0
- package/test/test/util/manifest_generator.js +2 -0
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/util/stream_utils_unit.js +118 -10
- package/ui/airplay_button.js +1 -1
- package/ui/audio_language_selection.js +2 -5
- package/ui/cast_button.js +4 -6
- package/ui/constants.js +0 -3
- package/ui/fast_forward_button.js +2 -3
- package/ui/fullscreen_button.js +1 -3
- package/ui/language_utils.js +1 -1
- 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 +5 -7
- 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();
|
|
@@ -959,4 +959,89 @@ describe('Player', () => {
|
|
|
959
959
|
}
|
|
960
960
|
});
|
|
961
961
|
}); // describe('unloading')
|
|
962
|
+
|
|
963
|
+
describe('chapters', () => {
|
|
964
|
+
it('add external chapters in vtt format', async () => {
|
|
965
|
+
await player.load('test:sintel_no_text_compiled');
|
|
966
|
+
const locationUri = new goog.Uri(location.href);
|
|
967
|
+
const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
968
|
+
const absoluteUri1 = locationUri.resolve(partialUri1);
|
|
969
|
+
await player.addChaptersTrack(absoluteUri1.toString(), 'en');
|
|
970
|
+
|
|
971
|
+
await shaka.test.Util.delay(1.5);
|
|
972
|
+
|
|
973
|
+
const chapters = player.getChapters('en');
|
|
974
|
+
expect(chapters.length).toBe(3);
|
|
975
|
+
const chapter1 = chapters[0];
|
|
976
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
977
|
+
expect(chapter1.startTime).toBe(0);
|
|
978
|
+
expect(chapter1.endTime).toBe(5);
|
|
979
|
+
const chapter2 = chapters[1];
|
|
980
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
981
|
+
expect(chapter2.startTime).toBe(5);
|
|
982
|
+
expect(chapter2.endTime).toBe(10);
|
|
983
|
+
const chapter3 = chapters[2];
|
|
984
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
985
|
+
expect(chapter3.startTime).toBe(10);
|
|
986
|
+
expect(chapter3.endTime).toBe(20);
|
|
987
|
+
|
|
988
|
+
const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
|
|
989
|
+
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
990
|
+
await player.addChaptersTrack(absoluteUri2.toString(), 'en');
|
|
991
|
+
|
|
992
|
+
await shaka.test.Util.delay(1.5);
|
|
993
|
+
|
|
994
|
+
const chaptersUpdated = player.getChapters('en');
|
|
995
|
+
expect(chaptersUpdated.length).toBe(6);
|
|
996
|
+
const chapterUpdated1 = chaptersUpdated[0];
|
|
997
|
+
expect(chapterUpdated1.title).toBe('Chapter 1');
|
|
998
|
+
expect(chapterUpdated1.startTime).toBe(0);
|
|
999
|
+
expect(chapterUpdated1.endTime).toBe(5);
|
|
1000
|
+
const chapterUpdated2 = chaptersUpdated[1];
|
|
1001
|
+
expect(chapterUpdated2.title).toBe('Chapter 2');
|
|
1002
|
+
expect(chapterUpdated2.startTime).toBe(5);
|
|
1003
|
+
expect(chapterUpdated2.endTime).toBe(10);
|
|
1004
|
+
const chapterUpdated3 = chaptersUpdated[2];
|
|
1005
|
+
expect(chapterUpdated3.title).toBe('Chapter 3');
|
|
1006
|
+
expect(chapterUpdated3.startTime).toBe(10);
|
|
1007
|
+
expect(chapterUpdated3.endTime).toBe(20);
|
|
1008
|
+
const chapterUpdated4 = chaptersUpdated[3];
|
|
1009
|
+
expect(chapterUpdated4.title).toBe('Chapter 4');
|
|
1010
|
+
expect(chapterUpdated4.startTime).toBe(20);
|
|
1011
|
+
expect(chapterUpdated4.endTime).toBe(30);
|
|
1012
|
+
const chapterUpdated5 = chaptersUpdated[4];
|
|
1013
|
+
expect(chapterUpdated5.title).toBe('Chapter 5');
|
|
1014
|
+
expect(chapterUpdated5.startTime).toBe(30);
|
|
1015
|
+
expect(chapterUpdated5.endTime).toBe(40);
|
|
1016
|
+
const chapterUpdated6 = chaptersUpdated[5];
|
|
1017
|
+
expect(chapterUpdated6.title).toBe('Chapter 6');
|
|
1018
|
+
expect(chapterUpdated6.startTime).toBe(40);
|
|
1019
|
+
expect(chapterUpdated6.endTime).toBe(61.349);
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
it('add external chapters in srt format', async () => {
|
|
1023
|
+
await player.load('test:sintel_no_text_compiled');
|
|
1024
|
+
const locationUri = new goog.Uri(location.href);
|
|
1025
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
1026
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
1027
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'es');
|
|
1028
|
+
|
|
1029
|
+
await shaka.test.Util.delay(1.5);
|
|
1030
|
+
|
|
1031
|
+
const chapters = player.getChapters('es');
|
|
1032
|
+
expect(chapters.length).toBe(3);
|
|
1033
|
+
const chapter1 = chapters[0];
|
|
1034
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
1035
|
+
expect(chapter1.startTime).toBe(0);
|
|
1036
|
+
expect(chapter1.endTime).toBe(5);
|
|
1037
|
+
const chapter2 = chapters[1];
|
|
1038
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
1039
|
+
expect(chapter2.startTime).toBe(5);
|
|
1040
|
+
expect(chapter2.endTime).toBe(30);
|
|
1041
|
+
const chapter3 = chapters[2];
|
|
1042
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
1043
|
+
expect(chapter3.startTime).toBe(30);
|
|
1044
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
1045
|
+
});
|
|
1046
|
+
}); // describe('chapters')
|
|
962
1047
|
});
|
|
@@ -326,6 +326,91 @@ describe('Player Src Equals', () => {
|
|
|
326
326
|
expect(newTrack).toBeTruthy();
|
|
327
327
|
});
|
|
328
328
|
|
|
329
|
+
it('add external chapters in vtt format', async () => {
|
|
330
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
331
|
+
|
|
332
|
+
const locationUri = new goog.Uri(location.href);
|
|
333
|
+
const partialUri1 = new goog.Uri('/base/test/test/assets/chapters.vtt');
|
|
334
|
+
const absoluteUri1 = locationUri.resolve(partialUri1);
|
|
335
|
+
await player.addChaptersTrack(absoluteUri1.toString(), 'en');
|
|
336
|
+
|
|
337
|
+
await shaka.test.Util.delay(1.5);
|
|
338
|
+
|
|
339
|
+
const chapters = player.getChapters('en');
|
|
340
|
+
expect(chapters.length).toBe(3);
|
|
341
|
+
const chapter1 = chapters[0];
|
|
342
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
343
|
+
expect(chapter1.startTime).toBe(0);
|
|
344
|
+
expect(chapter1.endTime).toBe(5);
|
|
345
|
+
const chapter2 = chapters[1];
|
|
346
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
347
|
+
expect(chapter2.startTime).toBe(5);
|
|
348
|
+
expect(chapter2.endTime).toBe(10);
|
|
349
|
+
const chapter3 = chapters[2];
|
|
350
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
351
|
+
expect(chapter3.startTime).toBe(10);
|
|
352
|
+
expect(chapter3.endTime).toBe(20);
|
|
353
|
+
|
|
354
|
+
const partialUri2 = new goog.Uri('/base/test/test/assets/chapters2.vtt');
|
|
355
|
+
const absoluteUri2 = locationUri.resolve(partialUri2);
|
|
356
|
+
await player.addChaptersTrack(absoluteUri2.toString(), 'en');
|
|
357
|
+
|
|
358
|
+
await shaka.test.Util.delay(1.5);
|
|
359
|
+
|
|
360
|
+
const chaptersUpdated = player.getChapters('en');
|
|
361
|
+
expect(chaptersUpdated.length).toBe(6);
|
|
362
|
+
const chapterUpdated1 = chaptersUpdated[0];
|
|
363
|
+
expect(chapterUpdated1.title).toBe('Chapter 1');
|
|
364
|
+
expect(chapterUpdated1.startTime).toBe(0);
|
|
365
|
+
expect(chapterUpdated1.endTime).toBe(5);
|
|
366
|
+
const chapterUpdated2 = chaptersUpdated[1];
|
|
367
|
+
expect(chapterUpdated2.title).toBe('Chapter 2');
|
|
368
|
+
expect(chapterUpdated2.startTime).toBe(5);
|
|
369
|
+
expect(chapterUpdated2.endTime).toBe(10);
|
|
370
|
+
const chapterUpdated3 = chaptersUpdated[2];
|
|
371
|
+
expect(chapterUpdated3.title).toBe('Chapter 3');
|
|
372
|
+
expect(chapterUpdated3.startTime).toBe(10);
|
|
373
|
+
expect(chapterUpdated3.endTime).toBe(20);
|
|
374
|
+
const chapterUpdated4 = chaptersUpdated[3];
|
|
375
|
+
expect(chapterUpdated4.title).toBe('Chapter 4');
|
|
376
|
+
expect(chapterUpdated4.startTime).toBe(20);
|
|
377
|
+
expect(chapterUpdated4.endTime).toBe(30);
|
|
378
|
+
const chapterUpdated5 = chaptersUpdated[4];
|
|
379
|
+
expect(chapterUpdated5.title).toBe('Chapter 5');
|
|
380
|
+
expect(chapterUpdated5.startTime).toBe(30);
|
|
381
|
+
expect(chapterUpdated5.endTime).toBe(40);
|
|
382
|
+
const chapterUpdated6 = chaptersUpdated[5];
|
|
383
|
+
expect(chapterUpdated6.title).toBe('Chapter 6');
|
|
384
|
+
expect(chapterUpdated6.startTime).toBe(40);
|
|
385
|
+
expect(chapterUpdated6.endTime).toBe(61.349);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('add external chapters in srt format', async () => {
|
|
389
|
+
await loadWithSrcEquals(SMALL_MP4_CONTENT_URI, /* startTime= */ null);
|
|
390
|
+
|
|
391
|
+
const locationUri = new goog.Uri(location.href);
|
|
392
|
+
const partialUri = new goog.Uri('/base/test/test/assets/chapters.srt');
|
|
393
|
+
const absoluteUri = locationUri.resolve(partialUri);
|
|
394
|
+
await player.addChaptersTrack(absoluteUri.toString(), 'es');
|
|
395
|
+
|
|
396
|
+
await shaka.test.Util.delay(1.5);
|
|
397
|
+
|
|
398
|
+
const chapters = player.getChapters('es');
|
|
399
|
+
expect(chapters.length).toBe(3);
|
|
400
|
+
const chapter1 = chapters[0];
|
|
401
|
+
expect(chapter1.title).toBe('Chapter 1');
|
|
402
|
+
expect(chapter1.startTime).toBe(0);
|
|
403
|
+
expect(chapter1.endTime).toBe(5);
|
|
404
|
+
const chapter2 = chapters[1];
|
|
405
|
+
expect(chapter2.title).toBe('Chapter 2');
|
|
406
|
+
expect(chapter2.startTime).toBe(5);
|
|
407
|
+
expect(chapter2.endTime).toBe(30);
|
|
408
|
+
const chapter3 = chapters[2];
|
|
409
|
+
expect(chapter3.title).toBe('Chapter 3');
|
|
410
|
+
expect(chapter3.startTime).toBe(30);
|
|
411
|
+
expect(chapter3.endTime).toBe(61.349);
|
|
412
|
+
});
|
|
413
|
+
|
|
329
414
|
// Since we are not in-charge of streaming, calling |retryStreaming| should
|
|
330
415
|
// have no effect.
|
|
331
416
|
it('requesting streaming retry does nothing', async () => {
|
package/test/player_unit.js
CHANGED
|
@@ -1092,8 +1092,8 @@ describe('Player', () => {
|
|
|
1092
1092
|
// Image tracks
|
|
1093
1093
|
manifest.addImageStream(53, (stream) => {
|
|
1094
1094
|
stream.originalId = 'thumbnail';
|
|
1095
|
-
stream.width =
|
|
1096
|
-
stream.height =
|
|
1095
|
+
stream.width = 200;
|
|
1096
|
+
stream.height = 400;
|
|
1097
1097
|
stream.bandwidth = 10;
|
|
1098
1098
|
stream.mimeType = 'image/jpeg';
|
|
1099
1099
|
stream.tilesLayout = '1x1';
|
|
@@ -1503,8 +1503,8 @@ describe('Player', () => {
|
|
|
1503
1503
|
audioBandwidth: null,
|
|
1504
1504
|
videoBandwidth: null,
|
|
1505
1505
|
bandwidth: 10,
|
|
1506
|
-
width:
|
|
1507
|
-
height:
|
|
1506
|
+
width: 200,
|
|
1507
|
+
height: 400,
|
|
1508
1508
|
frameRate: null,
|
|
1509
1509
|
pixelAspectRatio: null,
|
|
1510
1510
|
hdr: null,
|
|
@@ -2809,16 +2809,7 @@ describe('Player', () => {
|
|
|
2809
2809
|
expect(tracks[0].id).toBe(4);
|
|
2810
2810
|
});
|
|
2811
2811
|
|
|
2812
|
-
|
|
2813
|
-
for (const useMediaCapabilities of [true, false]) {
|
|
2814
|
-
const isEnabled = useMediaCapabilities ? 'enabled' : 'disabled';
|
|
2815
|
-
it('removes if key system does not support codec with ' +
|
|
2816
|
-
'MediaCapabilities ' + isEnabled, async () => {
|
|
2817
|
-
await testWithUnsupportedCodec(useMediaCapabilities);
|
|
2818
|
-
});
|
|
2819
|
-
}
|
|
2820
|
-
|
|
2821
|
-
async function testWithUnsupportedCodec(useMediaCapabilities) {
|
|
2812
|
+
it('removes if key system does not support codec', async () => {
|
|
2822
2813
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
2823
2814
|
manifest.addVariant(0, (variant) => {
|
|
2824
2815
|
variant.addVideo(1, (stream) => {
|
|
@@ -2836,35 +2827,22 @@ describe('Player', () => {
|
|
|
2836
2827
|
});
|
|
2837
2828
|
});
|
|
2838
2829
|
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
if (videoType.includes('video') &&
|
|
2830
|
+
navigator.mediaCapabilities.decodingInfo = async (config) => {
|
|
2831
|
+
await Promise.resolve();
|
|
2832
|
+
const videoType = config['video'] ? config['video'].contentType : '';
|
|
2833
|
+
if (videoType.includes('video') &&
|
|
2844
2834
|
videoType.includes('unsupported')) {
|
|
2845
|
-
|
|
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) => {
|
|
@@ -3559,29 +3537,39 @@ describe('Player', () => {
|
|
|
3559
3537
|
|
|
3560
3538
|
await player.load(fakeManifestUri, 0, fakeMimeType);
|
|
3561
3539
|
|
|
3540
|
+
expect(player.getImageTracks()[0].width).toBe(100);
|
|
3541
|
+
expect(player.getImageTracks()[0].height).toBe(50);
|
|
3562
3542
|
const thumbnail0 = await player.getThumbnails(5, 0);
|
|
3563
3543
|
const thumbnail1 = await player.getThumbnails(5, 11);
|
|
3564
3544
|
const thumbnail2 = await player.getThumbnails(5, 21);
|
|
3565
3545
|
const thumbnail5 = await player.getThumbnails(5, 51);
|
|
3566
3546
|
expect(thumbnail0).toEqual(jasmine.objectContaining({
|
|
3547
|
+
imageHeight: 150,
|
|
3548
|
+
imageWidth: 200,
|
|
3567
3549
|
positionX: 0,
|
|
3568
3550
|
positionY: 0,
|
|
3569
3551
|
width: 100,
|
|
3570
3552
|
height: 50,
|
|
3571
3553
|
}));
|
|
3572
3554
|
expect(thumbnail1).toEqual(jasmine.objectContaining({
|
|
3555
|
+
imageHeight: 150,
|
|
3556
|
+
imageWidth: 200,
|
|
3573
3557
|
positionX: 100,
|
|
3574
3558
|
positionY: 0,
|
|
3575
3559
|
width: 100,
|
|
3576
3560
|
height: 50,
|
|
3577
3561
|
}));
|
|
3578
3562
|
expect(thumbnail2).toEqual(jasmine.objectContaining({
|
|
3563
|
+
imageHeight: 150,
|
|
3564
|
+
imageWidth: 200,
|
|
3579
3565
|
positionX: 0,
|
|
3580
3566
|
positionY: 50,
|
|
3581
3567
|
width: 100,
|
|
3582
3568
|
height: 50,
|
|
3583
3569
|
}));
|
|
3584
3570
|
expect(thumbnail5).toEqual(jasmine.objectContaining({
|
|
3571
|
+
imageHeight: 150,
|
|
3572
|
+
imageWidth: 200,
|
|
3585
3573
|
positionX: 100,
|
|
3586
3574
|
positionY: 100,
|
|
3587
3575
|
width: 100,
|
|
@@ -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_;
|
|
@@ -407,6 +407,8 @@ shaka.test.ManifestGenerator.DrmInfo = class {
|
|
|
407
407
|
this.keyIds = new Set();
|
|
408
408
|
/** @type {string} */
|
|
409
409
|
this.sessionType = '';
|
|
410
|
+
/** @type {string} */
|
|
411
|
+
this.serverCertificateUri = '';
|
|
410
412
|
|
|
411
413
|
/** @type {shaka.extern.DrmInfo} */
|
|
412
414
|
const foo = this;
|
|
@@ -56,11 +56,12 @@ shaka.test.ManifestParser = class {
|
|
|
56
56
|
* @param {?number=} endByte
|
|
57
57
|
* @param {number=} timestampOffset
|
|
58
58
|
* @param {!Array.<!shaka.media.SegmentReference>=} partialReferences
|
|
59
|
+
* @param {?string=} tilesLayout
|
|
59
60
|
* @return {!shaka.media.SegmentReference}
|
|
60
61
|
*/
|
|
61
62
|
static makeReference(uri, start, end, baseUri = '',
|
|
62
63
|
startByte = 0, endByte = null, timestampOffset = 0,
|
|
63
|
-
partialReferences = []) {
|
|
64
|
+
partialReferences = [], tilesLayout = '') {
|
|
64
65
|
const getUris = () => uri.length ? [baseUri + uri] : [];
|
|
65
66
|
|
|
66
67
|
// If a test wants to verify these, they can be set explicitly after
|
|
@@ -84,6 +85,7 @@ shaka.test.ManifestParser = class {
|
|
|
84
85
|
appendWindowStart,
|
|
85
86
|
appendWindowEnd,
|
|
86
87
|
partialReferences,
|
|
88
|
+
tilesLayout,
|
|
87
89
|
);
|
|
88
90
|
}
|
|
89
91
|
};
|
|
@@ -9,23 +9,45 @@ goog.require('shaka.text.WebVttGenerator');
|
|
|
9
9
|
|
|
10
10
|
describe('WebVttGenerator', () => {
|
|
11
11
|
it('supports no cues', () => {
|
|
12
|
-
verifyHelper([], 'WEBVTT\n\n');
|
|
12
|
+
verifyHelper([], [], 'WEBVTT\n\n');
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it('convert cues to WebVTT', () => {
|
|
16
16
|
const shakaCue1 = new shaka.text.Cue(20, 40, 'Test');
|
|
17
|
+
shakaCue1.textAlign = shaka.text.Cue.textAlign.LEFT;
|
|
18
|
+
shakaCue1.writingMode = shaka.text.Cue.writingMode.VERTICAL_LEFT_TO_RIGHT;
|
|
17
19
|
const shakaCue2 = new shaka.text.Cue(40, 50, 'Test2');
|
|
20
|
+
shakaCue2.textAlign = shaka.text.Cue.textAlign.RIGHT;
|
|
21
|
+
shakaCue2.writingMode = shaka.text.Cue.writingMode.VERTICAL_RIGHT_TO_LEFT;
|
|
22
|
+
const shakaCue3 = new shaka.text.Cue(50, 51, 'Test3');
|
|
23
|
+
shakaCue3.textAlign = shaka.text.Cue.textAlign.CENTER;
|
|
24
|
+
const shakaCue4 = new shaka.text.Cue(52, 53, 'Test4');
|
|
25
|
+
shakaCue4.textAlign = shaka.text.Cue.textAlign.START;
|
|
26
|
+
const shakaCue5 = new shaka.text.Cue(53, 54, 'Test5');
|
|
27
|
+
shakaCue5.textAlign = shaka.text.Cue.textAlign.END;
|
|
28
|
+
|
|
29
|
+
const adCuePoints = [];
|
|
18
30
|
|
|
19
31
|
verifyHelper(
|
|
20
32
|
[
|
|
21
33
|
shakaCue1,
|
|
22
34
|
shakaCue2,
|
|
35
|
+
shakaCue3,
|
|
36
|
+
shakaCue4,
|
|
37
|
+
shakaCue5,
|
|
23
38
|
],
|
|
39
|
+
adCuePoints,
|
|
24
40
|
'WEBVTT\n\n' +
|
|
25
|
-
'00:00:20.000 --> 00:00:40.000\n' +
|
|
41
|
+
'00:00:20.000 --> 00:00:40.000 align:left vertical:lr\n' +
|
|
26
42
|
'Test\n\n' +
|
|
27
|
-
'00:00:40.000 --> 00:00:50.000\n' +
|
|
28
|
-
'Test2\n\n'
|
|
43
|
+
'00:00:40.000 --> 00:00:50.000 align:right vertical:rl\n' +
|
|
44
|
+
'Test2\n\n' +
|
|
45
|
+
'00:00:50.000 --> 00:00:51.000 align:middle\n' +
|
|
46
|
+
'Test3\n\n' +
|
|
47
|
+
'00:00:52.000 --> 00:00:53.000 align:start\n' +
|
|
48
|
+
'Test4\n\n' +
|
|
49
|
+
'00:00:53.000 --> 00:00:54.000 align:end\n' +
|
|
50
|
+
'Test5\n\n');
|
|
29
51
|
});
|
|
30
52
|
|
|
31
53
|
it('creates style tags for cues with underline/italics/bold', () => {
|
|
@@ -49,19 +71,71 @@ describe('WebVttGenerator', () => {
|
|
|
49
71
|
nestedCue4.textDecoration.push(shaka.text.Cue.textDecoration.UNDERLINE);
|
|
50
72
|
|
|
51
73
|
shakaCue.nestedCues = [nestedCue1, nestedCue2, nestedCue3, nestedCue4];
|
|
74
|
+
|
|
75
|
+
const adCuePoints = [];
|
|
76
|
+
|
|
52
77
|
verifyHelper(
|
|
53
78
|
[shakaCue],
|
|
79
|
+
adCuePoints,
|
|
54
80
|
'WEBVTT\n\n' +
|
|
55
|
-
'00:00:10.000 --> 00:00:20.000\n' +
|
|
81
|
+
'00:00:10.000 --> 00:00:20.000 align:middle\n' +
|
|
56
82
|
'<i><u>Test1</u></i><b><i>Test2</i></b>Test3<u>Test4</u>\n\n');
|
|
57
83
|
});
|
|
58
84
|
|
|
85
|
+
it('computes the time with ad cue points', () => {
|
|
86
|
+
const shakaCue1 = new shaka.text.Cue(20, 30, 'Test');
|
|
87
|
+
shakaCue1.textAlign = shaka.text.Cue.textAlign.LEFT;
|
|
88
|
+
shakaCue1.writingMode = shaka.text.Cue.writingMode.VERTICAL_LEFT_TO_RIGHT;
|
|
89
|
+
const shakaCue2 = new shaka.text.Cue(40, 50, 'Test2');
|
|
90
|
+
shakaCue2.textAlign = shaka.text.Cue.textAlign.RIGHT;
|
|
91
|
+
shakaCue2.writingMode = shaka.text.Cue.writingMode.VERTICAL_RIGHT_TO_LEFT;
|
|
92
|
+
const shakaCue3 = new shaka.text.Cue(50, 51, 'Test3');
|
|
93
|
+
shakaCue3.textAlign = shaka.text.Cue.textAlign.CENTER;
|
|
94
|
+
const shakaCue4 = new shaka.text.Cue(52, 53, 'Test4');
|
|
95
|
+
shakaCue4.textAlign = shaka.text.Cue.textAlign.START;
|
|
96
|
+
const shakaCue5 = new shaka.text.Cue(53, 54, 'Test5');
|
|
97
|
+
shakaCue5.textAlign = shaka.text.Cue.textAlign.END;
|
|
98
|
+
|
|
99
|
+
const adCuePoints = [
|
|
100
|
+
{
|
|
101
|
+
start: 0,
|
|
102
|
+
end: 10,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
start: 35,
|
|
106
|
+
end: 45,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
verifyHelper(
|
|
111
|
+
[
|
|
112
|
+
shakaCue1,
|
|
113
|
+
shakaCue2,
|
|
114
|
+
shakaCue3,
|
|
115
|
+
shakaCue4,
|
|
116
|
+
shakaCue5,
|
|
117
|
+
],
|
|
118
|
+
adCuePoints,
|
|
119
|
+
'WEBVTT\n\n' +
|
|
120
|
+
'00:00:30.000 --> 00:00:40.000 align:left vertical:lr\n' +
|
|
121
|
+
'Test\n\n' +
|
|
122
|
+
'00:01:00.000 --> 00:01:10.000 align:right vertical:rl\n' +
|
|
123
|
+
'Test2\n\n' +
|
|
124
|
+
'00:01:10.000 --> 00:01:11.000 align:middle\n' +
|
|
125
|
+
'Test3\n\n' +
|
|
126
|
+
'00:01:12.000 --> 00:01:13.000 align:start\n' +
|
|
127
|
+
'Test4\n\n' +
|
|
128
|
+
'00:01:13.000 --> 00:01:14.000 align:end\n' +
|
|
129
|
+
'Test5\n\n');
|
|
130
|
+
});
|
|
131
|
+
|
|
59
132
|
/**
|
|
60
133
|
* @param {!Array} cues
|
|
134
|
+
* @param {!Array} adCuePoints
|
|
61
135
|
* @param {string} text
|
|
62
136
|
*/
|
|
63
|
-
function verifyHelper(cues, text) {
|
|
64
|
-
const result = shaka.text.WebVttGenerator.convert(cues);
|
|
137
|
+
function verifyHelper(cues, adCuePoints, text) {
|
|
138
|
+
const result = shaka.text.WebVttGenerator.convert(cues, adCuePoints);
|
|
65
139
|
expect(text).toBe(result);
|
|
66
140
|
}
|
|
67
141
|
});
|