shaka-player 4.5.0 → 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.
Files changed (214) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/AUTHORS +2 -0
  3. package/CHANGELOG.md +98 -0
  4. package/CODE_OF_CONDUCT.md +1 -1
  5. package/CONTRIBUTORS +2 -0
  6. package/README.md +38 -32
  7. package/demo/common/asset.js +11 -17
  8. package/demo/common/assets.js +117 -11
  9. package/demo/config.js +28 -1
  10. package/demo/custom.js +52 -38
  11. package/demo/main.js +11 -3
  12. package/demo/search.js +7 -0
  13. package/dist/controls.css +1 -1
  14. package/dist/controls.css.map +1 -1
  15. package/dist/demo.compiled.debug.js +133 -124
  16. package/dist/demo.compiled.debug.map +3 -3
  17. package/dist/demo.compiled.js +133 -124
  18. package/dist/demo.compiled.map +3 -3
  19. package/dist/deps.js +20 -18
  20. package/dist/locales.js +35 -31
  21. package/dist/receiver.compiled.debug.js +58 -50
  22. package/dist/receiver.compiled.debug.map +3 -3
  23. package/dist/receiver.compiled.js +58 -50
  24. package/dist/receiver.compiled.map +3 -3
  25. package/dist/shaka-player.compiled.d.ts +440 -390
  26. package/dist/shaka-player.compiled.debug.d.ts +440 -390
  27. package/dist/shaka-player.compiled.debug.externs.js +162 -77
  28. package/dist/shaka-player.compiled.debug.js +786 -736
  29. package/dist/shaka-player.compiled.debug.map +4 -4
  30. package/dist/shaka-player.compiled.externs.js +162 -77
  31. package/dist/shaka-player.compiled.js +1154 -1121
  32. package/dist/shaka-player.compiled.map +4 -4
  33. package/dist/shaka-player.ui.d.ts +491 -437
  34. package/dist/shaka-player.ui.debug.d.ts +491 -437
  35. package/dist/shaka-player.ui.debug.externs.js +167 -77
  36. package/dist/shaka-player.ui.debug.js +877 -811
  37. package/dist/shaka-player.ui.debug.map +4 -4
  38. package/dist/shaka-player.ui.externs.js +167 -77
  39. package/dist/shaka-player.ui.js +1362 -1318
  40. package/dist/shaka-player.ui.map +4 -4
  41. package/docs/tutorials/ad_monetization.md +54 -0
  42. package/docs/tutorials/basic-usage.md +2 -1
  43. package/docs/tutorials/errors.md +2 -1
  44. package/docs/tutorials/offline.md +10 -8
  45. package/docs/tutorials/plugins.md +5 -0
  46. package/docs/tutorials/ui-customization.md +13 -0
  47. package/docs/tutorials/ui.md +2 -1
  48. package/docs/tutorials/upgrade.md +3 -0
  49. package/externs/managedmediasource.js +24 -0
  50. package/externs/shaka/abr_manager.js +6 -2
  51. package/externs/shaka/cea.js +7 -0
  52. package/externs/shaka/codecs.js +5 -3
  53. package/externs/shaka/manifest.js +21 -5
  54. package/externs/shaka/manifest_parser.js +17 -0
  55. package/externs/shaka/net.js +2 -2
  56. package/externs/shaka/offline.js +9 -2
  57. package/externs/shaka/player.js +53 -7
  58. package/externs/shaka/text.js +3 -1
  59. package/externs/shaka/transmuxer.js +1 -1
  60. package/lib/abr/simple_abr_manager.js +25 -8
  61. package/lib/ads/media_tailor_ad_manager.js +14 -3
  62. package/lib/cast/cast_receiver.js +1 -1
  63. package/lib/cea/cea_decoder.js +28 -0
  64. package/lib/cea/dummy_caption_decoder.js +5 -0
  65. package/lib/dash/dash_parser.js +249 -83
  66. package/lib/dash/mpd_utils.js +52 -31
  67. package/lib/dash/segment_base.js +4 -5
  68. package/lib/dash/segment_list.js +5 -4
  69. package/lib/dash/segment_template.js +83 -26
  70. package/lib/hls/hls_classes.js +28 -43
  71. package/lib/hls/hls_parser.js +761 -649
  72. package/lib/hls/hls_utils.js +64 -5
  73. package/lib/hls/manifest_text_parser.js +7 -11
  74. package/lib/media/adaptation_set.js +20 -13
  75. package/lib/media/adaptation_set_criteria.js +70 -18
  76. package/lib/media/closed_caption_parser.js +13 -0
  77. package/lib/media/content_workarounds.js +6 -0
  78. package/lib/media/drm_engine.js +8 -13
  79. package/lib/media/manifest_parser.js +8 -113
  80. package/lib/media/media_source_capabilities.js +10 -3
  81. package/lib/media/media_source_engine.js +75 -21
  82. package/lib/media/play_rate_controller.js +8 -38
  83. package/lib/media/presentation_timeline.js +7 -1
  84. package/lib/media/quality_observer.js +1 -1
  85. package/lib/media/segment_index.js +5 -5
  86. package/lib/media/segment_prefetch.js +92 -24
  87. package/lib/media/segment_reference.js +67 -1
  88. package/lib/media/segment_utils.js +343 -0
  89. package/lib/media/stall_detector.js +0 -3
  90. package/lib/media/streaming_engine.js +41 -21
  91. package/lib/mss/mss_parser.js +18 -2
  92. package/lib/net/networking_engine.js +66 -12
  93. package/lib/net/networking_utils.js +95 -0
  94. package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
  95. package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
  96. package/lib/offline/manifest_converter.js +2 -0
  97. package/lib/offline/offline_manifest_parser.js +10 -0
  98. package/lib/offline/storage.js +11 -7
  99. package/lib/player.js +993 -1502
  100. package/lib/polyfill/mediasource.js +22 -1
  101. package/lib/text/mp4_ttml_parser.js +2 -2
  102. package/lib/text/srt_text_parser.js +2 -2
  103. package/lib/text/stub_text_displayer.js +51 -0
  104. package/lib/text/text_engine.js +3 -2
  105. package/lib/text/ttml_text_parser.js +28 -5
  106. package/lib/text/ui_text_displayer.js +4 -0
  107. package/lib/text/vtt_text_parser.js +7 -2
  108. package/lib/transmuxer/aac_transmuxer.js +1 -1
  109. package/lib/transmuxer/ac3_transmuxer.js +1 -1
  110. package/lib/transmuxer/ec3_transmuxer.js +1 -1
  111. package/lib/transmuxer/h264.js +5 -4
  112. package/lib/transmuxer/h265.js +5 -4
  113. package/lib/transmuxer/mp3_transmuxer.js +1 -1
  114. package/lib/transmuxer/mpeg_ts_transmuxer.js +1 -1
  115. package/lib/transmuxer/mss_transmuxer.js +1 -1
  116. package/lib/transmuxer/ts_transmuxer.js +33 -13
  117. package/lib/util/buffer_utils.js +26 -4
  118. package/lib/util/content_steering_manager.js +358 -0
  119. package/lib/util/error.js +2 -6
  120. package/lib/util/fairplay_utils.js +1 -1
  121. package/lib/util/fake_event.js +5 -1
  122. package/lib/util/id3_utils.js +50 -1
  123. package/lib/util/manifest_parser_utils.js +12 -8
  124. package/lib/util/mp4_generator.js +2 -4
  125. package/lib/util/mutex.js +59 -0
  126. package/lib/util/object_utils.js +1 -1
  127. package/lib/util/periods.js +154 -179
  128. package/lib/util/platform.js +4 -3
  129. package/lib/util/player_configuration.js +35 -6
  130. package/lib/util/stream_utils.js +105 -98
  131. package/lib/util/ts_parser.js +124 -73
  132. package/lib/util/uint8array_utils.js +5 -1
  133. package/lib/util/xml_utils.js +5 -0
  134. package/maintained-branches.md +2 -2
  135. package/package.json +1 -1
  136. package/roadmap.md +15 -5
  137. package/shaka-player.uncompiled.js +0 -1
  138. package/test/abr/simple_abr_manager_unit.js +33 -33
  139. package/test/ads/ad_manager_unit.js +3 -2
  140. package/test/cast/cast_receiver_integration.js +3 -4
  141. package/test/cast/cast_utils_unit.js +2 -0
  142. package/test/cea/cea_decoder_unit.js +7 -0
  143. package/test/codec_switching/codec_switching_integration.js +2 -1
  144. package/test/dash/dash_parser_integration.js +2 -1
  145. package/test/dash/dash_parser_live_unit.js +0 -19
  146. package/test/dash/dash_parser_manifest_unit.js +494 -2
  147. package/test/dash/mpd_utils_unit.js +61 -30
  148. package/test/hls/hls_live_unit.js +12 -3
  149. package/test/hls/hls_parser_unit.js +377 -27
  150. package/test/hls/manifest_text_parser_unit.js +32 -99
  151. package/test/media/adaptation_set_criteria_unit.js +172 -21
  152. package/test/media/adaptation_set_unit.js +1 -0
  153. package/test/media/content_workarounds_unit.js +1 -1
  154. package/test/media/drm_engine_unit.js +3 -3
  155. package/test/media/media_source_engine_unit.js +1 -1
  156. package/test/media/play_rate_controller_unit.js +0 -48
  157. package/test/media/segment_index_unit.js +2 -1
  158. package/test/mss/mss_player_integration.js +3 -2
  159. package/test/net/networking_engine_unit.js +3 -3
  160. package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
  161. package/test/offline/manifest_convert_unit.js +9 -0
  162. package/test/offline/offline_integration.js +2 -1
  163. package/test/offline/storage_integration.js +21 -9
  164. package/test/player_external.js +4 -2
  165. package/test/player_integration.js +15 -4
  166. package/test/player_load_graph_integration.js +47 -151
  167. package/test/player_src_equals_external.js +1 -0
  168. package/test/player_src_equals_integration.js +71 -4
  169. package/test/player_unit.js +80 -27
  170. package/test/test/util/fake_media_source_engine.js +5 -0
  171. package/test/test/util/fake_networking_engine.js +9 -1
  172. package/test/test/util/fake_segment_prefetch.js +3 -0
  173. package/test/test/util/manifest_generator.js +4 -0
  174. package/test/test/util/manifest_parser_util.js +14 -2
  175. package/test/test/util/offline_utils.js +1 -0
  176. package/test/test/util/simple_fakes.js +2 -2
  177. package/test/test/util/streaming_engine_util.js +3 -0
  178. package/test/test/util/test_scheme.js +6 -0
  179. package/test/test/util/ui_utils.js +4 -3
  180. package/test/text/mp4_ttml_parser_unit.js +4 -4
  181. package/test/text/srt_text_parser_unit.js +1 -1
  182. package/test/text/text_displayer_layout_unit.js +1 -1
  183. package/test/text/text_engine_unit.js +6 -0
  184. package/test/text/ttml_text_parser_unit.js +33 -2
  185. package/test/transmuxer/transmuxer_engine_integration.js +9 -0
  186. package/test/transmuxer/transmuxer_integration.js +33 -3
  187. package/test/ui/ad_ui_unit.js +2 -2
  188. package/test/ui/ui_customization_unit.js +17 -16
  189. package/test/ui/ui_integration.js +30 -20
  190. package/test/ui/ui_unit.js +25 -19
  191. package/test/util/buffer_utils_unit.js +1 -1
  192. package/test/util/content_steering_manager_unit.js +427 -0
  193. package/test/util/id3_utils_unit.js +52 -0
  194. package/test/util/stream_utils_unit.js +17 -113
  195. package/test/util/ts_parser_unit.js +3 -3
  196. package/third_party/closure-uri/uri.js +13 -1
  197. package/ui/audio_language_selection.js +9 -2
  198. package/ui/externs/ui.js +17 -2
  199. package/ui/language_utils.js +43 -8
  200. package/ui/less/range_elements.less +33 -0
  201. package/ui/locales/en.json +1 -0
  202. package/ui/locales/es-419.json +1 -0
  203. package/ui/locales/es.json +1 -0
  204. package/ui/locales/source.json +4 -0
  205. package/ui/localization.js +10 -0
  206. package/ui/remote_button.js +3 -1
  207. package/ui/resolution_selection.js +47 -10
  208. package/ui/seek_bar.js +296 -3
  209. package/ui/text_selection.js +2 -1
  210. package/ui/ui.js +6 -2
  211. package/lib/routing/node.js +0 -23
  212. package/lib/routing/payload.js +0 -47
  213. package/lib/routing/walker.js +0 -587
  214. package/test/routing/walker_unit.js +0 -505
