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.
Files changed (307) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/.github/workflows/release-please.yaml +2 -27
  3. package/AUTHORS +2 -0
  4. package/CHANGELOG.md +156 -39
  5. package/CODE_OF_CONDUCT.md +1 -1
  6. package/CONTRIBUTORS +2 -0
  7. package/README.md +54 -42
  8. package/demo/asset_card.js +18 -21
  9. package/demo/cast_receiver/index.html +0 -1
  10. package/demo/close_button.js +0 -3
  11. package/demo/common/asset.js +33 -22
  12. package/demo/common/assets.js +249 -60
  13. package/demo/config.js +219 -253
  14. package/demo/custom.js +88 -133
  15. package/demo/front.js +7 -10
  16. package/demo/index.html +19 -22
  17. package/demo/input.js +6 -11
  18. package/demo/input_container.js +8 -9
  19. package/demo/main.js +62 -126
  20. package/demo/search.js +29 -34
  21. package/demo/service_worker.js +0 -3
  22. package/demo/tooltip.js +3 -5
  23. package/demo/visualizer.js +3 -5
  24. package/demo/visualizer_button.js +1 -20
  25. package/dist/controls.css +1 -1
  26. package/dist/controls.css.map +1 -1
  27. package/dist/demo.compiled.debug.js +211 -228
  28. package/dist/demo.compiled.debug.map +4 -4
  29. package/dist/demo.compiled.js +211 -228
  30. package/dist/demo.compiled.map +4 -4
  31. package/dist/deps.js +42 -37
  32. package/dist/locales.js +34 -30
  33. package/dist/receiver.compiled.debug.js +64 -77
  34. package/dist/receiver.compiled.debug.map +4 -4
  35. package/dist/receiver.compiled.js +64 -77
  36. package/dist/receiver.compiled.map +4 -4
  37. package/dist/shaka-player.compiled.d.ts +343 -151
  38. package/dist/shaka-player.compiled.debug.d.ts +343 -151
  39. package/dist/shaka-player.compiled.debug.externs.js +356 -117
  40. package/dist/shaka-player.compiled.debug.js +952 -811
  41. package/dist/shaka-player.compiled.debug.map +4 -4
  42. package/dist/shaka-player.compiled.externs.js +356 -117
  43. package/dist/shaka-player.compiled.js +1165 -1078
  44. package/dist/shaka-player.compiled.map +4 -4
  45. package/dist/shaka-player.ui.d.ts +359 -153
  46. package/dist/shaka-player.ui.debug.d.ts +359 -153
  47. package/dist/shaka-player.ui.debug.externs.js +382 -117
  48. package/dist/shaka-player.ui.debug.js +1084 -918
  49. package/dist/shaka-player.ui.debug.map +4 -4
  50. package/dist/shaka-player.ui.externs.js +382 -117
  51. package/dist/shaka-player.ui.js +1377 -1274
  52. package/dist/shaka-player.ui.map +4 -4
  53. package/docs/design/lcevc-integration.md +14 -14
  54. package/docs/tutorials/ad_monetization.md +54 -0
  55. package/docs/tutorials/basic-usage.md +2 -1
  56. package/docs/tutorials/errors.md +2 -1
  57. package/docs/tutorials/faq.md +27 -55
  58. package/docs/tutorials/index.json +2 -1
  59. package/docs/tutorials/lcevc.md +118 -0
  60. package/docs/tutorials/offline.md +10 -8
  61. package/docs/tutorials/plugins.md +5 -0
  62. package/docs/tutorials/ui-customization.md +17 -0
  63. package/docs/tutorials/ui.md +2 -1
  64. package/docs/tutorials/upgrade.md +3 -0
  65. package/externs/css_style_declaration.js +19 -0
  66. package/externs/lcevc.js +37 -13
  67. package/externs/managedmediasource.js +24 -0
  68. package/externs/media_remote.js +68 -0
  69. package/externs/mediatailor.js +193 -0
  70. package/externs/pictureinpicture.js +11 -0
  71. package/externs/shaka/abr_manager.js +6 -2
  72. package/externs/shaka/ads.js +27 -0
  73. package/externs/shaka/cea.js +7 -0
  74. package/externs/shaka/codecs.js +5 -3
  75. package/externs/shaka/manifest.js +31 -10
  76. package/externs/shaka/manifest_parser.js +24 -1
  77. package/externs/shaka/net.js +2 -2
  78. package/externs/shaka/offline.js +13 -2
  79. package/externs/shaka/player.js +65 -8
  80. package/externs/shaka/text.js +3 -1
  81. package/externs/shaka/transmuxer.js +1 -1
  82. package/karma.conf.js +7 -3
  83. package/lib/abr/simple_abr_manager.js +66 -9
  84. package/lib/ads/ad_manager.js +104 -50
  85. package/lib/ads/media_tailor_ad.js +297 -0
  86. package/lib/ads/media_tailor_ad_manager.js +839 -0
  87. package/lib/cast/cast_receiver.js +1 -1
  88. package/lib/cea/cea_decoder.js +28 -0
  89. package/lib/cea/dummy_caption_decoder.js +5 -0
  90. package/lib/cea/ts_cea_parser.js +15 -2
  91. package/lib/config/codec_switching_strategy.js +24 -0
  92. package/lib/dash/content_protection.js +120 -2
  93. package/lib/dash/dash_parser.js +322 -93
  94. package/lib/dash/mpd_utils.js +62 -37
  95. package/lib/dash/segment_base.js +17 -10
  96. package/lib/dash/segment_list.js +18 -9
  97. package/lib/dash/segment_template.js +122 -107
  98. package/lib/dependencies/all.js +8 -7
  99. package/lib/hls/hls_classes.js +28 -43
  100. package/lib/hls/hls_parser.js +798 -658
  101. package/lib/hls/hls_utils.js +64 -5
  102. package/lib/hls/manifest_text_parser.js +7 -11
  103. package/lib/lcevc/lcevc_dec.js +220 -0
  104. package/lib/media/adaptation_set.js +32 -14
  105. package/lib/media/adaptation_set_criteria.js +86 -16
  106. package/lib/media/closed_caption_parser.js +13 -0
  107. package/lib/media/content_workarounds.js +6 -0
  108. package/lib/media/drm_engine.js +8 -13
  109. package/lib/media/manifest_parser.js +8 -113
  110. package/lib/media/media_source_capabilities.js +10 -3
  111. package/lib/media/media_source_engine.js +286 -44
  112. package/lib/media/play_rate_controller.js +8 -38
  113. package/lib/media/presentation_timeline.js +7 -1
  114. package/lib/media/quality_observer.js +1 -1
  115. package/lib/media/segment_index.js +6 -6
  116. package/lib/media/segment_prefetch.js +92 -24
  117. package/lib/media/segment_reference.js +73 -7
  118. package/lib/media/segment_utils.js +343 -0
  119. package/lib/media/stall_detector.js +0 -3
  120. package/lib/media/streaming_engine.js +73 -38
  121. package/lib/mss/mss_parser.js +19 -2
  122. package/lib/net/networking_engine.js +67 -12
  123. package/lib/net/networking_utils.js +95 -0
  124. package/lib/offline/indexeddb/v1_storage_cell.js +3 -0
  125. package/lib/offline/indexeddb/v2_storage_cell.js +3 -0
  126. package/lib/offline/manifest_converter.js +3 -0
  127. package/lib/offline/offline_manifest_parser.js +10 -0
  128. package/lib/offline/storage.js +14 -7
  129. package/lib/player.js +1098 -1537
  130. package/lib/polyfill/mediasource.js +22 -1
  131. package/lib/text/cue.js +15 -0
  132. package/lib/text/mp4_ttml_parser.js +2 -2
  133. package/lib/text/srt_text_parser.js +2 -2
  134. package/lib/text/stub_text_displayer.js +51 -0
  135. package/lib/text/text_engine.js +3 -2
  136. package/lib/text/ttml_text_parser.js +45 -5
  137. package/lib/text/ui_text_displayer.js +8 -0
  138. package/lib/text/vtt_text_parser.js +40 -22
  139. package/lib/transmuxer/aac_transmuxer.js +1 -1
  140. package/lib/transmuxer/ac3_transmuxer.js +1 -1
  141. package/lib/transmuxer/ec3_transmuxer.js +1 -1
  142. package/lib/transmuxer/h264.js +5 -4
  143. package/lib/transmuxer/h265.js +863 -0
  144. package/lib/transmuxer/mp3_transmuxer.js +1 -1
  145. package/lib/transmuxer/mpeg_ts_transmuxer.js +4 -3
  146. package/lib/transmuxer/mss_transmuxer.js +1 -1
  147. package/lib/transmuxer/ts_transmuxer.js +187 -22
  148. package/lib/util/buffer_utils.js +26 -4
  149. package/lib/util/content_steering_manager.js +358 -0
  150. package/lib/util/error.js +30 -15
  151. package/lib/util/exp_golomb.js +30 -2
  152. package/lib/util/fairplay_utils.js +1 -1
  153. package/lib/util/fake_event.js +8 -1
  154. package/lib/util/id3_utils.js +50 -1
  155. package/lib/util/manifest_parser_utils.js +12 -8
  156. package/lib/util/mp4_generator.js +6 -8
  157. package/lib/util/mutex.js +59 -0
  158. package/lib/util/object_utils.js +1 -1
  159. package/lib/util/periods.js +156 -179
  160. package/lib/util/platform.js +44 -3
  161. package/lib/util/player_configuration.js +43 -6
  162. package/lib/util/state_history.js +6 -2
  163. package/lib/util/stream_utils.js +206 -283
  164. package/lib/util/ts_parser.js +335 -98
  165. package/lib/util/uint8array_utils.js +5 -1
  166. package/lib/util/xml_utils.js +5 -0
  167. package/maintained-branches.md +3 -2
  168. package/package.json +4 -6
  169. package/roadmap.md +25 -5
  170. package/shaka-player.uncompiled.js +2 -2
  171. package/support.html +0 -1
  172. package/test/abr/simple_abr_manager_unit.js +33 -33
  173. package/test/ads/ad_manager_unit.js +3 -2
  174. package/test/cast/cast_receiver_integration.js +50 -4
  175. package/test/cast/cast_utils_unit.js +2 -0
  176. package/test/cea/cea_decoder_unit.js +7 -0
  177. package/test/codec_switching/codec_switching_integration.js +182 -0
  178. package/test/dash/dash_parser_content_protection_unit.js +2 -0
  179. package/test/dash/dash_parser_integration.js +74 -0
  180. package/test/dash/dash_parser_live_unit.js +2 -19
  181. package/test/dash/dash_parser_manifest_unit.js +536 -2
  182. package/test/dash/dash_parser_segment_base_unit.js +2 -0
  183. package/test/dash/dash_parser_segment_list_unit.js +2 -0
  184. package/test/dash/dash_parser_segment_template_unit.js +2 -0
  185. package/test/dash/mpd_utils_unit.js +61 -30
  186. package/test/demo/demo_unit.js +0 -16
  187. package/test/hls/hls_live_unit.js +14 -3
  188. package/test/hls/hls_parser_unit.js +385 -33
  189. package/test/hls/manifest_text_parser_unit.js +32 -99
  190. package/test/media/adaptation_set_criteria_unit.js +284 -15
  191. package/test/media/adaptation_set_unit.js +2 -0
  192. package/test/media/content_workarounds_unit.js +1 -1
  193. package/test/media/drm_engine_unit.js +3 -3
  194. package/test/media/media_source_engine_unit.js +166 -2
  195. package/test/media/play_rate_controller_unit.js +0 -48
  196. package/test/media/segment_index_unit.js +5 -4
  197. package/test/media/segment_prefetch_unit.js +1 -1
  198. package/test/media/streaming_engine_unit.js +17 -17
  199. package/test/mss/mss_parser_unit.js +2 -0
  200. package/test/mss/mss_player_integration.js +3 -2
  201. package/test/net/networking_engine_unit.js +3 -3
  202. package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
  203. package/test/offline/manifest_convert_unit.js +14 -0
  204. package/test/offline/offline_integration.js +2 -1
  205. package/test/offline/storage_integration.js +22 -13
  206. package/test/player_external.js +4 -2
  207. package/test/player_integration.js +15 -4
  208. package/test/player_load_graph_integration.js +47 -151
  209. package/test/player_src_equals_external.js +1 -0
  210. package/test/player_src_equals_integration.js +71 -4
  211. package/test/player_unit.js +182 -158
  212. package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
  213. package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
  214. package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
  215. package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
  216. package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
  217. package/test/test/assets/dash-aes-128/dash.mpd +18 -0
  218. package/test/test/assets/dash-aes-128/license +1 -0
  219. package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
  220. package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
  221. package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
  222. package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
  223. package/test/test/assets/hls-ts-h265/0.ts +0 -0
  224. package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
  225. package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
  226. package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
  227. package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
  228. package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
  229. package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
  230. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
  231. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
  232. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
  233. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
  234. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
  235. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
  236. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
  237. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
  238. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
  239. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
  240. package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
  241. package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
  242. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
  243. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
  244. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
  245. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
  246. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
  247. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
  248. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
  249. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
  250. package/test/test/util/dash_parser_util.js +4 -0
  251. package/test/test/util/fake_ad_manager.js +20 -0
  252. package/test/test/util/fake_media_source_engine.js +13 -2
  253. package/test/test/util/fake_networking_engine.js +9 -1
  254. package/test/test/util/fake_segment_prefetch.js +3 -0
  255. package/test/test/util/manifest_generator.js +11 -3
  256. package/test/test/util/manifest_parser_util.js +14 -2
  257. package/test/test/util/mss_parser_util.js +4 -0
  258. package/test/test/util/offline_utils.js +2 -0
  259. package/test/test/util/simple_fakes.js +2 -2
  260. package/test/test/util/streaming_engine_util.js +10 -4
  261. package/test/test/util/test_scheme.js +6 -0
  262. package/test/test/util/ui_utils.js +4 -3
  263. package/test/text/mp4_ttml_parser_unit.js +4 -4
  264. package/test/text/srt_text_parser_unit.js +1 -1
  265. package/test/text/text_displayer_layout_unit.js +1 -1
  266. package/test/text/text_engine_unit.js +6 -0
  267. package/test/text/ttml_text_parser_unit.js +85 -2
  268. package/test/text/vtt_text_parser_unit.js +103 -31
  269. package/test/transmuxer/transmuxer_engine_integration.js +9 -0
  270. package/test/transmuxer/transmuxer_integration.js +150 -3
  271. package/test/ui/ad_ui_unit.js +2 -2
  272. package/test/ui/ui_customization_unit.js +17 -16
  273. package/test/ui/ui_integration.js +30 -20
  274. package/test/ui/ui_unit.js +28 -29
  275. package/test/util/buffer_utils_unit.js +1 -1
  276. package/test/util/content_steering_manager_unit.js +427 -0
  277. package/test/util/id3_utils_unit.js +52 -0
  278. package/test/util/stream_utils_unit.js +207 -169
  279. package/test/util/ts_parser_unit.js +3 -3
  280. package/third_party/closure-uri/uri.js +13 -1
  281. package/ui/audio_language_selection.js +9 -2
  282. package/ui/controls.js +125 -0
  283. package/ui/externs/ui.js +24 -2
  284. package/ui/language_utils.js +43 -8
  285. package/ui/less/range_elements.less +33 -0
  286. package/ui/locales/en.json +1 -0
  287. package/ui/locales/es-419.json +1 -0
  288. package/ui/locales/es.json +1 -0
  289. package/ui/locales/source.json +4 -0
  290. package/ui/localization.js +10 -0
  291. package/ui/pip_button.js +22 -120
  292. package/ui/remote_button.js +203 -0
  293. package/ui/resolution_selection.js +47 -10
  294. package/ui/seek_bar.js +296 -3
  295. package/ui/text_selection.js +2 -1
  296. package/ui/ui.js +11 -4
  297. package/demo/common/message_ids.js +0 -309
  298. package/demo/locales/en.json +0 -288
  299. package/demo/locales/source.json +0 -1146
  300. package/externs/mux.js +0 -69
  301. package/lib/lcevc/lcevc_dil.js +0 -152
  302. package/lib/routing/node.js +0 -23
  303. package/lib/routing/payload.js +0 -43
  304. package/lib/routing/walker.js +0 -587
  305. package/lib/transmuxer/muxjs_transmuxer.js +0 -242
  306. package/test/routing/walker_unit.js +0 -504
  307. package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
