shaka-player 4.4.3 → 4.6.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/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/workflows/release-please.yaml +2 -27
- package/AUTHORS +2 -0
- package/CHANGELOG.md +156 -39
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +54 -42
- 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 +33 -22
- package/demo/common/assets.js +249 -60
- package/demo/config.js +219 -253
- package/demo/custom.js +88 -133
- 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 +62 -126
- package/demo/search.js +29 -34
- 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/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +211 -228
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +211 -228
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +42 -37
- package/dist/locales.js +34 -30
- package/dist/receiver.compiled.debug.js +64 -77
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +64 -77
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.externs.js +356 -117
- package/dist/shaka-player.compiled.debug.js +952 -811
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +356 -117
- package/dist/shaka-player.compiled.js +1165 -1078
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +359 -153
- package/dist/shaka-player.ui.debug.d.ts +359 -153
- package/dist/shaka-player.ui.debug.externs.js +382 -117
- package/dist/shaka-player.ui.debug.js +1084 -918
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +382 -117
- package/dist/shaka-player.ui.js +1377 -1274
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-integration.md +14 -14
- package/docs/tutorials/ad_monetization.md +54 -0
- package/docs/tutorials/basic-usage.md +2 -1
- package/docs/tutorials/errors.md +2 -1
- 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 +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +17 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/css_style_declaration.js +19 -0
- package/externs/lcevc.js +37 -13
- package/externs/managedmediasource.js +24 -0
- package/externs/media_remote.js +68 -0
- package/externs/mediatailor.js +193 -0
- package/externs/pictureinpicture.js +11 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/ads.js +27 -0
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +31 -10
- package/externs/shaka/manifest_parser.js +24 -1
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +13 -2
- package/externs/shaka/player.js +65 -8
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/karma.conf.js +7 -3
- package/lib/abr/simple_abr_manager.js +66 -9
- 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 +839 -0
- package/lib/cast/cast_receiver.js +1 -1
- package/lib/cea/cea_decoder.js +28 -0
- package/lib/cea/dummy_caption_decoder.js +5 -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 +322 -93
- package/lib/dash/mpd_utils.js +62 -37
- package/lib/dash/segment_base.js +17 -10
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +122 -107
- package/lib/dependencies/all.js +8 -7
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +798 -658
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/lcevc/lcevc_dec.js +220 -0
- package/lib/media/adaptation_set.js +32 -14
- package/lib/media/adaptation_set_criteria.js +86 -16
- package/lib/media/closed_caption_parser.js +13 -0
- package/lib/media/content_workarounds.js +6 -0
- package/lib/media/drm_engine.js +8 -13
- package/lib/media/manifest_parser.js +8 -113
- package/lib/media/media_source_capabilities.js +10 -3
- package/lib/media/media_source_engine.js +286 -44
- package/lib/media/play_rate_controller.js +8 -38
- package/lib/media/presentation_timeline.js +7 -1
- package/lib/media/quality_observer.js +1 -1
- package/lib/media/segment_index.js +6 -6
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +73 -7
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +73 -38
- package/lib/mss/mss_parser.js +19 -2
- package/lib/net/networking_engine.js +67 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +3 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +3 -0
- package/lib/offline/manifest_converter.js +3 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +14 -7
- package/lib/player.js +1098 -1537
- package/lib/polyfill/mediasource.js +22 -1
- package/lib/text/cue.js +15 -0
- package/lib/text/mp4_ttml_parser.js +2 -2
- package/lib/text/srt_text_parser.js +2 -2
- package/lib/text/stub_text_displayer.js +51 -0
- package/lib/text/text_engine.js +3 -2
- package/lib/text/ttml_text_parser.js +45 -5
- package/lib/text/ui_text_displayer.js +8 -0
- package/lib/text/vtt_text_parser.js +40 -22
- package/lib/transmuxer/aac_transmuxer.js +1 -1
- package/lib/transmuxer/ac3_transmuxer.js +1 -1
- package/lib/transmuxer/ec3_transmuxer.js +1 -1
- package/lib/transmuxer/h264.js +5 -4
- package/lib/transmuxer/h265.js +863 -0
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +4 -3
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +187 -22
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +30 -15
- package/lib/util/exp_golomb.js +30 -2
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +8 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +6 -8
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +156 -179
- package/lib/util/platform.js +44 -3
- package/lib/util/player_configuration.js +43 -6
- package/lib/util/state_history.js +6 -2
- package/lib/util/stream_utils.js +206 -283
- package/lib/util/ts_parser.js +335 -98
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +3 -2
- package/package.json +4 -6
- package/roadmap.md +25 -5
- package/shaka-player.uncompiled.js +2 -2
- package/support.html +0 -1
- package/test/abr/simple_abr_manager_unit.js +33 -33
- package/test/ads/ad_manager_unit.js +3 -2
- package/test/cast/cast_receiver_integration.js +50 -4
- package/test/cast/cast_utils_unit.js +2 -0
- package/test/cea/cea_decoder_unit.js +7 -0
- package/test/codec_switching/codec_switching_integration.js +182 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_integration.js +74 -0
- package/test/dash/dash_parser_live_unit.js +2 -19
- package/test/dash/dash_parser_manifest_unit.js +536 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -0
- package/test/dash/dash_parser_segment_template_unit.js +2 -0
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/demo/demo_unit.js +0 -16
- package/test/hls/hls_live_unit.js +14 -3
- package/test/hls/hls_parser_unit.js +385 -33
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +284 -15
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/content_workarounds_unit.js +1 -1
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/media_source_engine_unit.js +166 -2
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +5 -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/mss/mss_player_integration.js +3 -2
- package/test/net/networking_engine_unit.js +3 -3
- package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
- package/test/offline/manifest_convert_unit.js +14 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +22 -13
- package/test/player_external.js +4 -2
- package/test/player_integration.js +15 -4
- package/test/player_load_graph_integration.js +47 -151
- package/test/player_src_equals_external.js +1 -0
- package/test/player_src_equals_integration.js +71 -4
- package/test/player_unit.js +182 -158
- 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 +4 -0
- package/test/test/util/fake_ad_manager.js +20 -0
- package/test/test/util/fake_media_source_engine.js +13 -2
- package/test/test/util/fake_networking_engine.js +9 -1
- package/test/test/util/fake_segment_prefetch.js +3 -0
- package/test/test/util/manifest_generator.js +11 -3
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/mss_parser_util.js +4 -0
- package/test/test/util/offline_utils.js +2 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +10 -4
- package/test/test/util/test_scheme.js +6 -0
- package/test/test/util/ui_utils.js +4 -3
- package/test/text/mp4_ttml_parser_unit.js +4 -4
- package/test/text/srt_text_parser_unit.js +1 -1
- package/test/text/text_displayer_layout_unit.js +1 -1
- package/test/text/text_engine_unit.js +6 -0
- package/test/text/ttml_text_parser_unit.js +85 -2
- package/test/text/vtt_text_parser_unit.js +103 -31
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +150 -3
- package/test/ui/ad_ui_unit.js +2 -2
- package/test/ui/ui_customization_unit.js +17 -16
- package/test/ui/ui_integration.js +30 -20
- package/test/ui/ui_unit.js +28 -29
- package/test/util/buffer_utils_unit.js +1 -1
- package/test/util/content_steering_manager_unit.js +427 -0
- package/test/util/id3_utils_unit.js +52 -0
- package/test/util/stream_utils_unit.js +207 -169
- package/test/util/ts_parser_unit.js +3 -3
- package/third_party/closure-uri/uri.js +13 -1
- package/ui/audio_language_selection.js +9 -2
- package/ui/controls.js +125 -0
- package/ui/externs/ui.js +24 -2
- package/ui/language_utils.js +43 -8
- package/ui/less/range_elements.less +33 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/es-419.json +1 -0
- package/ui/locales/es.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +10 -0
- package/ui/pip_button.js +22 -120
- package/ui/remote_button.js +203 -0
- package/ui/resolution_selection.js +47 -10
- package/ui/seek_bar.js +296 -3
- package/ui/text_selection.js +2 -1
- package/ui/ui.js +11 -4
- package/demo/common/message_ids.js +0 -309
- package/demo/locales/en.json +0 -288
- package/demo/locales/source.json +0 -1146
- package/externs/mux.js +0 -69
- package/lib/lcevc/lcevc_dil.js +0 -152
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -43
- package/lib/routing/walker.js +0 -587
- package/lib/transmuxer/muxjs_transmuxer.js +0 -242
- package/test/routing/walker_unit.js +0 -504
- package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
package/roadmap.md
CHANGED
|
@@ -9,22 +9,42 @@ The goals of future milestones are fluid until we begin that development cycle,
|
|
|
9
9
|
so the exact milestone for future features is not pre-determined.
|
|
10
10
|
|
|
11
11
|
Candidate features for future release cycles:
|
|
12
|
-
- Preload API
|
|
13
|
-
https://github.com/shaka-project/shaka-player/issues/880
|
|
14
12
|
- Official TypeScript defs, generated from source
|
|
15
13
|
https://github.com/shaka-project/shaka-player/issues/1030
|
|
16
14
|
- Background fetch for offline storage
|
|
17
15
|
https://github.com/shaka-project/shaka-player/issues/879
|
|
16
|
+
- A method to stitch together clips
|
|
17
|
+
https://github.com/shaka-project/shaka-player/issues/764
|
|
18
|
+
- Predict next segment in DASH SegmentTimeline
|
|
19
|
+
https://github.com/shaka-project/shaka-player/issues/898
|
|
18
20
|
- Smaller, more modular binary
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
v5.0 - 2024 Q1
|
|
23
|
+
- Preload API
|
|
24
|
+
https://github.com/shaka-project/shaka-player/issues/880
|
|
25
|
+
- Common Media Server Data (CMSD)
|
|
26
|
+
https://github.com/shaka-project/shaka-player/issues/5890
|
|
27
|
+
|
|
28
|
+
=====
|
|
29
|
+
|
|
30
|
+
v4.6 - 2023 Q4
|
|
31
|
+
- Content Steering
|
|
32
|
+
https://github.com/shaka-project/shaka-player/issues/5704
|
|
33
|
+
- New DASH protocol for Low Latency.
|
|
34
|
+
- ManagedMediaSource
|
|
35
|
+
https://github.com/shaka-project/shaka-player/issues/5271
|
|
36
|
+
- Add thumbnails support in src=
|
|
37
|
+
- Remove state engine
|
|
38
|
+
|
|
39
|
+
v4.5 - 2023 Q4
|
|
21
40
|
- Built-in transmuxer support for muxed content streams (audio+video)
|
|
22
41
|
- Built-in transmuxer support for H265 streams
|
|
23
42
|
- Remove optional mux.js dependency
|
|
24
43
|
- Codec switching
|
|
25
44
|
https://github.com/shaka-project/shaka-player/issues/1528
|
|
26
|
-
|
|
27
|
-
|
|
45
|
+
- AES-128 in DASH.
|
|
46
|
+
https://github.com/shaka-project/shaka-player/issues/5622
|
|
47
|
+
- AWS Elemental MediaTailor
|
|
28
48
|
|
|
29
49
|
v4.4 - 2023 Q3
|
|
30
50
|
- Built-in transmuxer for common cases, no mux.js required:
|
|
@@ -50,7 +50,6 @@ goog.require('shaka.polyfill.VTTCue');
|
|
|
50
50
|
goog.require('shaka.polyfill.VideoPlayPromise');
|
|
51
51
|
goog.require('shaka.polyfill.VideoPlaybackQuality');
|
|
52
52
|
goog.require('shaka.polyfill');
|
|
53
|
-
goog.require('shaka.routing.Walker');
|
|
54
53
|
goog.require('shaka.text.Cue');
|
|
55
54
|
goog.require('shaka.text.LrcTextParser');
|
|
56
55
|
goog.require('shaka.text.Mp4TtmlParser');
|
|
@@ -72,12 +71,12 @@ goog.require('shaka.transmuxer.ADTS');
|
|
|
72
71
|
goog.require('shaka.transmuxer.Ec3');
|
|
73
72
|
goog.require('shaka.transmuxer.Ec3Transmuxer');
|
|
74
73
|
goog.require('shaka.transmuxer.H264');
|
|
74
|
+
goog.require('shaka.transmuxer.H265');
|
|
75
75
|
goog.require('shaka.transmuxer.Mp3Transmuxer');
|
|
76
76
|
goog.require('shaka.transmuxer.MpegAudio');
|
|
77
77
|
goog.require('shaka.transmuxer.MpegTsTransmuxer');
|
|
78
78
|
goog.require('shaka.transmuxer.TransmuxerEngine');
|
|
79
79
|
goog.require('shaka.transmuxer.MssTransmuxer');
|
|
80
|
-
goog.require('shaka.transmuxer.MuxjsTransmuxer');
|
|
81
80
|
goog.require('shaka.transmuxer.TsTransmuxer');
|
|
82
81
|
goog.require('shaka.ui.Controls');
|
|
83
82
|
goog.require('shaka.ui.PlayButton');
|
|
@@ -100,6 +99,7 @@ goog.require('shaka.ui.Overlay');
|
|
|
100
99
|
goog.require('shaka.ui.PipButton');
|
|
101
100
|
goog.require('shaka.ui.PlaybackRateSelection');
|
|
102
101
|
goog.require('shaka.ui.PresentationTimeTracker');
|
|
102
|
+
goog.require('shaka.ui.RemoteButton');
|
|
103
103
|
goog.require('shaka.ui.ResolutionSelection');
|
|
104
104
|
goog.require('shaka.ui.RewindButton');
|
|
105
105
|
goog.require('shaka.ui.SkipAdButton');
|
package/support.html
CHANGED
|
@@ -145,14 +145,14 @@ describe('SimpleAbrManager', () => {
|
|
|
145
145
|
abrManager.setVariants(variants);
|
|
146
146
|
abrManager.chooseVariant();
|
|
147
147
|
|
|
148
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
149
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
148
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
149
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
150
150
|
|
|
151
151
|
abrManager.enable();
|
|
152
152
|
|
|
153
153
|
// Make another call to segmentDownloaded() so switchCallback() is
|
|
154
154
|
// called.
|
|
155
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
155
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
156
156
|
|
|
157
157
|
// Expect variants 2 to be chosen for bandwidth = 5e5
|
|
158
158
|
// and variant 5 - for bandwidth = 6e5
|
|
@@ -173,12 +173,12 @@ describe('SimpleAbrManager', () => {
|
|
|
173
173
|
abrManager.chooseVariant();
|
|
174
174
|
|
|
175
175
|
// 0 duration segment shouldn't cause us to get stuck on the lowest variant
|
|
176
|
-
abrManager.segmentDownloaded(0, bytesPerSecond);
|
|
177
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
176
|
+
abrManager.segmentDownloaded(0, bytesPerSecond, true);
|
|
177
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
178
178
|
|
|
179
179
|
abrManager.enable();
|
|
180
180
|
|
|
181
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
181
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
182
182
|
|
|
183
183
|
expect(abrManager.getBandwidthEstimate()).toBeTruthy();
|
|
184
184
|
});
|
|
@@ -193,14 +193,14 @@ describe('SimpleAbrManager', () => {
|
|
|
193
193
|
// bandwidth.
|
|
194
194
|
const bytesPerSecond = sufficientBWMultiplier * bandwidth / 8.0;
|
|
195
195
|
|
|
196
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
197
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
196
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
197
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
198
198
|
|
|
199
199
|
abrManager.enable();
|
|
200
200
|
|
|
201
201
|
// Make another call to segmentDownloaded() so switchCallback() is
|
|
202
202
|
// called.
|
|
203
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
203
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
204
204
|
|
|
205
205
|
// Expect variants 4 to be chosen
|
|
206
206
|
const expectedVariant = variants[3];
|
|
@@ -216,9 +216,9 @@ describe('SimpleAbrManager', () => {
|
|
|
216
216
|
abrManager.chooseVariant();
|
|
217
217
|
|
|
218
218
|
// Don't enable AbrManager.
|
|
219
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
220
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
221
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
219
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
220
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
221
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
222
222
|
expect(switchCallback).not.toHaveBeenCalled();
|
|
223
223
|
});
|
|
224
224
|
|
|
@@ -229,12 +229,12 @@ describe('SimpleAbrManager', () => {
|
|
|
229
229
|
abrManager.setVariants(variants);
|
|
230
230
|
abrManager.chooseVariant();
|
|
231
231
|
|
|
232
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
233
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
232
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
233
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
234
234
|
|
|
235
235
|
abrManager.enable();
|
|
236
236
|
|
|
237
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
237
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
238
238
|
expect(switchCallback).toHaveBeenCalled();
|
|
239
239
|
switchCallback.calls.reset();
|
|
240
240
|
|
|
@@ -242,23 +242,23 @@ describe('SimpleAbrManager', () => {
|
|
|
242
242
|
bandwidth = 2e6;
|
|
243
243
|
bytesPerSecond = sufficientBWMultiplier * bandwidth / 8.0;
|
|
244
244
|
|
|
245
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
246
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
247
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
248
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
249
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
250
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
251
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
245
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
246
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
247
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
248
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
249
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
250
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
251
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
252
252
|
|
|
253
253
|
// Stay inside switch interval.
|
|
254
254
|
Date.now = () => (config.switchInterval - 2) * 1e3;
|
|
255
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
255
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
256
256
|
|
|
257
257
|
expect(switchCallback).not.toHaveBeenCalled();
|
|
258
258
|
|
|
259
259
|
// Move outside switch interval.
|
|
260
260
|
Date.now = () => (config.switchInterval + 2) * 1e3;
|
|
261
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
261
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
262
262
|
|
|
263
263
|
expect(switchCallback).toHaveBeenCalled();
|
|
264
264
|
});
|
|
@@ -272,14 +272,14 @@ describe('SimpleAbrManager', () => {
|
|
|
272
272
|
abrManager.setVariants(variants);
|
|
273
273
|
abrManager.chooseVariant();
|
|
274
274
|
|
|
275
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
276
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
275
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
276
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
277
277
|
|
|
278
278
|
abrManager.enable();
|
|
279
279
|
|
|
280
280
|
// Make another call to segmentDownloaded(). switchCallback() will be
|
|
281
281
|
// called to upgrade.
|
|
282
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
282
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
283
283
|
|
|
284
284
|
// The second parameter is missing to indicate that the buffer should not be
|
|
285
285
|
// cleared.
|
|
@@ -300,14 +300,14 @@ describe('SimpleAbrManager', () => {
|
|
|
300
300
|
abrManager.setVariants(variants);
|
|
301
301
|
abrManager.chooseVariant();
|
|
302
302
|
|
|
303
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
304
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
303
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
304
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
305
305
|
|
|
306
306
|
abrManager.enable();
|
|
307
307
|
|
|
308
308
|
// Make another call to segmentDownloaded(). switchCallback() will be
|
|
309
309
|
// called to upgrade.
|
|
310
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
310
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
311
311
|
|
|
312
312
|
// The second parameter is missing to indicate that the buffer should not be
|
|
313
313
|
// cleared.
|
|
@@ -327,14 +327,14 @@ describe('SimpleAbrManager', () => {
|
|
|
327
327
|
abrManager.setVariants(variants);
|
|
328
328
|
abrManager.chooseVariant();
|
|
329
329
|
|
|
330
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
331
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
330
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
331
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
332
332
|
|
|
333
333
|
abrManager.enable();
|
|
334
334
|
|
|
335
335
|
// Make another call to segmentDownloaded(). switchCallback() will be
|
|
336
336
|
// called to downgrade.
|
|
337
|
-
abrManager.segmentDownloaded(1000, bytesPerSecond);
|
|
337
|
+
abrManager.segmentDownloaded(1000, bytesPerSecond, true);
|
|
338
338
|
|
|
339
339
|
// The second parameter is missing to indicate that the buffer should not be
|
|
340
340
|
// cleared.
|
|
@@ -16,10 +16,11 @@ describe('Ad manager', () => {
|
|
|
16
16
|
/** @type {google.ima.AdsRenderingSettings} */
|
|
17
17
|
let adsRenderingSettings;
|
|
18
18
|
|
|
19
|
-
beforeEach(() => {
|
|
19
|
+
beforeEach(async () => {
|
|
20
20
|
window['google'] = null;
|
|
21
21
|
mockVideo = new shaka.test.FakeVideo();
|
|
22
|
-
player = new shaka.Player(
|
|
22
|
+
player = new shaka.Player();
|
|
23
|
+
await player.attach(mockVideo, /* initializeMediaSource= */ false);
|
|
23
24
|
adManager = player.getAdManager();
|
|
24
25
|
expect(adManager instanceof shaka.ads.AdManager).toBe(true);
|
|
25
26
|
|
|
@@ -65,7 +65,7 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => {
|
|
|
65
65
|
support = await shaka.media.DrmEngine.probeSupport();
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
beforeEach(() => {
|
|
68
|
+
beforeEach(async () => {
|
|
69
69
|
mockReceiverApi = createMockReceiverApi();
|
|
70
70
|
|
|
71
71
|
const mockCanDisplayType = jasmine.createSpy('canDisplayType');
|
|
@@ -87,7 +87,8 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => {
|
|
|
87
87
|
|
|
88
88
|
document.body.appendChild(video);
|
|
89
89
|
|
|
90
|
-
player = new shaka.Player(
|
|
90
|
+
player = new shaka.Player();
|
|
91
|
+
await player.attach(video);
|
|
91
92
|
receiver = new CastReceiver(video, player);
|
|
92
93
|
|
|
93
94
|
toRestore = [];
|
|
@@ -139,6 +140,53 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => {
|
|
|
139
140
|
}
|
|
140
141
|
});
|
|
141
142
|
|
|
143
|
+
describe('state changed event', () => {
|
|
144
|
+
it('does not trigger a stack overflow', async () => {
|
|
145
|
+
const p = waitForLoadedData();
|
|
146
|
+
|
|
147
|
+
// We had a regression in which polling attributes eventually triggered a
|
|
148
|
+
// stack overflow because of a state change event that fired every time
|
|
149
|
+
// we checked the state. The error itself got swallowed and hidden
|
|
150
|
+
// inside CastReceiver, but would cause tests to disconnect in some
|
|
151
|
+
// environments (consistently in GitHub Actions VMs, inconsistently
|
|
152
|
+
// elsewhere).
|
|
153
|
+
//
|
|
154
|
+
// Testing for this is subtle: if we try to catch the error, it will be
|
|
155
|
+
// caught at a point when the stack has already or is about to overflow.
|
|
156
|
+
// Then if we call "fail", Jasmine will grow the stack further,
|
|
157
|
+
// triggering *another* overflow inside of fail(), causing our test to
|
|
158
|
+
// *pass*. So we need to fail fast. The best way I have found is to
|
|
159
|
+
// catch the very first recursion of pollAttributes_, long before we
|
|
160
|
+
// overflow, fail, then return early to avoid the actual recursion.
|
|
161
|
+
const original = /** @type {?} */(receiver).pollAttributes_;
|
|
162
|
+
let numRecursions = 0;
|
|
163
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
164
|
+
/** @type {?} */(receiver).pollAttributes_ = function() {
|
|
165
|
+
try {
|
|
166
|
+
if (numRecursions > 0) {
|
|
167
|
+
fail('Found recursion in pollAttributes_!');
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
numRecursions++;
|
|
172
|
+
return original.apply(receiver, arguments);
|
|
173
|
+
} finally {
|
|
174
|
+
numRecursions--;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// Start the process of loading by sending a fake init message.
|
|
179
|
+
fakeConnectedSenders(1);
|
|
180
|
+
fakeIncomingMessage({
|
|
181
|
+
type: 'init',
|
|
182
|
+
initState: fakeInitState,
|
|
183
|
+
appData: {},
|
|
184
|
+
}, mockShakaMessageBus);
|
|
185
|
+
|
|
186
|
+
await p;
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
142
190
|
describe('without drm', () => {
|
|
143
191
|
it('sends reasonably-sized updates', async () => {
|
|
144
192
|
// Use an unencrypted asset.
|
|
@@ -273,8 +321,6 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => {
|
|
|
273
321
|
// Add wrappers to various methods along player.load to make sure that,
|
|
274
322
|
// at each stage, the cast receiver can form an update message without
|
|
275
323
|
// causing an error.
|
|
276
|
-
waitForUpdateMessageWrapper(
|
|
277
|
-
shaka.media.ManifestParser, 'ManifestParser', 'getFactory');
|
|
278
324
|
waitForUpdateMessageWrapper(
|
|
279
325
|
// eslint-disable-next-line no-restricted-syntax
|
|
280
326
|
shaka.test.TestScheme.ManifestParser.prototype, 'ManifestParser',
|
|
@@ -21,11 +21,13 @@ describe('CastUtils', () => {
|
|
|
21
21
|
'getMediaElement', // Handled specially
|
|
22
22
|
'setMaxHardwareResolution',
|
|
23
23
|
'destroy', // Should use CastProxy.destroy instead
|
|
24
|
+
'getAllThumbnails', // Too large to proxy.
|
|
24
25
|
'drmInfo', // Too large to proxy
|
|
25
26
|
'getManifest', // Too large to proxy
|
|
26
27
|
'getManifestParserFactory', // Would not serialize.
|
|
27
28
|
'setVideoContainer',
|
|
28
29
|
'getActiveSessionsMetadata',
|
|
30
|
+
'releaseAllMutexes', // Very specific to the inner workings of the player.
|
|
29
31
|
|
|
30
32
|
// Test helper methods (not @export'd)
|
|
31
33
|
'createDrmEngine',
|
|
@@ -519,6 +519,13 @@ describe('CeaDecoder', () => {
|
|
|
519
519
|
|
|
520
520
|
expect(decoder.reset).toHaveBeenCalledTimes(1);
|
|
521
521
|
});
|
|
522
|
+
|
|
523
|
+
it('does not attempt to extract SEI packet that is too short', () => {
|
|
524
|
+
const badData = new Uint8Array([0xb5]);
|
|
525
|
+
decoder.extract(badData, 0);
|
|
526
|
+
const captions = decoder.decode();
|
|
527
|
+
expect(captions.length).toBe(0);
|
|
528
|
+
});
|
|
522
529
|
});
|
|
523
530
|
|
|
524
531
|
describe('decodes CEA-708', () => {
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
describe('Codec Switching', () => {
|
|
8
|
+
/** @type {!HTMLVideoElement} */
|
|
9
|
+
let video;
|
|
10
|
+
/** @type {shaka.Player} */
|
|
11
|
+
let player;
|
|
12
|
+
/** @type {!shaka.util.EventManager} */
|
|
13
|
+
let eventManager;
|
|
14
|
+
|
|
15
|
+
let compiledShaka;
|
|
16
|
+
|
|
17
|
+
/** @type {!shaka.test.Waiter} */
|
|
18
|
+
let waiter;
|
|
19
|
+
|
|
20
|
+
beforeAll(async () => {
|
|
21
|
+
video = shaka.test.UiUtils.createVideoElement();
|
|
22
|
+
document.body.appendChild(video);
|
|
23
|
+
compiledShaka =
|
|
24
|
+
await shaka.test.Loader.loadShaka(getClientArg('uncompiled'));
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
beforeEach(async () => {
|
|
28
|
+
await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled');
|
|
29
|
+
player = new compiledShaka.Player();
|
|
30
|
+
await player.attach(video);
|
|
31
|
+
|
|
32
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
33
|
+
player.configure('streaming.stallEnabled', false);
|
|
34
|
+
|
|
35
|
+
eventManager = new shaka.util.EventManager();
|
|
36
|
+
waiter = new shaka.test.Waiter(eventManager);
|
|
37
|
+
waiter.setPlayer(player);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
afterEach(async () => {
|
|
41
|
+
eventManager.release();
|
|
42
|
+
await player.destroy();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
afterAll(() => {
|
|
46
|
+
document.body.removeChild(video);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('for audio and only-audio content', () => {
|
|
50
|
+
it('can switch codecs RELOAD', async () => {
|
|
51
|
+
if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
52
|
+
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
53
|
+
}
|
|
54
|
+
const preferredAudioLanguage = 'en';
|
|
55
|
+
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
56
|
+
player.configure('manifest.disableVideo', true);
|
|
57
|
+
player.configure('streaming.mediaSource.codecSwitchingStrategy',
|
|
58
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
59
|
+
|
|
60
|
+
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
61
|
+
await video.play();
|
|
62
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
63
|
+
|
|
64
|
+
expect(player.isLive()).toBe(false);
|
|
65
|
+
|
|
66
|
+
let variants = player.getVariantTracks();
|
|
67
|
+
|
|
68
|
+
expect(variants.length).toBe(2);
|
|
69
|
+
expect(variants.find((v) => !!v.active).language).toBe('en');
|
|
70
|
+
|
|
71
|
+
player.selectAudioLanguage('es');
|
|
72
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
73
|
+
|
|
74
|
+
variants = player.getVariantTracks();
|
|
75
|
+
|
|
76
|
+
expect(variants.find((v) => !!v.active).language).toBe('es');
|
|
77
|
+
|
|
78
|
+
await player.unload();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('can switch codecs SMOOTH', async () => {
|
|
82
|
+
if (!shaka.util.Platform.supportsSmoothCodecSwitching()) {
|
|
83
|
+
pending('Mediasource.ChangeType is not considered ' +
|
|
84
|
+
'reliable on this device');
|
|
85
|
+
}
|
|
86
|
+
if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
87
|
+
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
88
|
+
}
|
|
89
|
+
const preferredAudioLanguage = 'en';
|
|
90
|
+
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
91
|
+
player.configure('manifest.disableVideo', true);
|
|
92
|
+
player.configure('streaming.mediaSource.codecSwitchingStrategy',
|
|
93
|
+
shaka.config.CodecSwitchingStrategy.SMOOTH);
|
|
94
|
+
|
|
95
|
+
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
96
|
+
await video.play();
|
|
97
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
98
|
+
|
|
99
|
+
expect(player.isLive()).toBe(false);
|
|
100
|
+
|
|
101
|
+
let variants = player.getVariantTracks();
|
|
102
|
+
|
|
103
|
+
expect(variants.length).toBe(2);
|
|
104
|
+
expect(variants.find((v) => !!v.active).language).toBe('en');
|
|
105
|
+
|
|
106
|
+
player.selectAudioLanguage('es');
|
|
107
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
108
|
+
|
|
109
|
+
variants = player.getVariantTracks();
|
|
110
|
+
|
|
111
|
+
expect(variants.find((v) => !!v.active).language).toBe('es');
|
|
112
|
+
|
|
113
|
+
await player.unload();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('for audio', () => {
|
|
118
|
+
it('can switch codecs RELOAD', async () => {
|
|
119
|
+
if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
120
|
+
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
121
|
+
}
|
|
122
|
+
const preferredAudioLanguage = 'en';
|
|
123
|
+
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
124
|
+
player.configure('streaming.mediaSource.codecSwitchingStrategy',
|
|
125
|
+
shaka.config.CodecSwitchingStrategy.RELOAD);
|
|
126
|
+
|
|
127
|
+
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
128
|
+
await video.play();
|
|
129
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
130
|
+
|
|
131
|
+
expect(player.isLive()).toBe(false);
|
|
132
|
+
|
|
133
|
+
let variants = player.getVariantTracks();
|
|
134
|
+
|
|
135
|
+
expect(variants.length).toBe(2);
|
|
136
|
+
expect(variants.find((v) => !!v.active).language).toBe('en');
|
|
137
|
+
|
|
138
|
+
player.selectAudioLanguage('es');
|
|
139
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
140
|
+
|
|
141
|
+
variants = player.getVariantTracks();
|
|
142
|
+
|
|
143
|
+
expect(variants.find((v) => !!v.active).language).toBe('es');
|
|
144
|
+
|
|
145
|
+
await player.unload();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('can switch codecs SMOOTH', async () => {
|
|
149
|
+
if (!shaka.util.Platform.supportsSmoothCodecSwitching()) {
|
|
150
|
+
pending('Mediasource.ChangeType is not considered ' +
|
|
151
|
+
'reliable on this device');
|
|
152
|
+
}
|
|
153
|
+
if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
|
|
154
|
+
pending('Codec OPUS in WEBM is not supported by the platform.');
|
|
155
|
+
}
|
|
156
|
+
const preferredAudioLanguage = 'en';
|
|
157
|
+
player.configure({preferredAudioLanguage: preferredAudioLanguage});
|
|
158
|
+
player.configure('streaming.mediaSource.codecSwitchingStrategy',
|
|
159
|
+
shaka.config.CodecSwitchingStrategy.SMOOTH);
|
|
160
|
+
|
|
161
|
+
await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
|
|
162
|
+
await video.play();
|
|
163
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
164
|
+
|
|
165
|
+
expect(player.isLive()).toBe(false);
|
|
166
|
+
|
|
167
|
+
let variants = player.getVariantTracks();
|
|
168
|
+
|
|
169
|
+
expect(variants.length).toBe(2);
|
|
170
|
+
expect(variants.find((v) => !!v.active).language).toBe('en');
|
|
171
|
+
|
|
172
|
+
player.selectAudioLanguage('es');
|
|
173
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
|
|
174
|
+
|
|
175
|
+
variants = player.getVariantTracks();
|
|
176
|
+
|
|
177
|
+
expect(variants.find((v) => !!v.active).language).toBe('es');
|
|
178
|
+
|
|
179
|
+
await player.unload();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
@@ -45,6 +45,8 @@ describe('DashParser ContentProtection', () => {
|
|
|
45
45
|
enableLowLatencyMode: () => {},
|
|
46
46
|
updateDuration: () => {},
|
|
47
47
|
newDrmInfo: (stream) => {},
|
|
48
|
+
onManifestUpdated: () => {},
|
|
49
|
+
getBandwidthEstimate: () => 1e6,
|
|
48
50
|
};
|
|
49
51
|
|
|
50
52
|
const actual = await dashParser.start(
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
describe('DashParser', () => {
|
|
8
|
+
const Util = shaka.test.Util;
|
|
9
|
+
|
|
10
|
+
/** @type {!jasmine.Spy} */
|
|
11
|
+
let onErrorSpy;
|
|
12
|
+
|
|
13
|
+
/** @type {!HTMLVideoElement} */
|
|
14
|
+
let video;
|
|
15
|
+
/** @type {shaka.Player} */
|
|
16
|
+
let player;
|
|
17
|
+
/** @type {!shaka.util.EventManager} */
|
|
18
|
+
let eventManager;
|
|
19
|
+
|
|
20
|
+
let compiledShaka;
|
|
21
|
+
|
|
22
|
+
/** @type {!shaka.test.Waiter} */
|
|
23
|
+
let waiter;
|
|
24
|
+
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
video = shaka.test.UiUtils.createVideoElement();
|
|
27
|
+
document.body.appendChild(video);
|
|
28
|
+
compiledShaka =
|
|
29
|
+
await shaka.test.Loader.loadShaka(getClientArg('uncompiled'));
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
beforeEach(async () => {
|
|
33
|
+
await shaka.test.TestScheme.createManifests(compiledShaka, '_compiled');
|
|
34
|
+
player = new compiledShaka.Player();
|
|
35
|
+
await player.attach(video);
|
|
36
|
+
|
|
37
|
+
// Disable stall detection, which can interfere with playback tests.
|
|
38
|
+
player.configure('streaming.stallEnabled', false);
|
|
39
|
+
|
|
40
|
+
// Grab event manager from the uncompiled library:
|
|
41
|
+
eventManager = new shaka.util.EventManager();
|
|
42
|
+
waiter = new shaka.test.Waiter(eventManager);
|
|
43
|
+
waiter.setPlayer(player);
|
|
44
|
+
|
|
45
|
+
onErrorSpy = jasmine.createSpy('onError');
|
|
46
|
+
onErrorSpy.and.callFake((event) => fail(event.detail));
|
|
47
|
+
eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
afterEach(async () => {
|
|
51
|
+
eventManager.release();
|
|
52
|
+
await player.destroy();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
afterAll(() => {
|
|
56
|
+
document.body.removeChild(video);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('supports AES-128 streaming', async () => {
|
|
60
|
+
await player.load('/base/test/test/assets/dash-aes-128/dash.mpd');
|
|
61
|
+
await video.play();
|
|
62
|
+
expect(player.isLive()).toBe(false);
|
|
63
|
+
|
|
64
|
+
// Wait for the video to start playback. If it takes longer than 10
|
|
65
|
+
// seconds, fail the test.
|
|
66
|
+
await waiter.waitForMovementOrFailOnTimeout(video, 10);
|
|
67
|
+
|
|
68
|
+
// Play for 10 seconds, but stop early if the video ends. If it takes
|
|
69
|
+
// longer than 30 seconds, fail the test.
|
|
70
|
+
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 30);
|
|
71
|
+
|
|
72
|
+
await player.unload();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -36,6 +36,8 @@ describe('DashParser Live', () => {
|
|
|
36
36
|
enableLowLatencyMode: () => {},
|
|
37
37
|
updateDuration: () => {},
|
|
38
38
|
newDrmInfo: (stream) => {},
|
|
39
|
+
onManifestUpdated: () => {},
|
|
40
|
+
getBandwidthEstimate: () => 1e6,
|
|
39
41
|
};
|
|
40
42
|
});
|
|
41
43
|
|
|
@@ -659,25 +661,6 @@ describe('DashParser Live', () => {
|
|
|
659
661
|
expect(delay).toBe(updateTime);
|
|
660
662
|
});
|
|
661
663
|
|
|
662
|
-
it('still updates when @minimumUpdatePeriod is zero', async () => {
|
|
663
|
-
const lines = [
|
|
664
|
-
'<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
|
|
665
|
-
];
|
|
666
|
-
// updateTime parameter sets @minimumUpdatePeriod in the manifest.
|
|
667
|
-
const manifestText = makeSimpleLiveManifestText(lines, /* updateTime= */ 0);
|
|
668
|
-
|
|
669
|
-
/** @type {!jasmine.Spy} */
|
|
670
|
-
const tickAfter = updateTickSpy();
|
|
671
|
-
Date.now = () => 0;
|
|
672
|
-
|
|
673
|
-
fakeNetEngine.setResponseText('dummy://foo', manifestText);
|
|
674
|
-
await parser.start('dummy://foo', playerInterface);
|
|
675
|
-
|
|
676
|
-
expect(tickAfter).toHaveBeenCalledTimes(1);
|
|
677
|
-
const delay = tickAfter.calls.mostRecent().args[0];
|
|
678
|
-
expect(delay).toBe(0);
|
|
679
|
-
});
|
|
680
|
-
|
|
681
664
|
it('does not update when @minimumUpdatePeriod is missing', async () => {
|
|
682
665
|
const lines = [
|
|
683
666
|
'<SegmentTemplate startNumber="1" media="s$Number$.mp4" duration="2" />',
|