@@ -0,0 +1,427 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ describe('ContentSteeringManager', () => {
8
+ /** @type {!shaka.test.FakeNetworkingEngine} */
9
+ let fakeNetEngine;
10
+
11
+ /** @type {!shaka.util.ContentSteeringManager} */
12
+ let manager;
13
+
14
+ beforeEach(() => {
15
+ fakeNetEngine = new shaka.test.FakeNetworkingEngine();
16
+ const playerInterface = {
17
+ networkingEngine: fakeNetEngine,
18
+ modifyManifestRequest: fail,
19
+ modifySegmentRequest: fail,
20
+ filter: fail,
21
+ makeTextStreamsForClosedCaptions: fail,
22
+ onTimelineRegionAdded: fail,
23
+ onEvent: fail,
24
+ onError: fail,
25
+ isLowLatencyMode: fail,
26
+ isAutoLowLatencyMode: fail,
27
+ enableLowLatencyMode: fail,
28
+ updateDuration: fail,
29
+ newDrmInfo: fail,
30
+ onManifestUpdated: fail,
31
+ getBandwidthEstimate: () => 1e6,
32
+ };
33
+ const config = shaka.util.PlayerConfiguration.createDefault().manifest;
34
+ manager = new shaka.util.ContentSteeringManager(playerInterface);
35
+ manager.configure(config);
36
+ manager.setBaseUris([
37
+ 'http://default',
38
+ ]);
39
+ manager.addLocation('foo', 'cdn-a', 'http://cdn-a');
40
+ manager.addLocation('foo', 'cdn-b', 'http://cdn-b');
41
+ manager.addLocation('foo', 'cdn-c', 'http://cdn-c');
42
+ });
43
+
44
+ afterEach(async () => {
45
+ await manager.destroy();
46
+ });
47
+
48
+ describe('defaultPathwayId', () => {
49
+ it('allows no value', () => {
50
+ manager.setDefaultPathwayId(null);
51
+
52
+ const locations = manager.getLocations('foo');
53
+ expect(locations.length).toBe(3);
54
+ expect(locations[0]).toBe('http://cdn-a');
55
+ expect(locations[1]).toBe('http://cdn-b');
56
+ expect(locations[2]).toBe('http://cdn-c');
57
+ });
58
+
59
+ it('allows one value', () => {
60
+ manager.setDefaultPathwayId('cdn-b');
61
+
62
+ const locations = manager.getLocations('foo');
63
+ expect(locations.length).toBe(1);
64
+ expect(locations[0]).toBe('http://cdn-b');
65
+ });
66
+
67
+ it('allows multiple values', () => {
68
+ manager.setDefaultPathwayId('cdn-b,cdn-a,cdn-c');
69
+
70
+ const locations = manager.getLocations('foo');
71
+ expect(locations.length).toBe(3);
72
+ expect(locations[0]).toBe('http://cdn-b');
73
+ expect(locations[1]).toBe('http://cdn-a');
74
+ expect(locations[2]).toBe('http://cdn-c');
75
+ });
76
+ });
77
+
78
+ describe('queryParams', () => {
79
+ it('send the correct value for DASH', async () => {
80
+ manager.setManifestType(shaka.media.ManifestParser.DASH);
81
+ const manifest = JSON.stringify({
82
+ 'VERSION': 1,
83
+ 'TTL': 1,
84
+ 'RELOAD-URI': 'http://foo.bar/update',
85
+ 'PATHWAY-PRIORITY': [
86
+ 'cdn-b',
87
+ 'cdn-a',
88
+ ],
89
+ });
90
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
91
+
92
+ await manager.requestInfo('http://foo.bar/manifest');
93
+
94
+ const locations = manager.getLocations('foo');
95
+ expect(locations.length).toBe(2);
96
+ expect(locations[0]).toBe('http://cdn-b');
97
+ expect(locations[1]).toBe('http://cdn-a');
98
+
99
+ const manifestUpdate = JSON.stringify({
100
+ 'VERSION': 1,
101
+ 'TTL': 1,
102
+ 'RELOAD-URI': 'http://foo.bar/update',
103
+ 'PATHWAY-PRIORITY': [
104
+ 'cdn-b',
105
+ ],
106
+ });
107
+ const updateUrl = 'http://foo.bar/update?_DASH_pathway=cdn-b&_DASH_throughput=1000000';
108
+ fakeNetEngine.setResponseText(updateUrl, manifestUpdate);
109
+
110
+ await shaka.test.Util.delay(1);
111
+
112
+ const newLocations = manager.getLocations('foo');
113
+ expect(newLocations.length).toBe(1);
114
+ expect(newLocations[0]).toBe('http://cdn-b');
115
+ });
116
+
117
+ it('send the correct value for HLS', async () => {
118
+ manager.setManifestType(shaka.media.ManifestParser.HLS);
119
+ const manifest = JSON.stringify({
120
+ 'VERSION': 1,
121
+ 'TTL': 1,
122
+ 'RELOAD-URI': 'http://foo.bar/update',
123
+ 'PATHWAY-PRIORITY': [
124
+ 'cdn-b',
125
+ 'cdn-a',
126
+ ],
127
+ });
128
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
129
+
130
+ await manager.requestInfo('http://foo.bar/manifest');
131
+
132
+ const locations = manager.getLocations('foo');
133
+ expect(locations.length).toBe(2);
134
+ expect(locations[0]).toBe('http://cdn-b');
135
+ expect(locations[1]).toBe('http://cdn-a');
136
+
137
+ const manifestUpdate = JSON.stringify({
138
+ 'VERSION': 1,
139
+ 'TTL': 1,
140
+ 'RELOAD-URI': 'http://foo.bar/update',
141
+ 'PATHWAY-PRIORITY': [
142
+ 'cdn-b',
143
+ ],
144
+ });
145
+ const updateUrl = 'http://foo.bar/update?_HLS_pathway=cdn-b&_HLS_throughput=1000000';
146
+ fakeNetEngine.setResponseText(updateUrl, manifestUpdate);
147
+
148
+ await shaka.test.Util.delay(1);
149
+
150
+ const newLocations = manager.getLocations('foo');
151
+ expect(newLocations.length).toBe(1);
152
+ expect(newLocations[0]).toBe('http://cdn-b');
153
+ });
154
+
155
+ it('not send value for unknown manifest', async () => {
156
+ const manifest = JSON.stringify({
157
+ 'VERSION': 1,
158
+ 'TTL': 1,
159
+ 'RELOAD-URI': 'http://foo.bar/update',
160
+ 'PATHWAY-PRIORITY': [
161
+ 'cdn-b',
162
+ 'cdn-a',
163
+ ],
164
+ });
165
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
166
+
167
+ await manager.requestInfo('http://foo.bar/manifest');
168
+
169
+ const locations = manager.getLocations('foo');
170
+ expect(locations.length).toBe(2);
171
+ expect(locations[0]).toBe('http://cdn-b');
172
+ expect(locations[1]).toBe('http://cdn-a');
173
+
174
+ const manifestUpdate = JSON.stringify({
175
+ 'VERSION': 1,
176
+ 'TTL': 1,
177
+ 'RELOAD-URI': 'http://foo.bar/update',
178
+ 'PATHWAY-PRIORITY': [
179
+ 'cdn-b',
180
+ ],
181
+ });
182
+ fakeNetEngine.setResponseText('http://foo.bar/update', manifestUpdate);
183
+
184
+ await shaka.test.Util.delay(1);
185
+
186
+ const newLocations = manager.getLocations('foo');
187
+ expect(newLocations.length).toBe(1);
188
+ expect(newLocations[0]).toBe('http://cdn-b');
189
+ });
190
+ });
191
+
192
+ describe('steeringManifest', () => {
193
+ it('ignores manifest with a version different than 1', async () => {
194
+ const manifest = JSON.stringify({
195
+ 'VERSION': 35,
196
+ 'TTL': 10,
197
+ 'RELOAD-URI': 'http://foo.bar/update',
198
+ 'PATHWAY-PRIORITY': [
199
+ 'cdn-b',
200
+ 'cdn-a',
201
+ ],
202
+ });
203
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
204
+
205
+ await manager.requestInfo('http://foo.bar/manifest');
206
+
207
+ const locations = manager.getLocations('foo');
208
+ expect(locations.length).toBe(3);
209
+ expect(locations[0]).toBe('http://cdn-a');
210
+ expect(locations[1]).toBe('http://cdn-b');
211
+ expect(locations[2]).toBe('http://cdn-c');
212
+ });
213
+
214
+ it('honors RELOAD-URI', async () => {
215
+ const manifest = JSON.stringify({
216
+ 'VERSION': 1,
217
+ 'TTL': 1,
218
+ 'RELOAD-URI': 'http://foo.bar/update',
219
+ 'PATHWAY-PRIORITY': [
220
+ 'cdn-b',
221
+ 'cdn-a',
222
+ ],
223
+ });
224
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
225
+
226
+ await manager.requestInfo('http://foo.bar/manifest');
227
+
228
+ const locations = manager.getLocations('foo');
229
+ expect(locations.length).toBe(2);
230
+ expect(locations[0]).toBe('http://cdn-b');
231
+ expect(locations[1]).toBe('http://cdn-a');
232
+
233
+ const manifestUpdate = JSON.stringify({
234
+ 'VERSION': 1,
235
+ 'TTL': 1,
236
+ 'RELOAD-URI': 'http://foo.bar/update',
237
+ 'PATHWAY-PRIORITY': [
238
+ 'cdn-b',
239
+ ],
240
+ });
241
+ fakeNetEngine.setResponseText('http://foo.bar/update', manifestUpdate);
242
+
243
+ await shaka.test.Util.delay(1);
244
+
245
+ const newLocations = manager.getLocations('foo');
246
+ expect(newLocations.length).toBe(1);
247
+ expect(newLocations[0]).toBe('http://cdn-b');
248
+ });
249
+
250
+ it('fallback for no RELOAD-URI', async () => {
251
+ const manifest = JSON.stringify({
252
+ 'VERSION': 1,
253
+ 'TTL': 1,
254
+ 'PATHWAY-PRIORITY': [
255
+ 'cdn-b',
256
+ 'cdn-a',
257
+ ],
258
+ });
259
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
260
+
261
+ await manager.requestInfo('http://foo.bar/manifest');
262
+
263
+ const locations = manager.getLocations('foo');
264
+ expect(locations.length).toBe(2);
265
+ expect(locations[0]).toBe('http://cdn-b');
266
+ expect(locations[1]).toBe('http://cdn-a');
267
+
268
+ const manifestUpdate = JSON.stringify({
269
+ 'VERSION': 1,
270
+ 'TTL': 1,
271
+ 'PATHWAY-PRIORITY': [
272
+ 'cdn-b',
273
+ ],
274
+ });
275
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifestUpdate);
276
+
277
+ await shaka.test.Util.delay(1);
278
+
279
+ const newLocations = manager.getLocations('foo');
280
+ expect(newLocations.length).toBe(1);
281
+ expect(newLocations[0]).toBe('http://cdn-b');
282
+ });
283
+
284
+ it('honors TTL', async () => {
285
+ const manifest = JSON.stringify({
286
+ 'VERSION': 1,
287
+ 'TTL': 1,
288
+ 'RELOAD-URI': 'http://foo.bar/update',
289
+ 'PATHWAY-PRIORITY': [
290
+ 'cdn-b',
291
+ 'cdn-a',
292
+ ],
293
+ });
294
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
295
+
296
+ await manager.requestInfo('http://foo.bar/manifest');
297
+
298
+ const locations = manager.getLocations('foo');
299
+ expect(locations.length).toBe(2);
300
+ expect(locations[0]).toBe('http://cdn-b');
301
+ expect(locations[1]).toBe('http://cdn-a');
302
+
303
+ const manifestUpdate = JSON.stringify({
304
+ 'VERSION': 1,
305
+ 'TTL': 2,
306
+ 'RELOAD-URI': 'http://foo.bar/update',
307
+ 'PATHWAY-PRIORITY': [
308
+ 'cdn-b',
309
+ ],
310
+ });
311
+ fakeNetEngine.setResponseText('http://foo.bar/update', manifestUpdate);
312
+
313
+ await shaka.test.Util.delay(2);
314
+
315
+ const newLocations = manager.getLocations('foo');
316
+ expect(newLocations.length).toBe(1);
317
+ expect(newLocations[0]).toBe('http://cdn-b');
318
+ });
319
+ });
320
+
321
+ describe('get correct locations', () => {
322
+ it('with PATHWAY-PRIORITY', async () => {
323
+ const manifest = JSON.stringify({
324
+ 'VERSION': 1,
325
+ 'TTL': 10,
326
+ 'RELOAD-URI': 'http://foo.bar/update',
327
+ 'PATHWAY-PRIORITY': [
328
+ 'cdn-b',
329
+ 'cdn-a',
330
+ 'cdn-c',
331
+ ],
332
+ });
333
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
334
+
335
+ await manager.requestInfo('http://foo.bar/manifest');
336
+
337
+ const locations = manager.getLocations('foo');
338
+ expect(locations.length).toBe(3);
339
+ expect(locations[0]).toBe('http://cdn-b');
340
+ expect(locations[1]).toBe('http://cdn-a');
341
+ expect(locations[2]).toBe('http://cdn-c');
342
+ });
343
+
344
+ it('with PATHWAY-PRIORITY and PATHWAY-CLONES', async () => {
345
+ const manifest = JSON.stringify({
346
+ 'VERSION': 1,
347
+ 'TTL': 10,
348
+ 'RELOAD-URI': 'http://foo.bar/update',
349
+ 'PATHWAY-PRIORITY': [
350
+ 'cdn-d',
351
+ 'cdn-b',
352
+ 'cdn-a',
353
+ 'cdn-c',
354
+ ],
355
+ 'PATHWAY-CLONES': [
356
+ {
357
+ 'BASE-ID': 'cdn-c',
358
+ 'ID': 'cdn-d',
359
+ 'URI-REPLACEMENT': {
360
+ 'HOST': 'cdn-d',
361
+ },
362
+ },
363
+ ],
364
+ });
365
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
366
+
367
+ await manager.requestInfo('http://foo.bar/manifest');
368
+
369
+ const locations = manager.getLocations('foo');
370
+ expect(locations.length).toBe(4);
371
+ expect(locations[0]).toBe('http://cdn-d');
372
+ expect(locations[1]).toBe('http://cdn-b');
373
+ expect(locations[2]).toBe('http://cdn-a');
374
+ expect(locations[3]).toBe('http://cdn-c');
375
+ });
376
+
377
+ it('without PATHWAY-PRIORITY but with defaultPathwayId', () => {
378
+ manager.setDefaultPathwayId('cdn-b,cdn-a,cdn-c');
379
+
380
+ const locations = manager.getLocations('foo');
381
+ expect(locations.length).toBe(3);
382
+ expect(locations[0]).toBe('http://cdn-b');
383
+ expect(locations[1]).toBe('http://cdn-a');
384
+ expect(locations[2]).toBe('http://cdn-c');
385
+ });
386
+
387
+ it('without PATHWAY-PRIORITY neither defaultPathwayId', () => {
388
+ const locations = manager.getLocations('foo');
389
+ expect(locations.length).toBe(3);
390
+ expect(locations[0]).toBe('http://cdn-a');
391
+ expect(locations[1]).toBe('http://cdn-b');
392
+ expect(locations[2]).toBe('http://cdn-c');
393
+ });
394
+
395
+ it('use baseuris if no locations', () => {
396
+ manager.clearPreviousLocations();
397
+ const locations = manager.getLocations('foo');
398
+ expect(locations.length).toBe(1);
399
+ expect(locations[0]).toBe('http://default');
400
+ });
401
+ });
402
+
403
+ describe('allow ban locations', () => {
404
+ it('with PATHWAY-PRIORITY', async () => {
405
+ const manifest = JSON.stringify({
406
+ 'VERSION': 1,
407
+ 'TTL': 10,
408
+ 'RELOAD-URI': 'http://foo.bar/update',
409
+ 'PATHWAY-PRIORITY': [
410
+ 'cdn-b',
411
+ 'cdn-a',
412
+ 'cdn-c',
413
+ ],
414
+ });
415
+ fakeNetEngine.setResponseText('http://foo.bar/manifest', manifest);
416
+
417
+ await manager.requestInfo('http://foo.bar/manifest');
418
+
419
+ manager.banLocation('http://cdn-b');
420
+
421
+ const locations = manager.getLocations('foo');
422
+ expect(locations.length).toBe(2);
423
+ expect(locations[0]).toBe('http://cdn-a');
424
+ expect(locations[1]).toBe('http://cdn-c');
425
+ });
426
+ });
427
+ });
@@ -13,6 +13,44 @@ describe('Id3Utils', () => {
13
13
  expect(Id3Utils.getID3Frames(new Uint8Array([]))).toEqual([]);
14
14
  });
