shaka-player 4.4.3 → 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.
Files changed (198) hide show
  1. package/.github/workflows/release-please.yaml +2 -27
  2. package/CHANGELOG.md +64 -45
  3. package/README.md +16 -10
  4. package/demo/asset_card.js +18 -21
  5. package/demo/cast_receiver/index.html +0 -1
  6. package/demo/close_button.js +0 -3
  7. package/demo/common/asset.js +22 -5
  8. package/demo/common/assets.js +132 -49
  9. package/demo/config.js +192 -253
  10. package/demo/custom.js +39 -98
  11. package/demo/front.js +7 -10
  12. package/demo/index.html +19 -22
  13. package/demo/input.js +6 -11
  14. package/demo/input_container.js +8 -9
  15. package/demo/main.js +51 -123
  16. package/demo/search.js +22 -34
  17. package/demo/service_worker.js +0 -3
  18. package/demo/tooltip.js +3 -5
  19. package/demo/visualizer.js +3 -5
  20. package/demo/visualizer_button.js +1 -20
  21. package/dist/demo.compiled.debug.js +152 -178
  22. package/dist/demo.compiled.debug.map +4 -4
  23. package/dist/demo.compiled.js +152 -178
  24. package/dist/demo.compiled.map +4 -4
  25. package/dist/deps.js +27 -24
  26. package/dist/locales.js +31 -31
  27. package/dist/receiver.compiled.debug.js +22 -43
  28. package/dist/receiver.compiled.debug.map +4 -4
  29. package/dist/receiver.compiled.js +22 -43
  30. package/dist/receiver.compiled.map +4 -4
  31. package/dist/shaka-player.compiled.d.ts +507 -365
  32. package/dist/shaka-player.compiled.debug.d.ts +507 -365
  33. package/dist/shaka-player.compiled.debug.externs.js +205 -51
  34. package/dist/shaka-player.compiled.debug.js +541 -450
  35. package/dist/shaka-player.compiled.debug.map +4 -4
  36. package/dist/shaka-player.compiled.externs.js +205 -51
  37. package/dist/shaka-player.compiled.js +1120 -1066
  38. package/dist/shaka-player.compiled.map +4 -4
  39. package/dist/shaka-player.ui.d.ts +562 -410
  40. package/dist/shaka-player.ui.debug.d.ts +562 -410
  41. package/dist/shaka-player.ui.debug.externs.js +226 -51
  42. package/dist/shaka-player.ui.debug.js +606 -506
  43. package/dist/shaka-player.ui.debug.map +4 -4
  44. package/dist/shaka-player.ui.externs.js +226 -51
  45. package/dist/shaka-player.ui.js +1266 -1207
  46. package/dist/shaka-player.ui.map +4 -4
  47. package/docs/design/lcevc-integration.md +14 -14
  48. package/docs/tutorials/faq.md +27 -55
  49. package/docs/tutorials/index.json +2 -1
  50. package/docs/tutorials/lcevc.md +118 -0
  51. package/docs/tutorials/ui-customization.md +4 -0
  52. package/externs/css_style_declaration.js +19 -0
  53. package/externs/lcevc.js +37 -13
  54. package/externs/media_remote.js +68 -0
  55. package/externs/mediatailor.js +193 -0
  56. package/externs/pictureinpicture.js +11 -0
  57. package/externs/shaka/ads.js +27 -0
  58. package/externs/shaka/manifest.js +10 -5
  59. package/externs/shaka/manifest_parser.js +7 -1
  60. package/externs/shaka/offline.js +4 -0
  61. package/externs/shaka/player.js +12 -1
  62. package/karma.conf.js +7 -3
  63. package/lib/abr/simple_abr_manager.js +43 -3
  64. package/lib/ads/ad_manager.js +104 -50
  65. package/lib/ads/media_tailor_ad.js +297 -0
  66. package/lib/ads/media_tailor_ad_manager.js +828 -0
  67. package/lib/cea/ts_cea_parser.js +15 -2
  68. package/lib/config/codec_switching_strategy.js +24 -0
  69. package/lib/dash/content_protection.js +120 -2
  70. package/lib/dash/dash_parser.js +75 -12
  71. package/lib/dash/mpd_utils.js +10 -6
  72. package/lib/dash/segment_base.js +13 -5
  73. package/lib/dash/segment_list.js +13 -5
  74. package/lib/dash/segment_template.js +43 -85
  75. package/lib/dependencies/all.js +8 -7
  76. package/lib/hls/hls_parser.js +44 -16
  77. package/lib/lcevc/lcevc_dec.js +220 -0
  78. package/lib/media/adaptation_set.js +22 -11
  79. package/lib/media/adaptation_set_criteria.js +25 -7
  80. package/lib/media/media_source_engine.js +215 -27
  81. package/lib/media/segment_index.js +1 -1
  82. package/lib/media/segment_reference.js +7 -7
  83. package/lib/media/streaming_engine.js +33 -18
  84. package/lib/mss/mss_parser.js +1 -0
  85. package/lib/net/networking_engine.js +1 -0
  86. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  87. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  88. package/lib/offline/manifest_converter.js +1 -0
  89. package/lib/offline/storage.js +3 -0
  90. package/lib/player.js +142 -72
  91. package/lib/routing/payload.js +5 -1
  92. package/lib/text/cue.js +15 -0
  93. package/lib/text/ttml_text_parser.js +17 -0
  94. package/lib/text/ui_text_displayer.js +4 -0
  95. package/lib/text/vtt_text_parser.js +33 -20
  96. package/lib/transmuxer/h265.js +862 -0
  97. package/lib/transmuxer/mpeg_ts_transmuxer.js +3 -2
  98. package/lib/transmuxer/ts_transmuxer.js +160 -15
  99. package/lib/util/error.js +28 -9
  100. package/lib/util/exp_golomb.js +30 -2
  101. package/lib/util/fake_event.js +3 -0
  102. package/lib/util/mp4_generator.js +4 -4
  103. package/lib/util/periods.js +2 -0
  104. package/lib/util/platform.js +40 -0
  105. package/lib/util/player_configuration.js +8 -0
  106. package/lib/util/state_history.js +6 -2
  107. package/lib/util/stream_utils.js +133 -217
  108. package/lib/util/ts_parser.js +226 -40
  109. package/maintained-branches.md +3 -2
  110. package/package.json +4 -6
  111. package/roadmap.md +15 -5
  112. package/shaka-player.uncompiled.js +2 -1
  113. package/support.html +0 -1
  114. package/test/cast/cast_receiver_integration.js +47 -0
  115. package/test/codec_switching/codec_switching_integration.js +181 -0
  116. package/test/dash/dash_parser_content_protection_unit.js +2 -0
  117. package/test/dash/dash_parser_integration.js +73 -0
  118. package/test/dash/dash_parser_live_unit.js +2 -0
  119. package/test/dash/dash_parser_manifest_unit.js +42 -0
  120. package/test/dash/dash_parser_segment_base_unit.js +2 -0
  121. package/test/dash/dash_parser_segment_list_unit.js +2 -0
  122. package/test/dash/dash_parser_segment_template_unit.js +2 -0
  123. package/test/demo/demo_unit.js +0 -16
  124. package/test/hls/hls_live_unit.js +2 -0
  125. package/test/hls/hls_parser_unit.js +8 -6
  126. package/test/media/adaptation_set_criteria_unit.js +118 -0
  127. package/test/media/adaptation_set_unit.js +1 -0
  128. package/test/media/media_source_engine_unit.js +165 -1
  129. package/test/media/segment_index_unit.js +4 -4
  130. package/test/media/segment_prefetch_unit.js +1 -1
  131. package/test/media/streaming_engine_unit.js +17 -17
  132. package/test/mss/mss_parser_unit.js +2 -0
  133. package/test/offline/manifest_convert_unit.js +5 -0
  134. package/test/offline/storage_integration.js +1 -4
  135. package/test/player_unit.js +102 -131
  136. package/test/routing/walker_unit.js +1 -0
  137. package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
  138. package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
  139. package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
  140. package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
  141. package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
  142. package/test/test/assets/dash-aes-128/dash.mpd +18 -0
  143. package/test/test/assets/dash-aes-128/license +1 -0
  144. package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
  145. package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
  146. package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
  147. package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
  148. package/test/test/assets/hls-ts-h265/0.ts +0 -0
  149. package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
  150. package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
  151. package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
  152. package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
  153. package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
  154. package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
  155. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
  156. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
  157. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
  158. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
  159. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
  160. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
  161. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
  162. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
  163. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
  164. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
  165. package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
  166. package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
  167. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
  168. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
  169. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
  170. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
  171. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
  172. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
  173. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
  174. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
  175. package/test/test/util/dash_parser_util.js +4 -0
  176. package/test/test/util/fake_ad_manager.js +20 -0
  177. package/test/test/util/fake_media_source_engine.js +8 -2
  178. package/test/test/util/manifest_generator.js +7 -3
  179. package/test/test/util/mss_parser_util.js +4 -0
  180. package/test/test/util/offline_utils.js +1 -0
  181. package/test/test/util/streaming_engine_util.js +7 -4
  182. package/test/text/ttml_text_parser_unit.js +52 -0
  183. package/test/text/vtt_text_parser_unit.js +103 -31
  184. package/test/transmuxer/transmuxer_integration.js +117 -0
  185. package/test/ui/ui_unit.js +3 -10
  186. package/test/util/stream_utils_unit.js +208 -74
  187. package/ui/controls.js +125 -0
  188. package/ui/externs/ui.js +8 -1
  189. package/ui/pip_button.js +22 -120
  190. package/ui/remote_button.js +201 -0
  191. package/ui/ui.js +5 -2
  192. package/demo/common/message_ids.js +0 -309
  193. package/demo/locales/en.json +0 -288
  194. package/demo/locales/source.json +0 -1146
  195. package/externs/mux.js +0 -69
  196. package/lib/lcevc/lcevc_dil.js +0 -152
  197. package/lib/transmuxer/muxjs_transmuxer.js +0 -242
  198. package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