@@ -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.
@@ -2569,8 +2611,8 @@ describe('DashParser Manifest', () => {
2569
2611
  '<MPD minBufferTime="PT75S" type="dynamic"',
2570
2612
  ' availabilityStartTime="1970-01-01T00:00:00Z">',
2571
2613
  ' <ServiceDescription id="0">',
2572
- ' <Latency max="2000" min="2000" referenceId="0" target="4000" />',
2573
- ' <PlaybackRate max="1.10" min="0.96" />',
2614
+ ' <Latency max="2000" min="1000" referenceId="0" target="4000" />',
2615
+ ' <PlaybackRate max="1.10" min="0.95" />',
2574
2616
  ' </ServiceDescription>',
2575
2617
  '</MPD>',
2576
2618
  ].join('\n');
@@ -2582,6 +2624,498 @@ describe('DashParser Manifest', () => {
2582
2624
 
2583
2625
  expect(manifest.serviceDescription.maxLatency).toBe(2);
2584
2626
  expect(manifest.serviceDescription.maxPlaybackRate).toBe(1.1);
2627
+ expect(manifest.serviceDescription.minLatency).toBe(1);
2628
+ expect(manifest.serviceDescription.minPlaybackRate).toBe(0.95);
2629
+ });
2630
+ });
2631
+
2632
+ it('parses urn:mpeg:dash:ssr:2023', async () => { // eslint-disable-line max-len
2633
+ const manifestText = [
2634
+ '<MPD minBufferTime="PT75S">',
2635
+ ' <Period id="1" duration="PT30S">',
2636
+ ' <AdaptationSet id="1" mimeType="video/mp4">',
2637
+ ' <Representation bandwidth="2" codecs="avc1.4d401f"',
2638
+ ' height="1080" width="1920">',
2639
+ ' <SegmentTemplate startNumber="1" media="l2-$Number$.mp4"',
2640
+ ' initialization="init.mp4" timescale="50" duration="100">',
2641
+ ' <SegmentTimeline>',
2642
+ ' <S t="0" d="100"/>',
2643
+ ' <S d="100"/>',
2644
+ ' </SegmentTimeline>',
2645
+ ' </SegmentTemplate>',
2646
+ ' </Representation>',
2647
+ ' </AdaptationSet>',
2648
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
2649
+ ' <EssentialProperty value="video_primary" ',
2650
+ ' schemeIdUri="urn:mpeg:dash:ssr:2023" />',
2651
+ ' <Representation bandwidth="1" codecs="avc1.4d401f"',
2652
+ ' height="720" width="1280">',
2653
+ ' <SegmentTemplate startNumber="1"',
2654
+ ' media="l-$Number$-p$SubNumber$.mp4"',
2655
+ ' initialization="init.mp4" timescale="50" duration="100">',
2656
+ ' <SegmentTimeline>',
2657
+ ' <S t="0" d="100" k="4"/>',
2658
+ ' <S d="100" k="4"/>',
2659
+ ' </SegmentTimeline>',
2660
+ ' </SegmentTemplate>',
2661
+ ' </Representation>',
2662
+ ' </AdaptationSet>',
2663
+ ' </Period>',
2664
+ '</MPD>',
2665
+ ].join('\n');
2666
+
2667
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2668
+ /** @type {shaka.extern.Manifest} */
2669
+ const manifest = await parser.start('dummy://foo', playerInterface);
2670
+ expect(manifest.variants.length).toBe(2);
2671
+
2672
+ const normalStream = manifest.variants[0].video;
2673
+ expect(normalStream.width).toBe(1920);
2674
+ expect(normalStream.height).toBe(1080);
2675
+ expect(normalStream.fastSwitching).toBe(false);
2676
+ await normalStream.createSegmentIndex();
2677
+ goog.asserts.assert(normalStream.segmentIndex != null,
2678
+ 'Null segmentIndex!');
2679
+
2680
+ const firstNormalReference = normalStream.segmentIndex.get(0);
2681
+ expect(firstNormalReference.partialReferences.length).toBe(0);
2682
+
2683
+ const stream = manifest.variants[1].video;
2684
+ expect(stream.width).toBe(1280);
2685
+ expect(stream.height).toBe(720);
2686
+ expect(stream.fastSwitching).toBe(true);
2687
+ await stream.createSegmentIndex();
2688
+ goog.asserts.assert(stream.segmentIndex != null,
2689
+ 'Null segmentIndex!');
2690
+
2691
+ const firstReference = stream.segmentIndex.get(0);
2692
+ expect(firstReference.partialReferences.length).toBe(4);
2693
+ });
2694
+
2695
+ describe('parses partial segments correctly', () => {
2696
+ it('whitout cadence', async () => {
2697
+ const manifestText = [
2698
+ '<MPD minBufferTime="PT75S">',
2699
+ ' <Period id="1" duration="PT30S">',
2700
+ ' <AdaptationSet id="1" mimeType="video/mp4">',
2701
+ ' <Representation bandwidth="1" codecs="avc1.4d401f">',
2702
+ ' <SegmentTemplate startNumber="1"',
2703
+ ' media="l-$Number$-p$SubNumber$.mp4"',
2704
+ ' initialization="init.mp4" timescale="50" duration="100">',
2705
+ ' <SegmentTimeline>',
2706
+ ' <S t="0" d="100" k="4"/>',
2707
+ ' <S d="100" k="4"/>',
2708
+ ' </SegmentTimeline>',
2709
+ ' </SegmentTemplate>',
2710
+ ' </Representation>',
2711
+ ' </AdaptationSet>',
2712
+ ' </Period>',
2713
+ '</MPD>',
2714
+ ].join('\n');
2715
+
2716
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2717
+ /** @type {shaka.extern.Manifest} */
2718
+ const manifest = await parser.start('dummy://foo', playerInterface);
2719
+ const stream = manifest.variants[0].video;
2720
+ await stream.createSegmentIndex();
2721
+ goog.asserts.assert(stream.segmentIndex != null, 'Null segmentIndex!');
2722
+
2723
+ const firstReference = stream.segmentIndex.get(0);
2724
+ expect(firstReference.startTime).toBe(0);
2725
+ expect(firstReference.endTime).toBe(2);
2726
+ expect(firstReference.getUris()).toEqual([]);
2727
+ expect(firstReference.partialReferences.length).toBe(4);
2728
+ const firstPartialReference = firstReference.partialReferences[0];
2729
+ expect(firstPartialReference.startTime).toBe(0);
2730
+ expect(firstPartialReference.endTime).toBe(0.5);
2731
+ expect(firstPartialReference.getUris())
2732
+ .toEqual(['dummy://foo/l-1-p1.mp4']);
2733
+ const secondPartialReference = firstReference.partialReferences[1];
2734
+ expect(secondPartialReference.startTime).toBe(0.5);
2735
+ expect(secondPartialReference.endTime).toBe(1);
2736
+ expect(secondPartialReference.getUris())
2737
+ .toEqual(['dummy://foo/l-1-p2.mp4']);
2738
+ const thirdPartialReference = firstReference.partialReferences[2];
2739
+ expect(thirdPartialReference.startTime).toBe(1);
2740
+ expect(thirdPartialReference.endTime).toBe(1.5);
2741
+ expect(thirdPartialReference.getUris())
2742
+ .toEqual(['dummy://foo/l-1-p3.mp4']);
2743
+ const fourthPartialReference = firstReference.partialReferences[3];
2744
+ expect(fourthPartialReference.startTime).toBe(1.5);
2745
+ expect(fourthPartialReference.endTime).toBe(2);
2746
+ expect(fourthPartialReference.getUris())
2747
+ .toEqual(['dummy://foo/l-1-p4.mp4']);
2748
+ });
2749
+
2750
+ it('with cadence equal to 1', async () => {
2751
+ const manifestText = [
2752
+ '<MPD minBufferTime="PT75S">',
2753
+ ' <Period id="1" duration="PT30S">',
2754
+ ' <AdaptationSet id="1" mimeType="video/mp4">',
2755
+ ' <Representation bandwidth="1" codecs="avc1.4d401f">',
2756
+ ' <SegmentTemplate startNumber="1"',
2757
+ ' media="l-$Number$-p$SubNumber$.mp4"',
2758
+ ' initialization="init.mp4" timescale="50" duration="100">',
2759
+ ' <SegmentTimeline>',
2760
+ ' <S t="0" d="100" k="4"/>',
2761
+ ' <S d="100" k="4"/>',
2762
+ ' </SegmentTimeline>',
2763
+ ' </SegmentTemplate>',
2764
+ ' <SegmentSequenceProperties>',
2765
+ ' <SAP type="1" cadence="1" />',
2766
+ ' </SegmentSequenceProperties>',
2767
+ ' </Representation>',
2768
+ ' </AdaptationSet>',
2769
+ ' </Period>',
2770
+ '</MPD>',
2771
+ ].join('\n');
2772
+
2773
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2774
+ /** @type {shaka.extern.Manifest} */
2775
+ const manifest = await parser.start('dummy://foo', playerInterface);
2776
+ const stream = manifest.variants[0].video;
2777
+ await stream.createSegmentIndex();
2778
+ goog.asserts.assert(stream.segmentIndex != null, 'Null segmentIndex!');
2779
+
2780
+ const firstReference = stream.segmentIndex.get(0);
2781
+ const firstPartialReference = firstReference.partialReferences[0];
2782
+ expect(firstPartialReference.isIndependent()).toBeTruthy();
2783
+ const secondPartialReference = firstReference.partialReferences[1];
2784
+ expect(secondPartialReference.isIndependent()).toBeTruthy();
2785
+ const thirdPartialReference = firstReference.partialReferences[2];
2786
+ expect(thirdPartialReference.isIndependent()).toBeTruthy();
2787
+ const fourthPartialReference = firstReference.partialReferences[3];
2788
+ expect(fourthPartialReference.isIndependent()).toBeTruthy();
2789
+ });
2790
+
2791
+ it('with cadence equal to 2', async () => {
2792
+ const manifestText = [
2793
+ '<MPD minBufferTime="PT75S">',
2794
+ ' <Period id="1" duration="PT30S">',
2795
+ ' <AdaptationSet id="1" mimeType="video/mp4">',
2796
+ ' <Representation bandwidth="1" codecs="avc1.4d401f">',
2797
+ ' <SegmentTemplate startNumber="1"',
2798
+ ' media="l-$Number$-p$SubNumber$.mp4"',
2799
+ ' initialization="init.mp4" timescale="50" duration="100">',
2800
+ ' <SegmentTimeline>',
2801
+ ' <S t="0" d="100" k="4"/>',
2802
+ ' <S d="100" k="4"/>',
2803
+ ' </SegmentTimeline>',
2804
+ ' </SegmentTemplate>',
2805
+ ' <SegmentSequenceProperties>',
2806
+ ' <SAP type="1" cadence="2" />',
2807
+ ' </SegmentSequenceProperties>',
2808
+ ' </Representation>',
2809
+ ' </AdaptationSet>',
2810
+ ' </Period>',
2811
+ '</MPD>',
2812
+ ].join('\n');
2813
+
2814
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2815
+ /** @type {shaka.extern.Manifest} */
2816
+ const manifest = await parser.start('dummy://foo', playerInterface);
2817
+ const stream = manifest.variants[0].video;
2818
+ await stream.createSegmentIndex();
2819
+ goog.asserts.assert(stream.segmentIndex != null, 'Null segmentIndex!');
2820
+
2821
+ const firstReference = stream.segmentIndex.get(0);
2822
+ const firstPartialReference = firstReference.partialReferences[0];
2823
+ expect(firstPartialReference.isIndependent()).toBeTruthy();
2824
+ const secondPartialReference = firstReference.partialReferences[1];
2825
+ expect(secondPartialReference.isIndependent()).toBeFalsy();
2826
+ const thirdPartialReference = firstReference.partialReferences[2];
2827
+ expect(thirdPartialReference.isIndependent()).toBeTruthy();
2828
+ const fourthPartialReference = firstReference.partialReferences[3];
2829
+ expect(fourthPartialReference.isIndependent()).toBeFalsy();
2830
+ });
2831
+ });
2832
+
2833
+ describe('supports ContentSteering', () => {
2834
+ it('with defaultServiceLocation', async () => {
2835
+ const manifestText = [
2836
+ '<MPD type="static">',
2837
+ ' <BaseURL serviceLocation="a">http://example.com/r0/</BaseURL>',
2838
+ ' <BaseURL serviceLocation="b">http://example.com/r1/</BaseURL>',
2839
+ ' <ContentSteering defaultServiceLocation="a,b" ',
2840
+ 'queryBeforeStart="true">http://contentsteering</ContentSteering>',
2841
+ ' <Period id="1" duration="PT30S">',
2842
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
2843
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
2844
+ ' <SegmentTimeline>',
2845
+ ' <S t="0" d="30" />',
2846
+ ' </SegmentTimeline>',
2847
+ ' </SegmentTemplate>',
2848
+ ' <Representation id="video-sd" width="640" height="480">',
2849
+ ' </Representation>',
2850
+ ' </AdaptationSet>',
2851
+ ' </Period>',
2852
+ '</MPD>',
2853
+ ].join('\n');
2854
+
2855
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2856
+
2857
+ const contentSteering = JSON.stringify({
2858
+ 'VERSION': 1,
2859
+ 'TTL': 1,
2860
+ 'RELOAD-URI': 'http://contentsteering/update',
2861
+ 'PATHWAY-PRIORITY': [],
2862
+ });
2863
+
2864
+ fakeNetEngine.setResponseText('http://contentsteering', contentSteering);
2865
+
2866
+ /** @type {shaka.extern.Manifest} */
2867
+ const manifest = await parser.start('dummy://foo', playerInterface);
2868
+
2869
+ const video0 = manifest.variants[0].video;
2870
+ await video0.createSegmentIndex();
2871
+ goog.asserts.assert(video0.segmentIndex, 'Null segmentIndex!');
2872
+ const segment0 = Array.from(video0.segmentIndex)[0];
2873
+ const uri0 = segment0.getUris()[0];
2874
+ const uri1 = segment0.getUris()[1];
2875
+
2876
+ expect(uri0).toBe('http://example.com/r0/1.mp4');
2877
+ expect(uri1).toBe('http://example.com/r1/1.mp4');
2878
+ });
2879
+
2880
+ it('without defaultServiceLocation', async () => {
2881
+ const manifestText = [
2882
+ '<MPD type="static">',
2883
+ ' <BaseURL serviceLocation="a">http://example.com/r0/</BaseURL>',
2884
+ ' <BaseURL serviceLocation="b">http://example.com/r1/</BaseURL>',
2885
+ ' <ContentSteering',
2886
+ 'queryBeforeStart="true">http://contentsteering</ContentSteering>',
2887
+ ' <Period id="1" duration="PT30S">',
2888
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
2889
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
2890
+ ' <SegmentTimeline>',
2891
+ ' <S t="0" d="30" />',
2892
+ ' </SegmentTimeline>',
2893
+ ' </SegmentTemplate>',
2894
+ ' <Representation id="video-sd" width="640" height="480">',
2895
+ ' </Representation>',
2896
+ ' </AdaptationSet>',
2897
+ ' </Period>',
2898
+ '</MPD>',
2899
+ ].join('\n');
2900
+
2901
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2902
+
2903
+ const contentSteering = JSON.stringify({
2904
+ 'VERSION': 1,
2905
+ 'TTL': 1,
2906
+ 'RELOAD-URI': 'http://contentsteering/update',
2907
+ 'PATHWAY-PRIORITY': [
2908
+ 'b',
2909
+ 'a',
2910
+ ],
2911
+ });
2912
+
2913
+ fakeNetEngine.setResponseText('http://contentsteering', contentSteering);
2914
+
2915
+ /** @type {shaka.extern.Manifest} */
2916
+ const manifest = await parser.start('dummy://foo', playerInterface);
2917
+
2918
+ const video0 = manifest.variants[0].video;
2919
+ await video0.createSegmentIndex();
2920
+ goog.asserts.assert(video0.segmentIndex, 'Null segmentIndex!');
2921
+ const segment0 = Array.from(video0.segmentIndex)[0];
2922
+ const uri0 = segment0.getUris()[0];
2923
+ const uri1 = segment0.getUris()[1];
2924
+
2925
+ expect(uri0).toBe('http://example.com/r1/1.mp4');
2926
+ expect(uri1).toBe('http://example.com/r0/1.mp4');
2927
+ });
2928
+
2929
+ it('with queryBeforeStart', async () => {
2930
+ const manifestText = [
2931
+ '<MPD type="static">',
2932
+ ' <BaseURL serviceLocation="a">http://example.com/r0/</BaseURL>',
2933
+ ' <BaseURL serviceLocation="b">http://example.com/r1/</BaseURL>',
2934
+ ' <ContentSteering defaultServiceLocation="b" ',
2935
+ 'queryBeforeStart="true">http://contentsteering</ContentSteering>',
2936
+ ' <Period id="1" duration="PT30S">',
2937
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
2938
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
2939
+ ' <SegmentTimeline>',
2940
+ ' <S t="0" d="30" />',
2941
+ ' </SegmentTimeline>',
2942
+ ' </SegmentTemplate>',
2943
+ ' <Representation id="video-sd" width="640" height="480">',
2944
+ ' </Representation>',
2945
+ ' </AdaptationSet>',
2946
+ ' </Period>',
2947
+ '</MPD>',
2948
+ ].join('\n');
2949
+
2950
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2951
+
2952
+ const contentSteering = JSON.stringify({
2953
+ 'VERSION': 1,
2954
+ 'TTL': 1,
2955
+ 'RELOAD-URI': 'http://contentsteering/update',
2956
+ 'PATHWAY-PRIORITY': [
2957
+ 'a',
2958
+ ],
2959
+ });
2960
+
2961
+ fakeNetEngine.setResponseText('http://contentsteering', contentSteering);
2962
+
2963
+ /** @type {shaka.extern.Manifest} */
2964
+ const manifest = await parser.start('dummy://foo', playerInterface);
2965
+
2966
+ const video0 = manifest.variants[0].video;
2967
+ await video0.createSegmentIndex();
2968
+ goog.asserts.assert(video0.segmentIndex, 'Null segmentIndex!');
2969
+ const segment0 = Array.from(video0.segmentIndex)[0];
2970
+ expect(segment0.getUris().length).toBe(1);
2971
+ const uri0 = segment0.getUris()[0];
2972
+
2973
+ expect(uri0).toBe('http://example.com/r0/1.mp4');
2974
+ });
2975
+
2976
+ it('without queryBeforeStart', async () => {
2977
+ const manifestText = [
2978
+ '<MPD type="static">',
2979
+ ' <BaseURL serviceLocation="a">http://example.com/r0/</BaseURL>',
2980
+ ' <BaseURL serviceLocation="b">http://example.com/r1/</BaseURL>',
2981
+ ' <ContentSteering defaultServiceLocation="b">',
2982
+ 'http://contentsteering</ContentSteering>',
2983
+ ' <Period id="1" duration="PT30S">',
2984
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
2985
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
2986
+ ' <SegmentTimeline>',
2987
+ ' <S t="0" d="30" />',
2988
+ ' </SegmentTimeline>',
2989
+ ' </SegmentTemplate>',
2990
+ ' <Representation id="video-sd" width="640" height="480">',
2991
+ ' </Representation>',
2992
+ ' </AdaptationSet>',
2993
+ ' </Period>',
2994
+ '</MPD>',
2995
+ ].join('\n');
2996
+
2997
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
2998
+
2999
+ fakeNetEngine.setResponseText('http://contentsteering', 'foo');
3000
+
3001
+ /** @type {shaka.extern.Manifest} */
3002
+ const manifest = await parser.start('dummy://foo', playerInterface);
3003
+
3004
+ const video0 = manifest.variants[0].video;
3005
+ await video0.createSegmentIndex();
3006
+ goog.asserts.assert(video0.segmentIndex, 'Null segmentIndex!');
3007
+ const segment0 = Array.from(video0.segmentIndex)[0];
3008
+ expect(segment0.getUris().length).toBe(1);
3009
+ const uri0 = segment0.getUris()[0];
3010
+
3011
+ expect(uri0).toBe('http://example.com/r1/1.mp4');
3012
+ });
3013
+
3014
+ it('without serviceLocation in BaseURL', async () => {
3015
+ const manifestText = [
3016
+ '<MPD type="static">',
3017
+ ' <BaseURL>http://example.com/r0/</BaseURL>',
3018
+ ' <BaseURL>http://example.com/r1/</BaseURL>',
3019
+ ' <ContentSteering',
3020
+ 'queryBeforeStart="true">http://contentsteering</ContentSteering>',
3021
+ ' <Period id="1" duration="PT30S">',
3022
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
3023
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
3024
+ ' <SegmentTimeline>',
3025
+ ' <S t="0" d="30" />',
3026
+ ' </SegmentTimeline>',
3027
+ ' </SegmentTemplate>',
3028
+ ' <Representation id="video-sd" width="640" height="480">',
3029
+ ' </Representation>',
3030
+ ' </AdaptationSet>',
3031
+ ' </Period>',
3032
+ '</MPD>',
3033
+ ].join('\n');
3034
+
3035
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
3036
+
3037
+ fakeNetEngine.setResponseText('http://contentsteering', 'foo');
3038
+
3039
+ /** @type {shaka.extern.Manifest} */
3040
+ const manifest = await parser.start('dummy://foo', playerInterface);
3041
+
3042
+ const video0 = manifest.variants[0].video;
3043
+ await video0.createSegmentIndex();
3044
+ goog.asserts.assert(video0.segmentIndex, 'Null segmentIndex!');
3045
+ const segment0 = Array.from(video0.segmentIndex)[0];
3046
+ const uri0 = segment0.getUris()[0];
3047
+ const uri1 = segment0.getUris()[1];
3048
+
3049
+ expect(uri0).toBe('http://example.com/r0/1.mp4');
3050
+ expect(uri1).toBe('http://example.com/r1/1.mp4');
3051
+ });
3052
+
3053
+ it('specify MPD BaseURL and AdaptationSet BaseURL', async () => {
3054
+ const manifestText = [
3055
+ '<MPD type="static">',
3056
+ ' <BaseURL serviceLocation="a">http://example.com/r0/</BaseURL>',
3057
+ ' <BaseURL serviceLocation="b">http://example.com/r1/</BaseURL>',
3058
+ ' <ContentSteering defaultServiceLocation="a,b" ',
3059
+ 'queryBeforeStart="true">http://contentsteering</ContentSteering>',
3060
+ ' <Period id="1" duration="PT30S">',
3061
+ ' <AdaptationSet id="2" mimeType="video/mp4">',
3062
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
3063
+ ' <SegmentTimeline>',
3064
+ ' <S t="0" d="30" />',
3065
+ ' </SegmentTimeline>',
3066
+ ' </SegmentTemplate>',
3067
+ ' <Representation id="video-sd" width="640" height="480">',
3068
+ ' </Representation>',
3069
+ ' </AdaptationSet>',
3070
+ ' <AdaptationSet id="3" mimeType="audio/mp4">',
3071
+ ' <BaseURL serviceLocation="c">http://example.foo/r0/</BaseURL>',
3072
+ ' <BaseURL serviceLocation="d">http://example.foo/r1/</BaseURL>',
3073
+ ' <SegmentTemplate media="$Number$.mp4" startNumber="1">',
3074
+ ' <SegmentTimeline>',
3075
+ ' <S t="0" d="30" />',
3076
+ ' </SegmentTimeline>',
3077
+ ' </SegmentTemplate>',
3078
+ ' <Representation id="audio">',
3079
+ ' </Representation>',
3080
+ ' </AdaptationSet>',
3081
+ ' </Period>',
3082
+ '</MPD>',
3083
+ ].join('\n');
3084
+
3085
+ fakeNetEngine.setResponseText('dummy://foo', manifestText);
3086
+
3087
+ const contentSteering = JSON.stringify({
3088
+ 'VERSION': 1,
3089
+ 'TTL': 1,
3090
+ 'RELOAD-URI': 'http://contentsteering/update',
3091
+ 'PATHWAY-PRIORITY': [
3092
+ 'a',
3093
+ 'c',
3094
+ ],
3095
+ });
3096
+
3097
+ fakeNetEngine.setResponseText('http://contentsteering', contentSteering);
3098
+
3099
+ /** @type {shaka.extern.Manifest} */
3100
+ const manifest = await parser.start('dummy://foo', playerInterface);
3101
+
3102
+ const video0 = manifest.variants[0].video;
3103
+ await video0.createSegmentIndex();
3104
+ goog.asserts.assert(video0.segmentIndex, 'Null segmentIndex!');
3105
+ const videoSegment0 = Array.from(video0.segmentIndex)[0];
3106
+ expect(videoSegment0.getUris().length).toBe(1);
3107
+ const videoUri0 = videoSegment0.getUris()[0];
3108
+
3109
+ expect(videoUri0).toBe('http://example.com/r0/1.mp4');
3110
+
3111
+ const audio0 = manifest.variants[0].audio;
3112
+ await audio0.createSegmentIndex();
3113
+ goog.asserts.assert(audio0.segmentIndex, 'Null segmentIndex!');
3114
+ const audioSegment0 = Array.from(audio0.segmentIndex)[0];
3115
+ expect(audioSegment0.getUris().length).toBe(1);
3116
+ const audioUri0 = audioSegment0.getUris()[0];
3117
+
3118
+ expect(audioUri0).toBe('http://example.foo/r0/1.mp4');
2585
3119
  });
2586
3120
  });
2587
3121
  });
@@ -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