shaka-player 4.4.2 → 4.5.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/release-please.yaml +2 -27
- package/CHANGELOG.md +67 -25
- package/README.md +16 -10
- package/demo/asset_card.js +18 -21
- package/demo/cast_receiver/index.html +0 -1
- package/demo/close_button.js +0 -3
- package/demo/common/asset.js +27 -5
- package/demo/common/assets.js +150 -52
- package/demo/config.js +192 -253
- package/demo/custom.js +39 -98
- package/demo/front.js +7 -10
- package/demo/index.html +19 -22
- package/demo/input.js +6 -11
- package/demo/input_container.js +8 -9
- package/demo/main.js +52 -124
- package/demo/search.js +23 -35
- package/demo/service_worker.js +0 -3
- package/demo/tooltip.js +3 -5
- package/demo/visualizer.js +3 -5
- package/demo/visualizer_button.js +1 -20
- package/dist/demo.compiled.debug.js +187 -211
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +187 -211
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +27 -24
- package/dist/locales.js +31 -31
- package/dist/receiver.compiled.debug.js +42 -61
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +42 -61
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +728 -365
- package/dist/shaka-player.compiled.debug.d.ts +728 -365
- package/dist/shaka-player.compiled.debug.externs.js +475 -51
- package/dist/shaka-player.compiled.debug.js +576 -480
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +475 -51
- package/dist/shaka-player.compiled.js +1117 -1056
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +783 -410
- package/dist/shaka-player.ui.debug.d.ts +783 -410
- package/dist/shaka-player.ui.debug.externs.js +496 -51
- package/dist/shaka-player.ui.debug.js +647 -542
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +496 -51
- package/dist/shaka-player.ui.js +1260 -1194
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-integration.md +14 -14
- package/docs/tutorials/faq.md +27 -55
- package/docs/tutorials/index.json +2 -1
- package/docs/tutorials/lcevc.md +118 -0
- package/docs/tutorials/offline.md +1 -1
- package/docs/tutorials/ui-customization.md +4 -0
- package/externs/css_style_declaration.js +19 -0
- package/externs/lcevc.js +37 -13
- package/externs/media_remote.js +68 -0
- package/externs/mediatailor.js +193 -0
- package/externs/pictureinpicture.js +11 -0
- package/externs/shaka/ads.js +27 -0
- package/externs/shaka/manifest.js +10 -5
- package/externs/shaka/manifest_parser.js +7 -1
- package/externs/shaka/offline.js +4 -0
- package/externs/shaka/player.js +12 -1
- package/karma.conf.js +7 -3
- package/lib/abr/simple_abr_manager.js +43 -3
- package/lib/ads/ad_manager.js +104 -50
- package/lib/ads/media_tailor_ad.js +297 -0
- package/lib/ads/media_tailor_ad_manager.js +828 -0
- package/lib/cea/ts_cea_parser.js +15 -2
- package/lib/config/codec_switching_strategy.js +24 -0
- package/lib/dash/content_protection.js +120 -2
- package/lib/dash/dash_parser.js +79 -13
- package/lib/dash/mpd_utils.js +10 -6
- package/lib/dash/segment_base.js +13 -5
- package/lib/dash/segment_list.js +13 -5
- package/lib/dash/segment_template.js +43 -85
- package/lib/dependencies/all.js +8 -7
- package/lib/hls/hls_parser.js +101 -37
- package/lib/lcevc/lcevc_dec.js +220 -0
- package/lib/media/adaptation_set.js +22 -11
- package/lib/media/adaptation_set_criteria.js +25 -7
- package/lib/media/media_source_engine.js +215 -27
- package/lib/media/segment_index.js +5 -5
- package/lib/media/segment_reference.js +10 -5
- package/lib/media/streaming_engine.js +44 -39
- package/lib/mss/mss_parser.js +1 -0
- package/lib/net/networking_engine.js +1 -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 +3 -0
- package/lib/player.js +142 -72
- package/lib/routing/payload.js +5 -1
- package/lib/text/cue.js +62 -47
- package/lib/text/ttml_text_parser.js +17 -0
- package/lib/text/ui_text_displayer.js +4 -0
- package/lib/text/vtt_text_parser.js +35 -22
- package/lib/transmuxer/h265.js +862 -0
- package/lib/transmuxer/mpeg_ts_transmuxer.js +3 -2
- package/lib/transmuxer/ts_transmuxer.js +160 -15
- package/lib/util/cmcd_manager.js +6 -1
- package/lib/util/error.js +28 -9
- package/lib/util/exp_golomb.js +30 -2
- package/lib/util/fake_event.js +3 -0
- package/lib/util/manifest_parser_utils.js +10 -4
- package/lib/util/mp4_generator.js +4 -4
- package/lib/util/periods.js +2 -0
- package/lib/util/platform.js +54 -0
- package/lib/util/player_configuration.js +8 -0
- package/lib/util/state_history.js +6 -2
- package/lib/util/stream_utils.js +133 -217
- package/lib/util/ts_parser.js +229 -43
- package/maintained-branches.md +3 -2
- package/package.json +4 -6
- package/roadmap.md +15 -5
- package/shaka-player.uncompiled.js +2 -1
- package/support.html +0 -1
- package/test/cast/cast_receiver_integration.js +47 -0
- package/test/codec_switching/codec_switching_integration.js +181 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_integration.js +73 -0
- package/test/dash/dash_parser_live_unit.js +2 -0
- package/test/dash/dash_parser_manifest_unit.js +47 -0
- package/test/dash/dash_parser_segment_base_unit.js +7 -0
- package/test/dash/dash_parser_segment_list_unit.js +23 -17
- package/test/dash/dash_parser_segment_template_unit.js +49 -0
- package/test/demo/demo_unit.js +0 -16
- package/test/hls/hls_live_unit.js +35 -0
- package/test/hls/hls_parser_unit.js +8 -61
- package/test/media/adaptation_set_criteria_unit.js +118 -0
- package/test/media/adaptation_set_unit.js +1 -0
- package/test/media/media_source_engine_unit.js +165 -1
- package/test/media/segment_index_unit.js +4 -4
- package/test/media/segment_prefetch_unit.js +1 -1
- package/test/media/streaming_engine_unit.js +17 -17
- package/test/mss/mss_parser_unit.js +2 -0
- package/test/offline/manifest_convert_unit.js +5 -0
- package/test/offline/storage_integration.js +1 -4
- package/test/player_unit.js +102 -131
- package/test/routing/walker_unit.js +1 -0
- package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/dash.mpd +18 -0
- package/test/test/assets/dash-aes-128/license +1 -0
- package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
- package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
- package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
- package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
- package/test/test/assets/hls-ts-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
- package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
- package/test/test/util/dash_parser_util.js +20 -7
- package/test/test/util/fake_ad_manager.js +20 -0
- package/test/test/util/fake_media_source_engine.js +8 -2
- package/test/test/util/manifest_generator.js +7 -3
- package/test/test/util/mss_parser_util.js +4 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +7 -4
- package/test/text/ttml_text_parser_unit.js +52 -0
- package/test/text/vtt_text_parser_unit.js +105 -48
- package/test/transmuxer/transmuxer_integration.js +121 -4
- package/test/ui/ui_unit.js +3 -10
- package/test/util/stream_utils_unit.js +208 -74
- package/test/util/ts_parser_unit.js +1 -1
- package/ui/controls.js +125 -0
- package/ui/externs/ui.js +8 -1
- package/ui/pip_button.js +22 -120
- package/ui/remote_button.js +201 -0
- package/ui/ui.js +5 -2
- package/demo/common/message_ids.js +0 -309
- package/demo/locales/en.json +0 -287
- package/demo/locales/source.json +0 -1142
- package/externs/mux.js +0 -69
- package/lib/lcevc/lcevc_dil.js +0 -152
- package/lib/transmuxer/muxjs_transmuxer.js +0 -242
- package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
|
@@ -36,8 +36,8 @@ describe('Transmuxer Player', () => {
|
|
|
36
36
|
// We must enable this, once it is resolved:
|
|
37
37
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1450313
|
|
38
38
|
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
39
|
-
if (shaka.util.Platform.isEdge() &&
|
|
40
|
-
chromeVersion && chromeVersion <=
|
|
39
|
+
if (shaka.util.Platform.isWindows() && shaka.util.Platform.isEdge() &&
|
|
40
|
+
chromeVersion && chromeVersion <= 118) {
|
|
41
41
|
return false;
|
|
42
42
|
}
|
|
43
43
|
return true;
|
|
@@ -57,8 +57,8 @@ describe('Transmuxer Player', () => {
|
|
|
57
57
|
// We must enable this, once it is resolved:
|
|
58
58
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1450313
|
|
59
59
|
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
60
|
-
if (shaka.util.Platform.isEdge() &&
|
|
61
|
-
chromeVersion && chromeVersion <=
|
|
60
|
+
if (shaka.util.Platform.isWindows() && shaka.util.Platform.isEdge() &&
|
|
61
|
+
chromeVersion && chromeVersion <= 118) {
|
|
62
62
|
return false;
|
|
63
63
|
}
|
|
64
64
|
return true;
|
|
@@ -273,6 +273,33 @@ describe('Transmuxer Player', () => {
|
|
|
273
273
|
|
|
274
274
|
await player.unload();
|
|
275
275
|
});
|
|
276
|
+
|
|
277
|
+
it('H.265 in TS', async () => {
|
|
278
|
+
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
279
|
+
if (shaka.util.Platform.isWindows() &&
|
|
280
|
+
chromeVersion && chromeVersion === 117) {
|
|
281
|
+
// It appears that Chrome 117 beta in Windows is incorrectly reporting
|
|
282
|
+
// H.265 in MediaCapabilities
|
|
283
|
+
pending('Codec H.265 is not supported by the platform.');
|
|
284
|
+
}
|
|
285
|
+
const mimeType = 'video/mp4; codecs="hvc1.2.4.L123.B0"';
|
|
286
|
+
if (!MediaSource.isTypeSupported(mimeType)) {
|
|
287
|
+
pending('Codec H.265 is not supported by the platform.');
|
|
288
|
+
}
|
|
289
|
+
await player.load('/base/test/test/assets/hls-ts-h265/hevc.m3u8');
|
|
290
|
+
await video.play();
|
|
291
|
+
expect(player.isLive()).toBe(false);
|
|
292
|
+
|
|
293
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
294
|
+
// seconds, fail the test.
|
|
295
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
296
|
+
|
|
297
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
298
|
+
// longer than 45 seconds, fail the test.
|
|
299
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
300
|
+
|
|
301
|
+
await player.unload();
|
|
302
|
+
});
|
|
276
303
|
});
|
|
277
304
|
|
|
278
305
|
describe('for muxed content', () => {
|
|
@@ -292,5 +319,95 @@ describe('Transmuxer Player', () => {
|
|
|
292
319
|
|
|
293
320
|
await player.unload();
|
|
294
321
|
});
|
|
322
|
+
|
|
323
|
+
it('H.265+AAC in TS', async () => {
|
|
324
|
+
const chromeVersion = shaka.util.Platform.chromeVersion();
|
|
325
|
+
if (shaka.util.Platform.isWindows() &&
|
|
326
|
+
chromeVersion && chromeVersion === 117) {
|
|
327
|
+
// It appears that Chrome 117 beta in Windows is incorrectly reporting
|
|
328
|
+
// H.265 in MediaCapabilities
|
|
329
|
+
pending('Codec H.265 is not supported by the platform.');
|
|
330
|
+
}
|
|
331
|
+
if (!MediaSource.isTypeSupported('video/mp4; codecs="hvc1.1.6.L93.90"')) {
|
|
332
|
+
pending('Codec H.265 is not supported by the platform.');
|
|
333
|
+
}
|
|
334
|
+
// eslint-disable-next-line max-len
|
|
335
|
+
await player.load('/base/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8');
|
|
336
|
+
await video.play();
|
|
337
|
+
expect(player.isLive()).toBe(false);
|
|
338
|
+
|
|
339
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
340
|
+
// seconds, fail the test.
|
|
341
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
342
|
+
|
|
343
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
344
|
+
// longer than 45 seconds, fail the test.
|
|
345
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
346
|
+
|
|
347
|
+
await player.unload();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('H.264+MP3 in TS', async () => {
|
|
351
|
+
if (!MediaSource.isTypeSupported('audio/mp4; codecs="mp3"')) {
|
|
352
|
+
pending('Codec MP3 in MP4 is not supported by the platform.');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// eslint-disable-next-line max-len
|
|
356
|
+
await player.load('/base/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8');
|
|
357
|
+
await video.play();
|
|
358
|
+
expect(player.isLive()).toBe(false);
|
|
359
|
+
|
|
360
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
361
|
+
// seconds, fail the test.
|
|
362
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
363
|
+
|
|
364
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
365
|
+
// longer than 45 seconds, fail the test.
|
|
366
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
367
|
+
|
|
368
|
+
await player.unload();
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it('H.264+AC3 in TS', async () => {
|
|
372
|
+
if (!isAc3Supported()) {
|
|
373
|
+
pending('Codec AC-3 is not supported by the platform.');
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// eslint-disable-next-line max-len
|
|
377
|
+
await player.load('/base/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8');
|
|
378
|
+
await video.play();
|
|
379
|
+
expect(player.isLive()).toBe(false);
|
|
380
|
+
|
|
381
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
382
|
+
// seconds, fail the test.
|
|
383
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
384
|
+
|
|
385
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
386
|
+
// longer than 45 seconds, fail the test.
|
|
387
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
388
|
+
|
|
389
|
+
await player.unload();
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it('H.264+EC3 in TS', async () => {
|
|
393
|
+
if (!isEc3Supported()) {
|
|
394
|
+
pending('Codec EC-3 is not supported by the platform.');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// eslint-disable-next-line max-len
|
|
398
|
+
await player.load('/base/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8');
|
|
399
|
+
await video.play();
|
|
400
|
+
expect(player.isLive()).toBe(false);
|
|
401
|
+
|
|
402
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
403
|
+
// seconds, fail the test.
|
|
404
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
405
|
+
|
|
406
|
+
// Play for 15 seconds, but stop early if the video ends. If it takes
|
|
407
|
+
// longer than 45 seconds, fail the test.
|
|
408
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 15, 45);
|
|
409
|
+
|
|
410
|
+
await player.unload();
|
|
411
|
+
});
|
|
295
412
|
});
|
|
296
413
|
});
|
package/test/ui/ui_unit.js
CHANGED
|
@@ -616,19 +616,10 @@ describe('UI', () => {
|
|
|
616
616
|
player.configure('abr.enabled', false);
|
|
617
617
|
|
|
618
618
|
const tracks = player.getVariantTracks();
|
|
619
|
-
const en2 =
|
|
620
|
-
tracks.find((t) => t.language == 'en' && t.channelsCount == 2);
|
|
621
619
|
const en1 =
|
|
622
620
|
tracks.find((t) => t.language == 'en' && t.channelsCount == 1);
|
|
623
621
|
const es = tracks.find((t) => t.language == 'es');
|
|
624
622
|
|
|
625
|
-
// There are 3 variants with English 2-channel, but one is a duplicate
|
|
626
|
-
// and shouldn't appear in the list.
|
|
627
|
-
goog.asserts.assert(en2, 'Unable to find tracks');
|
|
628
|
-
player.selectVariantTrack(en2, true);
|
|
629
|
-
await updateResolutionMenu();
|
|
630
|
-
expect(getResolutions()).toEqual(['240p', '480p']);
|
|
631
|
-
|
|
632
623
|
// There is 1 variant with English 1-channel.
|
|
633
624
|
goog.asserts.assert(en1, 'Unable to find tracks');
|
|
634
625
|
player.selectVariantTrack(en1, true);
|
|
@@ -646,7 +637,9 @@ describe('UI', () => {
|
|
|
646
637
|
const manifest =
|
|
647
638
|
shaka.test.ManifestGenerator.generate((manifest) => {
|
|
648
639
|
manifest.addVariant(0, (variant) => {
|
|
649
|
-
variant.addAudio(0)
|
|
640
|
+
variant.addAudio(0, (stream) => {
|
|
641
|
+
stream.roles = ['main'];
|
|
642
|
+
});
|
|
650
643
|
variant.bandwidth = 100000;
|
|
651
644
|
});
|
|
652
645
|
manifest.addVariant(1, (variant) => {
|
|
@@ -636,7 +636,8 @@ describe('StreamUtils', () => {
|
|
|
636
636
|
|
|
637
637
|
const noVariant = null;
|
|
638
638
|
await shaka.util.StreamUtils.filterManifest(
|
|
639
|
-
fakeDrmEngine, noVariant, manifest
|
|
639
|
+
fakeDrmEngine, noVariant, manifest,
|
|
640
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
640
641
|
|
|
641
642
|
// Covers a regression in which we would remove streams with codecs.
|
|
642
643
|
// The last two streams should be removed because their full MIME types
|
|
@@ -673,7 +674,8 @@ describe('StreamUtils', () => {
|
|
|
673
674
|
|
|
674
675
|
const noVariant = null;
|
|
675
676
|
await shaka.util.StreamUtils.filterManifest(
|
|
676
|
-
fakeDrmEngine, noVariant, manifest
|
|
677
|
+
fakeDrmEngine, noVariant, manifest,
|
|
678
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
677
679
|
|
|
678
680
|
// Covers a regression in which we would remove streams with codecs.
|
|
679
681
|
// The first 4 streams should be there because they are always supported.
|
|
@@ -691,6 +693,38 @@ describe('StreamUtils', () => {
|
|
|
691
693
|
jasmine.objectContaining({id: 5}));
|
|
692
694
|
});
|
|
693
695
|
|
|
696
|
+
it('does not filter manifest when codec switching is enabled', async () => {
|
|
697
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
698
|
+
manifest.addVariant(1, (variant) => {
|
|
699
|
+
variant.addAudio(10, (stream) => {
|
|
700
|
+
stream.codecs = 'mp4a.69';
|
|
701
|
+
});
|
|
702
|
+
variant.addVideo(11, (stream) => {
|
|
703
|
+
stream.codecs = 'avc1';
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
const originalFilterManifestByCurrentVariant =
|
|
709
|
+
shaka.util.StreamUtils.filterManifestByCurrentVariant;
|
|
710
|
+
|
|
711
|
+
try {
|
|
712
|
+
const filterManifestByCurrentVariantSpy =
|
|
713
|
+
jasmine.createSpy('filterManifestByCurrentVariant');
|
|
714
|
+
shaka.util.StreamUtils.filterManifestByCurrentVariant =
|
|
715
|
+
shaka.test.Util.spyFunc(filterManifestByCurrentVariantSpy);
|
|
716
|
+
|
|
717
|
+
await shaka.util.StreamUtils.filterManifest(
|
|
718
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest,
|
|
719
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
720
|
+
|
|
721
|
+
expect(filterManifestByCurrentVariantSpy).not.toHaveBeenCalled();
|
|
722
|
+
} finally {
|
|
723
|
+
shaka.util.StreamUtils.filterManifestByCurrentVariant =
|
|
724
|
+
originalFilterManifestByCurrentVariant;
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
|
|
694
728
|
it('filters transport streams', async () => {
|
|
695
729
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
696
730
|
manifest.addVariant(0, (variant) => {
|
|
@@ -705,7 +739,8 @@ describe('StreamUtils', () => {
|
|
|
705
739
|
});
|
|
706
740
|
|
|
707
741
|
await shaka.util.StreamUtils.filterManifest(
|
|
708
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
742
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest,
|
|
743
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
709
744
|
|
|
710
745
|
// Covers a regression in which we would remove streams with codecs.
|
|
711
746
|
// The last two streams should be removed because their full MIME types
|
|
@@ -732,7 +767,8 @@ describe('StreamUtils', () => {
|
|
|
732
767
|
});
|
|
733
768
|
|
|
734
769
|
await shaka.util.StreamUtils.filterManifest(
|
|
735
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
770
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest,
|
|
771
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
736
772
|
expect(manifest.variants.length).toBe(1);
|
|
737
773
|
});
|
|
738
774
|
|
|
@@ -749,7 +785,8 @@ describe('StreamUtils', () => {
|
|
|
749
785
|
});
|
|
750
786
|
|
|
751
787
|
await shaka.util.StreamUtils.filterManifest(
|
|
752
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
788
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest,
|
|
789
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
753
790
|
|
|
754
791
|
expect(manifest.variants.length).toBe(1);
|
|
755
792
|
});
|
|
@@ -813,148 +850,245 @@ describe('StreamUtils', () => {
|
|
|
813
850
|
});
|
|
814
851
|
|
|
815
852
|
await shaka.util.StreamUtils.filterManifest(
|
|
816
|
-
fakeDrmEngine, /* currentVariant= */ null, manifest
|
|
853
|
+
fakeDrmEngine, /* currentVariant= */ null, manifest,
|
|
854
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
817
855
|
|
|
818
856
|
expect(manifest.variants.length).toBe(1);
|
|
819
857
|
});
|
|
820
858
|
});
|
|
821
859
|
|
|
822
860
|
describe('chooseCodecsAndFilterManifest', () => {
|
|
823
|
-
const
|
|
824
|
-
const vp09Codecs = 'vp09.00.40.08.00.02.02.02.00';
|
|
825
|
-
|
|
826
|
-
const addVariant1080Avc1 = (manifest) => {
|
|
861
|
+
const addVariant720Avc1 = (manifest) => {
|
|
827
862
|
manifest.addVariant(0, (variant) => {
|
|
828
863
|
variant.bandwidth = 5058558;
|
|
829
864
|
variant.addAudio(1, (stream) => {
|
|
830
865
|
stream.bandwidth = 129998;
|
|
831
|
-
stream.
|
|
866
|
+
stream.mime('audio/mp4', 'mp4a.40.2');
|
|
832
867
|
});
|
|
833
868
|
variant.addVideo(2, (stream) => {
|
|
834
869
|
stream.bandwidth = 4928560;
|
|
835
|
-
stream.
|
|
836
|
-
stream.
|
|
870
|
+
stream.size(1280, 720);
|
|
871
|
+
stream.mime('video/mp4', 'avc1.640028');
|
|
837
872
|
});
|
|
838
873
|
});
|
|
839
874
|
};
|
|
840
875
|
|
|
841
|
-
const
|
|
876
|
+
const addVariant720Vp9 = (manifest) => {
|
|
842
877
|
manifest.addVariant(3, (variant) => {
|
|
843
878
|
variant.bandwidth = 4911000;
|
|
844
879
|
variant.addAudio(4, (stream) => {
|
|
845
880
|
stream.bandwidth = 129998;
|
|
846
|
-
stream.
|
|
881
|
+
stream.mime('audio/webm', 'vorbis');
|
|
847
882
|
});
|
|
848
883
|
variant.addVideo(5, (stream) => {
|
|
849
884
|
stream.bandwidth = 4781002;
|
|
850
|
-
stream.
|
|
851
|
-
stream.
|
|
885
|
+
stream.size(1280, 720);
|
|
886
|
+
stream.mime('video/webm', 'vp9');
|
|
852
887
|
});
|
|
853
888
|
});
|
|
854
889
|
};
|
|
855
890
|
|
|
856
|
-
const
|
|
891
|
+
const addVariant1080Vp9 = (manifest) => {
|
|
857
892
|
manifest.addVariant(6, (variant) => {
|
|
858
893
|
variant.bandwidth = 10850316;
|
|
859
|
-
variant.addAudio(
|
|
894
|
+
variant.addAudio(1, (stream) => {
|
|
860
895
|
stream.bandwidth = 129998;
|
|
861
|
-
stream.
|
|
896
|
+
stream.mime('audio/mp4', 'mp4a.40.2');
|
|
862
897
|
});
|
|
863
898
|
variant.addVideo(8, (stream) => {
|
|
864
899
|
stream.bandwidth = 10784324;
|
|
865
|
-
stream.
|
|
866
|
-
stream.
|
|
900
|
+
stream.size(1920, 1080);
|
|
901
|
+
stream.mime('video/webm', 'vp9');
|
|
867
902
|
});
|
|
868
903
|
});
|
|
869
904
|
};
|
|
870
905
|
|
|
906
|
+
it('should filter variants by the best available bandwidth' +
|
|
907
|
+
' for video resolution', () => {
|
|
908
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
909
|
+
manifest.addVariant(0, (variant) => {
|
|
910
|
+
variant.bandwidth = 4058558;
|
|
911
|
+
variant.addVideo(1, (stream) => {
|
|
912
|
+
stream.bandwidth = 300000;
|
|
913
|
+
stream.size(10, 10);
|
|
914
|
+
});
|
|
915
|
+
});
|
|
916
|
+
manifest.addVariant(2, (variant) => {
|
|
917
|
+
variant.bandwidth = 4781002;
|
|
918
|
+
variant.addVideo(3, (stream) => {
|
|
919
|
+
stream.bandwidth = 400000;
|
|
920
|
+
stream.size(10, 10);
|
|
921
|
+
});
|
|
922
|
+
});
|
|
923
|
+
manifest.addVariant(4, (variant) => {
|
|
924
|
+
variant.addVideo(5, (stream) => {
|
|
925
|
+
stream.bandwidth = 500000;
|
|
926
|
+
stream.size(20, 20);
|
|
927
|
+
});
|
|
928
|
+
});
|
|
929
|
+
manifest.addVariant(6, (variant) => {
|
|
930
|
+
variant.addVideo(7, (stream) => {
|
|
931
|
+
stream.bandwidth = 600000;
|
|
932
|
+
stream.size(20, 20);
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
938
|
+
/* preferredVideoCodecs= */[],
|
|
939
|
+
/* preferredAudioCodecs= */[],
|
|
940
|
+
/* preferredAudioChannelCount= */2,
|
|
941
|
+
/* preferredDecodingAttributes= */[]);
|
|
942
|
+
|
|
943
|
+
expect(manifest.variants.length).toBe(2);
|
|
944
|
+
expect(manifest.variants.every((v) => [300000, 500000].includes(
|
|
945
|
+
v.video.bandwidth))).toBeTruthy();
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
it('should filter variants by the best available bandwidth' +
|
|
949
|
+
' for audio language', () => {
|
|
950
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
951
|
+
manifest.addVariant(0, (variant) => {
|
|
952
|
+
variant.bandwidth = 4058558;
|
|
953
|
+
variant.addAudio(1, (stream) => {
|
|
954
|
+
stream.bandwidth = 100000;
|
|
955
|
+
stream.language = 'en';
|
|
956
|
+
});
|
|
957
|
+
});
|
|
958
|
+
manifest.addVariant(2, (variant) => {
|
|
959
|
+
variant.bandwidth = 4781002;
|
|
960
|
+
variant.addAudio(3, (stream) => {
|
|
961
|
+
stream.bandwidth = 200000;
|
|
962
|
+
stream.language = 'en';
|
|
963
|
+
});
|
|
964
|
+
});
|
|
965
|
+
manifest.addVariant(4, (variant) => {
|
|
966
|
+
variant.addAudio(5, (stream) => {
|
|
967
|
+
stream.bandwidth = 100000;
|
|
968
|
+
stream.language = 'es';
|
|
969
|
+
});
|
|
970
|
+
});
|
|
971
|
+
manifest.addVariant(6, (variant) => {
|
|
972
|
+
variant.addAudio(7, (stream) => {
|
|
973
|
+
stream.bandwidth = 500000;
|
|
974
|
+
stream.language = 'es';
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
980
|
+
/* preferredVideoCodecs= */[],
|
|
981
|
+
/* preferredAudioCodecs= */[],
|
|
982
|
+
/* preferredAudioChannelCount= */2,
|
|
983
|
+
/* preferredDecodingAttributes= */[]);
|
|
984
|
+
|
|
985
|
+
expect(manifest.variants.length).toBe(2);
|
|
986
|
+
expect(manifest.variants.every((v) => v.audio.bandwidth == 100000))
|
|
987
|
+
.toBeTruthy();
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
it('should allow multiple codecs for codec switching', () => {
|
|
991
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
|
|
992
|
+
pending('Codec VP9 is not supported by the platform.');
|
|
993
|
+
}
|
|
994
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
|
|
995
|
+
pending('Codec vorbis is not supported by the platform.');
|
|
996
|
+
}
|
|
997
|
+
// This test is flaky in some Tizen devices, due to codec restrictions.
|
|
998
|
+
if (shaka.util.Platform.isTizen()) {
|
|
999
|
+
pending('Skip flaky test in Tizen');
|
|
1000
|
+
}
|
|
1001
|
+
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
1002
|
+
addVariant720Avc1(manifest);
|
|
1003
|
+
addVariant720Vp9(manifest);
|
|
1004
|
+
addVariant1080Vp9(manifest);
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
manifest.variants[0].video.bandwidth = 1;
|
|
1008
|
+
|
|
1009
|
+
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
1010
|
+
/* preferredVideoCodecs= */[],
|
|
1011
|
+
/* preferredAudioCodecs= */[],
|
|
1012
|
+
/* preferredAudioChannelCount= */2,
|
|
1013
|
+
/* preferredDecodingAttributes= */[]);
|
|
1014
|
+
|
|
1015
|
+
expect(manifest.variants.length).toBe(2);
|
|
1016
|
+
expect(manifest.variants[0].video.codecs)
|
|
1017
|
+
.not.toBe(manifest.variants[1].video.codecs);
|
|
1018
|
+
});
|
|
1019
|
+
|
|
871
1020
|
it('chooses preferred audio and video codecs', () => {
|
|
1021
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
|
|
1022
|
+
pending('Codec VP9 is not supported by the platform.');
|
|
1023
|
+
}
|
|
1024
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
|
|
1025
|
+
pending('Codec vorbis is not supported by the platform.');
|
|
1026
|
+
}
|
|
872
1027
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
873
|
-
|
|
1028
|
+
addVariant720Avc1(manifest);
|
|
1029
|
+
addVariant720Vp9(manifest);
|
|
874
1030
|
addVariant1080Vp9(manifest);
|
|
875
|
-
addVariant2160Vp9(manifest);
|
|
876
1031
|
});
|
|
877
1032
|
const variants =
|
|
878
1033
|
shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
|
|
879
|
-
/* preferredVideoCodecs= */['
|
|
880
|
-
/* preferredAudioCodecs= */['
|
|
1034
|
+
/* preferredVideoCodecs= */['vp9'],
|
|
1035
|
+
/* preferredAudioCodecs= */['mp4a']);
|
|
881
1036
|
|
|
882
1037
|
expect(variants.length).toBe(1);
|
|
883
|
-
expect(variants[0].video.codecs).toBe(
|
|
884
|
-
expect(variants[0].audio.codecs).toBe('
|
|
1038
|
+
expect(variants[0].video.codecs).toBe('vp9');
|
|
1039
|
+
expect(variants[0].audio.codecs).toBe('mp4a.40.2');
|
|
885
1040
|
});
|
|
886
1041
|
|
|
887
1042
|
it('chooses preferred video codecs', () => {
|
|
1043
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
|
|
1044
|
+
pending('Codec VP9 is not supported by the platform.');
|
|
1045
|
+
}
|
|
1046
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
|
|
1047
|
+
pending('Codec vorbis is not supported by the platform.');
|
|
1048
|
+
}
|
|
888
1049
|
// If no preferred audio codecs is specified or can be found, choose the
|
|
889
1050
|
// variants with preferred video codecs.
|
|
890
1051
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
891
|
-
|
|
1052
|
+
addVariant720Avc1(manifest);
|
|
1053
|
+
addVariant720Vp9(manifest);
|
|
892
1054
|
addVariant1080Vp9(manifest);
|
|
893
|
-
addVariant2160Vp9(manifest);
|
|
894
1055
|
});
|
|
895
1056
|
const variants =
|
|
896
1057
|
shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
|
|
897
|
-
/* preferredVideoCodecs= */['
|
|
1058
|
+
/* preferredVideoCodecs= */['vp9'],
|
|
898
1059
|
/* preferredAudioCodecs= */[]);
|
|
899
1060
|
|
|
900
1061
|
expect(variants.length).toBe(2);
|
|
901
|
-
expect(variants[0].video.codecs).toBe(
|
|
1062
|
+
expect(variants[0].video.codecs).toBe('vp9');
|
|
902
1063
|
expect(variants[0].audio.codecs).toBe('vorbis');
|
|
903
|
-
expect(variants[1].video.codecs).toBe(
|
|
904
|
-
expect(variants[1].audio.codecs).toBe('
|
|
1064
|
+
expect(variants[1].video.codecs).toBe('vp9');
|
|
1065
|
+
expect(variants[1].audio.codecs).toBe('mp4a.40.2');
|
|
905
1066
|
});
|
|
906
1067
|
|
|
907
1068
|
it('chooses preferred audio codecs', () => {
|
|
1069
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
|
|
1070
|
+
pending('Codec VP9 is not supported by the platform.');
|
|
1071
|
+
}
|
|
1072
|
+
if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
|
|
1073
|
+
pending('Codec vorbis is not supported by the platform.');
|
|
1074
|
+
}
|
|
908
1075
|
// If no preferred video codecs is specified or can be found, choose the
|
|
909
1076
|
// variants with preferred audio codecs.
|
|
910
1077
|
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
911
|
-
|
|
1078
|
+
addVariant720Avc1(manifest);
|
|
1079
|
+
addVariant720Vp9(manifest);
|
|
912
1080
|
addVariant1080Vp9(manifest);
|
|
913
|
-
addVariant2160Vp9(manifest);
|
|
914
1081
|
});
|
|
915
1082
|
const variants =
|
|
916
1083
|
shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
|
|
917
1084
|
/* preferredVideoCodecs= */['foo'],
|
|
918
|
-
/* preferredAudioCodecs= */['
|
|
1085
|
+
/* preferredAudioCodecs= */['mp4a.40.2']);
|
|
919
1086
|
|
|
920
1087
|
expect(variants.length).toBe(2);
|
|
921
|
-
expect(variants[0].video.codecs).toBe(
|
|
922
|
-
expect(variants[0].audio.codecs).toBe('
|
|
923
|
-
expect(variants[1].video.codecs).toBe(
|
|
924
|
-
expect(variants[1].audio.codecs).toBe('
|
|
925
|
-
});
|
|
926
|
-
|
|
927
|
-
it('chooses variants with different sizes (density) by codecs', () => {
|
|
928
|
-
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
929
|
-
addVariant1080Avc1(manifest);
|
|
930
|
-
addVariant1080Vp9(manifest);
|
|
931
|
-
addVariant2160Vp9(manifest);
|
|
932
|
-
});
|
|
933
|
-
|
|
934
|
-
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
935
|
-
/* preferredVideoCodecs= */[],
|
|
936
|
-
/* preferredAudioCodecs= */[],
|
|
937
|
-
/* preferredAudioChannelCount= */2,
|
|
938
|
-
/* preferredDecodingAttributes= */[]);
|
|
939
|
-
|
|
940
|
-
expect(manifest.variants.length).toBe(1);
|
|
941
|
-
expect(manifest.variants[0].video.codecs).toBe(vp09Codecs);
|
|
942
|
-
});
|
|
943
|
-
|
|
944
|
-
it('chooses variants with same sizes (density) by codecs', () => {
|
|
945
|
-
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
946
|
-
addVariant1080Avc1(manifest);
|
|
947
|
-
addVariant1080Vp9(manifest);
|
|
948
|
-
});
|
|
949
|
-
|
|
950
|
-
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
|
|
951
|
-
/* preferredVideoCodecs= */[],
|
|
952
|
-
/* preferredAudioCodecs= */[],
|
|
953
|
-
/* preferredAudioChannelCount= */2,
|
|
954
|
-
/* preferredDecodingAttributes= */[]);
|
|
955
|
-
|
|
956
|
-
expect(manifest.variants.length).toBe(1);
|
|
957
|
-
expect(manifest.variants[0].video.codecs).toBe(vp09Codecs);
|
|
1088
|
+
expect(variants[0].video.codecs).toBe('avc1.640028');
|
|
1089
|
+
expect(variants[0].audio.codecs).toBe('mp4a.40.2');
|
|
1090
|
+
expect(variants[1].video.codecs).toBe('vp9');
|
|
1091
|
+
expect(variants[1].audio.codecs).toBe('mp4a.40.2');
|
|
958
1092
|
});
|
|
959
1093
|
|
|
960
1094
|
it('chooses variants by decoding attributes', async () => {
|