@@ -0,0 +1,181 @@
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(video);
30
+
31
+ // Disable stall detection, which can interfere with playback tests.
32
+ player.configure('streaming.stallEnabled', false);
33
+
34
+ eventManager = new shaka.util.EventManager();
35
+ waiter = new shaka.test.Waiter(eventManager);
36
+ waiter.setPlayer(player);
37
+ });
38
+
39
+ afterEach(async () => {
40
+ eventManager.release();
41
+ await player.destroy();
42
+ });
43
+
44
+ afterAll(() => {
45
+ document.body.removeChild(video);
46
+ });
47
+
48
+ describe('for audio and only-audio content', () => {
49
+ it('can switch codecs RELOAD', async () => {
50
+ if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
51
+ pending('Codec OPUS in WEBM is not supported by the platform.');
52
+ }
53
+ const preferredAudioLanguage = 'en';
54
+ player.configure({preferredAudioLanguage: preferredAudioLanguage});
55
+ player.configure('manifest.disableVideo', true);
56
+ player.configure('streaming.mediaSource.codecSwitchingStrategy',
57
+ shaka.config.CodecSwitchingStrategy.RELOAD);
58
+
59
+ await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
60
+ await video.play();
61
+ await waiter.waitForMovementOrFailOnTimeout(video, 10);
62
+
63
+ expect(player.isLive()).toBe(false);
64
+
65
+ let variants = player.getVariantTracks();
66
+
67
+ expect(variants.length).toBe(2);
68
+ expect(variants.find((v) => !!v.active).language).toBe('en');
69
+
70
+ player.selectAudioLanguage('es');
71
+ await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
72
+
73
+ variants = player.getVariantTracks();
74
+
75
+ expect(variants.find((v) => !!v.active).language).toBe('es');
76
+
77
+ await player.unload();
78
+ });
79
+
80
+ it('can switch codecs SMOOTH', async () => {
81
+ if (!shaka.util.Platform.supportsSmoothCodecSwitching()) {
82
+ pending('Mediasource.ChangeType is not considered ' +
83
+ 'reliable on this device');
84
+ }
85
+ if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
86
+ pending('Codec OPUS in WEBM is not supported by the platform.');
87
+ }
88
+ const preferredAudioLanguage = 'en';
89
+ player.configure({preferredAudioLanguage: preferredAudioLanguage});
90
+ player.configure('manifest.disableVideo', true);
91
+ player.configure('streaming.mediaSource.codecSwitchingStrategy',
92
+ shaka.config.CodecSwitchingStrategy.SMOOTH);
93
+
94
+ await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
95
+ await video.play();
96
+ await waiter.waitForMovementOrFailOnTimeout(video, 10);
97
+
98
+ expect(player.isLive()).toBe(false);
99
+
100
+ let variants = player.getVariantTracks();
101
+
102
+ expect(variants.length).toBe(2);
103
+ expect(variants.find((v) => !!v.active).language).toBe('en');
104
+
105
+ player.selectAudioLanguage('es');
106
+ await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
107
+
108
+ variants = player.getVariantTracks();
109
+
110
+ expect(variants.find((v) => !!v.active).language).toBe('es');
111
+
112
+ await player.unload();
113
+ });
114
+ });
115
+
116
+ describe('for audio', () => {
117
+ it('can switch codecs RELOAD', async () => {
118
+ if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
119
+ pending('Codec OPUS in WEBM is not supported by the platform.');
120
+ }
121
+ const preferredAudioLanguage = 'en';
122
+ player.configure({preferredAudioLanguage: preferredAudioLanguage});
123
+ player.configure('streaming.mediaSource.codecSwitchingStrategy',
124
+ shaka.config.CodecSwitchingStrategy.RELOAD);
125
+
126
+ await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
127
+ await video.play();
128
+ await waiter.waitForMovementOrFailOnTimeout(video, 10);
129
+
130
+ expect(player.isLive()).toBe(false);
131
+
132
+ let variants = player.getVariantTracks();
133
+
134
+ expect(variants.length).toBe(2);
135
+ expect(variants.find((v) => !!v.active).language).toBe('en');
136
+
137
+ player.selectAudioLanguage('es');
138
+ await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
139
+
140
+ variants = player.getVariantTracks();
141
+
142
+ expect(variants.find((v) => !!v.active).language).toBe('es');
143
+
144
+ await player.unload();
145
+ });
146
+
147
+ it('can switch codecs SMOOTH', async () => {
148
+ if (!shaka.util.Platform.supportsSmoothCodecSwitching()) {
149
+ pending('Mediasource.ChangeType is not considered ' +
150
+ 'reliable on this device');
151
+ }
152
+ if (!MediaSource.isTypeSupported('audio/webm; codecs="opus"')) {
153
+ pending('Codec OPUS in WEBM is not supported by the platform.');
154
+ }
155
+ const preferredAudioLanguage = 'en';
156
+ player.configure({preferredAudioLanguage: preferredAudioLanguage});
157
+ player.configure('streaming.mediaSource.codecSwitchingStrategy',
158
+ shaka.config.CodecSwitchingStrategy.SMOOTH);
159
+
160
+ await player.load('/base/test/test/assets/dash-multi-codec/dash.mpd', 9);
161
+ await video.play();
162
+ await waiter.waitForMovementOrFailOnTimeout(video, 10);
163
+
164
+ expect(player.isLive()).toBe(false);
165
+
166
+ let variants = player.getVariantTracks();
167
+
168
+ expect(variants.length).toBe(2);
169
+ expect(variants.find((v) => !!v.active).language).toBe('en');
170
+
171
+ player.selectAudioLanguage('es');
172
+ await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 45);
173
+
174
+ variants = player.getVariantTracks();
175
+
176
+ expect(variants.find((v) => !!v.active).language).toBe('es');
177
+
178
+ await player.unload();
179
+ });
180
+ });
181
+ });
@@ -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,73 @@
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(video);
35
+
36
+ // Disable stall detection, which can interfere with playback tests.
37
+ player.configure('streaming.stallEnabled', false);
38
+
39
+ // Grab event manager from the uncompiled library:
40
+ eventManager = new shaka.util.EventManager();
41
+ waiter = new shaka.test.Waiter(eventManager);
42
+ waiter.setPlayer(player);
43
+
44
+ onErrorSpy = jasmine.createSpy('onError');
45
+ onErrorSpy.and.callFake((event) => fail(event.detail));
46
+ eventManager.listen(player, 'error', Util.spyFunc(onErrorSpy));
47
+ });
48
+
49
+ afterEach(async () => {
50
+ eventManager.release();
51
+ await player.destroy();
52
+ });
53
+
54
+ afterAll(() => {
55
+ document.body.removeChild(video);
56
+ });
57
+
58
+ it('supports AES-128 streaming', async () => {
59
+ await player.load('/base/test/test/assets/dash-aes-128/dash.mpd');
60
+ await video.play();
61
+ expect(player.isLive()).toBe(false);
62
+
63
+ // Wait for the video to start playback. If it takes longer than 10
64
+ // seconds, fail the test.
65
+ await waiter.waitForMovementOrFailOnTimeout(video, 10);
66
+
67
+ // Play for 10 seconds, but stop early if the video ends. If it takes
68
+ // longer than 30 seconds, fail the test.
69
+ await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 30);
70
+
71
+ await player.unload();
72
+ });
73
+ });
@@ -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
 