15
15
 
16
+ it('parse an APIC frame with image data', () => {
17
+ const apicValue = new Uint8Array([
18
+ 3, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 0, 3, 83, 104, 97,
19
+ 107, 97, 0, 1, 2, 3,
20
+ ]);
21
+ const apicFrame = Id3Generator.generateId3Frame('APIC', apicValue);
22
+ const apicID3 = Id3Generator.generateId3(apicFrame);
23
+ const expectedID3 = [
24
+ {
25
+ key: 'APIC',
26
+ mimeType: 'image/jpeg',
27
+ pictureType: 3,
28
+ description: 'Shaka',
29
+ data: BufferUtils.toArrayBuffer(new Uint8Array([1, 2, 3])),
30
+ },
31
+ ];
32
+ expect(Id3Utils.getID3Frames(apicID3)).toEqual(expectedID3);
33
+ });
34
+
35
+ it('parse an APIC frame with image URL', () => {
36
+ const apicValue = new Uint8Array([
37
+ 3, 45, 45, 62, 0, 3, 83, 104, 97, 107, 97, 0, 103, 111, 111, 103, 108,
38
+ 101, 46, 99, 111, 109,
39
+ ]);
40
+ const apicFrame = Id3Generator.generateId3Frame('APIC', apicValue);
41
+ const apicID3 = Id3Generator.generateId3(apicFrame);
42
+ const expectedID3 = [
43
+ {
44
+ key: 'APIC',
45
+ mimeType: '-->',
46
+ pictureType: 3,
47
+ description: 'Shaka',
48
+ data: 'google.com',
49
+ },
50
+ ];
51
+ expect(Id3Utils.getID3Frames(apicID3)).toEqual(expectedID3);
52
+ });
53
+
16
54
  it('parse a TXXX frame', () => {
17
55
  const txxxValue = new Uint8Array([3, 65, 0, 83, 104, 97, 107, 97]);
18
56
  const txxxFrame = Id3Generator.generateId3Frame('TXXX', txxxValue);
@@ -22,6 +60,8 @@ describe('Id3Utils', () => {
22
60
  key: 'TXXX',
23
61
  description: 'A',
24
62
  data: 'Shaka',
63
+ mimeType: null,
64
+ pictureType: null,
25
65
  },
26
66
  ];
27
67
  expect(Id3Utils.getID3Frames(txxxID3)).toEqual(expectedID3);
@@ -36,6 +76,8 @@ describe('Id3Utils', () => {
36
76
  key: 'TXXX',
37
77
  description: 'A',
38
78
  data: 'Shaka',
79
+ mimeType: null,
80
+ pictureType: null,
39
81
  },
40
82
  ];
41
83
  expect(Id3Utils.getID3Frames(txxxID3)).toEqual(expectedID3);
@@ -51,6 +93,8 @@ describe('Id3Utils', () => {
51
93
  key: 'TCOP',
52
94
  description: '',
53
95
  data: 'Shaka 2016',
96
+ mimeType: null,
97
+ pictureType: null,
54
98
  },
55
99
  ];
56
100
  expect(Id3Utils.getID3Frames(tcopID3)).toEqual(expectedID3);
@@ -66,6 +110,8 @@ describe('Id3Utils', () => {
66
110
  key: 'WXXX',
67
111
  description: 'A',
68
112
  data: 'google.com',
113
+ mimeType: null,
114
+ pictureType: null,
69
115
  },
70
116
  ];
71
117
  expect(Id3Utils.getID3Frames(wxxxID3)).toEqual(expectedID3);
@@ -81,6 +127,8 @@ describe('Id3Utils', () => {
81
127
  key: 'WCOP',
82
128
  description: '',
83
129
  data: 'google.com',
130
+ mimeType: null,
131
+ pictureType: null,
84
132
  },
85
133
  ];
86
134
  expect(Id3Utils.getID3Frames(wcopID3)).toEqual(expectedID3);
@@ -95,6 +143,8 @@ describe('Id3Utils', () => {
95
143
  key: 'PRIV',
96
144
  description: 'A',
97
145
  data: BufferUtils.toArrayBuffer(new Uint8Array([83, 104, 97, 107])),
146
+ mimeType: null,
147
+ pictureType: null,
98
148
  },
99
149
  ];
100
150
  expect(Id3Utils.getID3Frames(privID3)).toEqual(expectedID3);
@@ -109,6 +159,8 @@ describe('Id3Utils', () => {
109
159
  key: 'XXXX',
110
160
  description: '',
111
161
  data: BufferUtils.toArrayBuffer(new Uint8Array([83, 104, 97, 107])),
162
+ mimeType: null,
163
+ pictureType: null,
112
164
  },
113
165
  ];
114
166
  expect(Id3Utils.getID3Frames(unknownID3)).toEqual(expectedID3);