@@ -54,6 +54,8 @@ describe('DashParser Manifest', () => {
54
54
  enableLowLatencyMode: () => {},
55
55
  updateDuration: () => {},
56
56
  newDrmInfo: (stream) => {},
57
+ onManifestUpdated: () => {},
58
+ getBandwidthEstimate: () => 1e6,
57
59
  };
58
60
  });
59
61
 
@@ -1180,6 +1182,46 @@ describe('DashParser Manifest', () => {
1180
1182
  expect(trickModeVideo).toBe(null);
1181
1183
  });
1182
1184
 
1185
+ it('populates groupId if configuration enabled', async () => {
1186
+ const manifestText = [
1187
+ '<MPD minBufferTime="PT75S">',
1188
+ ' <Period id="1" duration="PT30S">',
1189
+ ' <AdaptationSet id="1" contentType="text">',
1190
+ ' <Representation id="text-en" mimeType="text/webvtt">',
1191
+ ' <BaseURL>t-en.vtt</BaseURL>',
1192
+ ' </Representation>',
1193
+ ' </AdaptationSet>',
1194
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
1195
+ ' <Representation id="video-sd" width="640" height="480">',
1196
+ ' <BaseURL>v-sd.mp4</BaseURL>',
1197
+ ' <SegmentBase indexRange="100-200" />',
1198
+ ' </Representation>',
1199
+ ' </AdaptationSet>',
1200
+ ' <AdaptationSet id="3" mimeType="audio/mp4">',
1201
+ ' <Representation id="audio-en">',
1202
+ ' <BaseURL>a-en.mp4</BaseURL>',
1203
+ ' <SegmentBase indexRange="100-200" />',
1204
+ ' </Representation>',
1205
+ ' </AdaptationSet>',
1206
+ ' </Period>',
1207
+ '</MPD>',
1208
+ ].join('\n');
1209
+
1210
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
1211
+
1212
+ const config = shaka.util.PlayerConfiguration.createDefault().manifest;
1213
+ config.dash.enableAudioGroups = true;
1214
+ parser.configure(config);
1215
+
1216
+ /** @type {shaka.extern.Manifest} */
1217
+ const manifest = await parser.start('dummy://foo', playerInterface);
1218
+
1219
+
1220
+ expect(manifest.variants.length).toBe(1);
1221
+ const variant = manifest.variants[0];
1222
+ expect(variant.audio.groupId).toBe('3');
1223
+ });
1224
+
1183
1225
  it('sets contentType to text for embedded text mime types', async () => {
1184
1226
  // One MIME type for embedded TTML, one for embedded WebVTT.
1185
1227
  // One MIME type specified on AdaptationSet, on one Representation.
@@ -40,6 +40,8 @@ describe('DashParser SegmentBase', () => {
40
40
  enableLowLatencyMode: () => {},
41
41
  updateDuration: () => {},
42
42
  newDrmInfo: (stream) => {},
43
+ onManifestUpdated: () => {},
44
+ getBandwidthEstimate: () => 1e6,
43
45
  };
44
46
  });
45
47
 
@@ -350,6 +350,8 @@ describe('DashParser SegmentList', () => {
350
350
  enableLowLatencyMode: () => {},
351
351
  updateDuration: () => {},
352
352
  newDrmInfo: (stream) => {},
353
+ onManifestUpdated: () => {},
354
+ getBandwidthEstimate: () => 1e6,
353
355
  };
354
356
  try {
355
357
  const manifest = await dashParser.start('dummy://foo', playerInterface);
@@ -49,6 +49,8 @@ describe('DashParser SegmentTemplate', () => {
49
49
  enableLowLatencyMode: () => {},
50
50
  updateDuration: () => {},
51
51
  newDrmInfo: (stream) => {},
52
+ onManifestUpdated: () => {},
53
+ getBandwidthEstimate: () => 1e6,
52
54
  };
53
55
  });
54
56
 
@@ -33,22 +33,6 @@ describe('Demo', () => {
33
33
  await shakaDemoMain.cleanup();
34
34
  });
35
35
 
36
- it('has all messages defined', async () => {
37
- const englishBuffer =
38
- await shaka.test.Util.fetch('/base/demo/locales/en.json');
39
- const englishMessages = JSON.parse(shaka.util.StringUtils.fromUTF8(
40
- englishBuffer));
41
- const sourceBuffer =
42
- await shaka.test.Util.fetch('/base/demo/locales/source.json');
43
- const sourceMessages = JSON.parse(shaka.util.StringUtils.fromUTF8(
44
- sourceBuffer));
45
-
46
- for (const id of Object.values(shakaDemo.MessageIds)) {
47
- expect(englishMessages[id]).withContext(`id=${id}, English`).toBeTruthy();
48
- expect(sourceMessages[id]).withContext(`id=${id}, source`).toBeTruthy();
49
- }
50
- });
51
-
52
36
  describe('config', () => {
53
37
  it('does not have entries for invalid config options', () => {
54
38
  // We determine whether a config option has been made or not by looking at
@@ -77,6 +77,8 @@ describe('HlsParser live', () => {
77
77
  enableLowLatencyMode: () => {},
78
78
  updateDuration: () => {},
79
79
  newDrmInfo: (stream) => {},
80
+ onManifestUpdated: () => {},
81
+ getBandwidthEstimate: () => 1e6,
80
82
  };
81
83
 
82
84
  parser = new shaka.hls.HlsParser();
@@ -90,6 +90,8 @@ describe('HlsParser', () => {
90
90
  enableLowLatencyMode: () => {},
91
91
  updateDuration: () => {},
92
92
  newDrmInfo: shaka.test.Util.spyFunc(newDrmInfoSpy),
93
+ onManifestUpdated: () => {},
94
+ getBandwidthEstimate: () => 1e6,
93
95
  };
94
96
 
95
97
  parser = new shaka.hls.HlsParser();
@@ -3124,11 +3126,11 @@ describe('HlsParser', () => {
3124
3126
  'Null segmentIndex!');
3125
3127
 
3126
3128
  const firstMp4Segment = mp4AesEncryptionVideo.segmentIndex.get(0);
3127
- expect(firstMp4Segment.hlsAes128Key).toBeDefined();
3128
- expect(firstMp4Segment.initSegmentReference.hlsAes128Key).toBeDefined();
3129
+ expect(firstMp4Segment.aes128Key).toBeDefined();
3130
+ expect(firstMp4Segment.initSegmentReference.aes128Key).toBeDefined();
3129
3131
  const secondMp4Segment = mp4AesEncryptionVideo.segmentIndex.get(1);
3130
- expect(secondMp4Segment.hlsAes128Key).toBeNull();
3131
- expect(secondMp4Segment.initSegmentReference.hlsAes128Key).toBeDefined();
3132
+ expect(secondMp4Segment.aes128Key).toBeNull();
3133
+ expect(secondMp4Segment.initSegmentReference.aes128Key).toBeDefined();
3132
3134
 
3133
3135
  const tsAesEncryptionVideo = actual.variants[2].video;
3134
3136
  await tsAesEncryptionVideo.createSegmentIndex();
@@ -3136,9 +3138,9 @@ describe('HlsParser', () => {
3136
3138
  'Null segmentIndex!');
3137
3139
 
3138
3140
  const firstTsSegment = tsAesEncryptionVideo.segmentIndex.get(0);
3139
- expect(firstTsSegment.hlsAes128Key).toBeDefined();
3141
+ expect(firstTsSegment.aes128Key).toBeDefined();
3140
3142
  const secondTsSegment = tsAesEncryptionVideo.segmentIndex.get(1);
3141
- expect(secondTsSegment.hlsAes128Key).toBeNull();
3143
+ expect(secondTsSegment.aes128Key).toBeNull();
3142
3144
  });
3143
3145
 
3144
3146
  it('fails on AES-128 if WebCrypto APIs are not available', async () => {
@@ -49,6 +49,90 @@ describe('AdaptationSetCriteria', () => {
49
49
  ]);
50
50
  });
51
51
 
52
+ it('should not filter varaints when codec switching startegy is smooth '+
53
+ 'and changeType is supported', () => {
54
+ const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
55
+ manifest.addVariant(1, (variant) => {
56
+ variant.addAudio(10, (stream) => {
57
+ stream.codecs = 'mp4a.69';
58
+ });
59
+ variant.addVideo(11, (stream) => {
60
+ stream.codecs = 'avc1';
61
+ });
62
+ });
63
+ manifest.addVariant(2, (variant) => {
64
+ variant.addAudio(12, (stream) => {
65
+ stream.codecs = 'mp4a.66';
66
+ });
67
+ variant.addVideo(13, (stream) => {
68
+ stream.codecs = 'hvc1';
69
+ });
70
+ });
71
+ manifest.addVariant(3, (variant) => {
72
+ variant.addAudio(14, (stream) => {
73
+ stream.codecs = 'mp4a.a6';
74
+ });
75
+ variant.addVideo(14, (stream) => {
76
+ stream.codecs = 'dvh1';
77
+ });
78
+ });
79
+ });
80
+
81
+ const originalIsChangeTypeSupported = shaka.media.Capabilities
82
+ .isChangeTypeSupported;
83
+
84
+ try {
85
+ shaka.media.Capabilities.isChangeTypeSupported = () => {
86
+ return true;
87
+ };
88
+
89
+ const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0, '',
90
+ undefined, shaka.config.CodecSwitchingStrategy.SMOOTH);
91
+ const set = builder.create(manifest.variants);
92
+
93
+ expect(Array.from(set.values()).length).toBe(3);
94
+ } finally {
95
+ shaka.media.Capabilities
96
+ .isChangeTypeSupported = originalIsChangeTypeSupported;
97
+ }
98
+ });
99
+
100
+ it('should filter varaints when codec switching startegy'+
101
+ 'is not SMOOTH', () => {
102
+ const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
103
+ manifest.addVariant(1, (variant) => {
104
+ variant.addAudio(10, (stream) => {
105
+ stream.codecs = 'mp4a.69';
106
+ });
107
+ variant.addVideo(11, (stream) => {
108
+ stream.codecs = 'avc1';
109
+ });
110
+ });
111
+ manifest.addVariant(2, (variant) => {
112
+ variant.addAudio(12, (stream) => {
113
+ stream.codecs = 'mp4a.66';
114
+ });
115
+ variant.addVideo(13, (stream) => {
116
+ stream.codecs = 'hvc1';
117
+ });
118
+ });
119
+ manifest.addVariant(3, (variant) => {
120
+ variant.addAudio(14, (stream) => {
121
+ stream.codecs = 'mp4a.a6';
122
+ });
123
+ variant.addVideo(14, (stream) => {
124
+ stream.codecs = 'dvh1';
125
+ });
126
+ });
127
+ });
128
+
129
+ const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0, '',
130
+ undefined, shaka.config.CodecSwitchingStrategy.RELOAD);
131
+ const set = builder.create(manifest.variants);
132
+
133
+ expect(Array.from(set.values()).length).toBe(1);
134
+ });
135
+
52
136
  it('chooses variants in preferred language and role', () => {
53
137
  const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
54
138
  manifest.addVariant(1, (variant) => {
@@ -524,6 +608,40 @@ describe('AdaptationSetCriteria', () => {
524
608
  manifest.variants[2],
525
609
  ]);
526
610
  });
611
+
612
+ it('filters by audio group if present', () => {
613
+ const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
614
+ manifest.addVariant(1, (variant) => {
615
+ variant.language = 'en';
616
+ variant.bandwidth = 300;
617
+ variant.addAudio(10, (stream) => {
618
+ stream.groupId = '1';
619
+ });
620
+ });
621
+ manifest.addVariant(2, (variant) => {
622
+ variant.language = 'en';
623
+ variant.bandwidth = 400;
624
+ variant.addAudio(11, (stream) => {
625
+ stream.groupId = '2';
626
+ });
627
+ });
628
+ manifest.addVariant(3, (variant) => {
629
+ variant.language = 'en';
630
+ variant.bandwidth = 500;
631
+ variant.addAudio(12, (stream) => {
632
+ stream.groupId = '1';
633
+ });
634
+ });
635
+ });
636
+
637
+ const builder = new shaka.media.PreferenceBasedCriteria('en', '', 0, '');
638
+ const set = builder.create(manifest.variants);
639
+
640
+ checkSet(set, [
641
+ manifest.variants[0],
642
+ manifest.variants[2],
643
+ ]);
644
+ });
527
645
  });
528
646
 
529
647
  /**
@@ -221,6 +221,7 @@ describe('AdaptationSet', () => {
221
221
  type: '',
222
222
  accessibilityPurpose: null,
223
223
  external: false,
224
+ groupId: null,
224
225
  };
225
226
  }
226
227
  });