shaka-player 4.3.9 → 4.4.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 (321) hide show
  1. package/.github/workflows/build-and-test.yaml +11 -18
  2. package/.github/workflows/compute-incremental-coverage.py +3 -0
  3. package/.github/workflows/release-please.yaml +7 -0
  4. package/.github/workflows/selenium-lab-tests.yaml +45 -10
  5. package/AUTHORS +9 -0
  6. package/CHANGELOG.md +295 -190
  7. package/CONTRIBUTORS +8 -0
  8. package/LICENSE +32 -0
  9. package/README.md +63 -10
  10. package/demo/autoTemplate.txt +40 -5
  11. package/demo/close_button.js +11 -0
  12. package/demo/common/asset.js +13 -1
  13. package/demo/common/assets.js +112 -28
  14. package/demo/common/message_ids.js +25 -1
  15. package/demo/config.js +69 -10
  16. package/demo/customWarning.txt +2 -2
  17. package/demo/index.html +3 -1
  18. package/demo/locales/en.json +26 -2
  19. package/demo/locales/source.json +105 -9
  20. package/demo/main.js +57 -9
  21. package/demo/search.js +3 -1
  22. package/demo/service_worker.js +3 -0
  23. package/dist/controls.css +1 -1
  24. package/dist/controls.css.map +1 -1
  25. package/dist/demo.compiled.debug.js +132 -118
  26. package/dist/demo.compiled.debug.map +3 -3
  27. package/dist/demo.compiled.js +132 -118
  28. package/dist/demo.compiled.map +3 -3
  29. package/dist/deps.js +46 -28
  30. package/dist/locales.js +31 -31
  31. package/dist/receiver.compiled.debug.js +60 -52
  32. package/dist/receiver.compiled.debug.map +3 -3
  33. package/dist/receiver.compiled.js +60 -52
  34. package/dist/receiver.compiled.map +3 -3
  35. package/dist/shaka-player.compiled.d.ts +676 -391
  36. package/dist/shaka-player.compiled.debug.d.ts +676 -391
  37. package/dist/shaka-player.compiled.debug.externs.js +1188 -616
  38. package/dist/shaka-player.compiled.debug.js +1046 -700
  39. package/dist/shaka-player.compiled.debug.map +4 -4
  40. package/dist/shaka-player.compiled.externs.js +1188 -616
  41. package/dist/shaka-player.compiled.js +1094 -933
  42. package/dist/shaka-player.compiled.map +4 -4
  43. package/dist/shaka-player.ui.d.ts +677 -392
  44. package/dist/shaka-player.ui.debug.d.ts +677 -392
  45. package/dist/shaka-player.ui.debug.externs.js +1023 -451
  46. package/dist/shaka-player.ui.debug.js +1101 -738
  47. package/dist/shaka-player.ui.debug.map +4 -4
  48. package/dist/shaka-player.ui.externs.js +1023 -451
  49. package/dist/shaka-player.ui.js +1244 -1071
  50. package/dist/shaka-player.ui.map +4 -4
  51. package/docs/tutorials/ad_monetization.md +15 -1
  52. package/docs/tutorials/application-level-redirects.md +1 -1
  53. package/docs/tutorials/config.md +9 -5
  54. package/docs/tutorials/drm-config.md +61 -0
  55. package/docs/tutorials/fairplay.md +19 -4
  56. package/docs/tutorials/license-server-auth.md +4 -4
  57. package/docs/tutorials/license-wrapping.md +2 -2
  58. package/docs/tutorials/ui-customization.md +7 -3
  59. package/docs/tutorials/ui.md +7 -7
  60. package/docs/tutorials/upgrade.md +3 -0
  61. package/externs/ima.js +123 -2
  62. package/externs/isoboxer.js +217 -0
  63. package/externs/mediakeys.js +18 -0
  64. package/externs/mux.js +1 -105
  65. package/externs/pictureinpicture.js +48 -0
  66. package/externs/shaka/ads.js +61 -1
  67. package/externs/shaka/cea.js +110 -0
  68. package/externs/shaka/codecs.js +32 -0
  69. package/externs/shaka/manifest.js +101 -1
  70. package/externs/shaka/manifest_parser.js +0 -10
  71. package/externs/shaka/net.js +36 -7
  72. package/externs/shaka/offline.js +8 -1
  73. package/externs/shaka/player.js +220 -21
  74. package/externs/shaka/text.js +1 -382
  75. package/externs/shaka/transmuxer.js +59 -0
  76. package/karma.conf.js +15 -0
  77. package/lib/abr/simple_abr_manager.js +6 -3
  78. package/lib/ads/ad_manager.js +60 -2
  79. package/lib/ads/client_side_ad.js +86 -0
  80. package/lib/ads/client_side_ad_manager.js +93 -5
  81. package/lib/ads/server_side_ad.js +86 -0
  82. package/lib/ads/server_side_ad_manager.js +13 -0
  83. package/lib/cast/cast_utils.js +1 -0
  84. package/lib/cea/cea608_data_channel.js +24 -14
  85. package/lib/cea/cea608_memory.js +5 -2
  86. package/lib/cea/cea708_service.js +8 -9
  87. package/lib/cea/cea708_window.js +1 -2
  88. package/lib/cea/cea_decoder.js +23 -6
  89. package/lib/cea/cea_utils.js +25 -2
  90. package/lib/cea/dummy_caption_decoder.js +21 -0
  91. package/lib/cea/dummy_cea_parser.js +1 -3
  92. package/lib/cea/mp4_cea_parser.js +15 -10
  93. package/lib/cea/ts_cea_parser.js +69 -0
  94. package/lib/dash/content_protection.js +32 -2
  95. package/lib/dash/dash_parser.js +93 -31
  96. package/lib/dash/mpd_utils.js +6 -25
  97. package/lib/dash/segment_base.js +12 -14
  98. package/lib/dash/segment_list.js +10 -6
  99. package/lib/dash/segment_template.js +349 -32
  100. package/lib/dependencies/all.js +8 -0
  101. package/lib/hls/hls_classes.js +33 -8
  102. package/lib/hls/hls_parser.js +805 -191
  103. package/lib/hls/manifest_text_parser.js +4 -14
  104. package/lib/media/adaptation_set_criteria.js +43 -3
  105. package/lib/media/closed_caption_parser.js +74 -12
  106. package/lib/media/drm_engine.js +189 -49
  107. package/lib/media/gap_jumping_controller.js +1 -1
  108. package/lib/media/manifest_parser.js +34 -0
  109. package/lib/media/media_source_capabilities.js +10 -0
  110. package/lib/media/media_source_engine.js +475 -231
  111. package/lib/media/playhead.js +1 -1
  112. package/lib/media/presentation_timeline.js +62 -0
  113. package/lib/media/segment_index.js +50 -14
  114. package/lib/media/segment_prefetch.js +277 -0
  115. package/lib/media/segment_reference.js +70 -4
  116. package/lib/media/streaming_engine.js +258 -81
  117. package/lib/media/video_wrapper.js +15 -7
  118. package/lib/mss/content_protection.js +353 -0
  119. package/lib/mss/mss_parser.js +1081 -0
  120. package/lib/net/networking_engine.js +60 -10
  121. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  122. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  123. package/lib/offline/manifest_converter.js +6 -0
  124. package/lib/offline/storage.js +2 -4
  125. package/lib/player.js +309 -105
  126. package/lib/polyfill/media_capabilities.js +43 -3
  127. package/lib/polyfill/patchedmediakeys_apple.js +5 -0
  128. package/lib/polyfill/patchedmediakeys_nop.js +5 -0
  129. package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
  130. package/lib/text/cue.js +208 -130
  131. package/lib/text/lrc_text_parser.js +2 -2
  132. package/lib/text/mp4_vtt_parser.js +2 -2
  133. package/lib/text/sbv_text_parser.js +1 -1
  134. package/lib/text/simple_text_displayer.js +2 -1
  135. package/lib/text/srt_text_parser.js +9 -1
  136. package/lib/text/ssa_text_parser.js +2 -2
  137. package/lib/text/text_engine.js +3 -21
  138. package/lib/text/text_utils.js +71 -20
  139. package/lib/text/ui_text_displayer.js +14 -14
  140. package/lib/text/vtt_text_parser.js +22 -14
  141. package/lib/transmuxer/aac_transmuxer.js +224 -0
  142. package/lib/transmuxer/ac3.js +142 -0
  143. package/lib/transmuxer/ac3_transmuxer.js +212 -0
  144. package/lib/transmuxer/adts.js +232 -0
  145. package/lib/transmuxer/ec3.js +103 -0
  146. package/lib/transmuxer/ec3_transmuxer.js +212 -0
  147. package/lib/transmuxer/h264.js +324 -0
  148. package/lib/transmuxer/mp3_transmuxer.js +204 -0
  149. package/lib/transmuxer/mpeg_audio.js +196 -0
  150. package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
  151. package/lib/transmuxer/mss_transmuxer.js +389 -0
  152. package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
  153. package/lib/transmuxer/transmuxer_engine.js +161 -0
  154. package/lib/transmuxer/ts_transmuxer.js +738 -0
  155. package/lib/util/cmcd_manager.js +131 -71
  156. package/lib/util/error.js +62 -26
  157. package/lib/util/exp_golomb.js +220 -0
  158. package/lib/util/fairplay_utils.js +64 -13
  159. package/lib/util/id3_utils.js +56 -3
  160. package/lib/util/language_utils.js +11 -8
  161. package/lib/util/manifest_parser_utils.js +3 -0
  162. package/lib/util/mime_utils.js +44 -7
  163. package/lib/util/mp4_box_parsers.js +233 -5
  164. package/lib/util/mp4_generator.js +1381 -0
  165. package/lib/util/periods.js +40 -34
  166. package/lib/util/platform.js +25 -3
  167. package/lib/util/player_configuration.js +38 -1
  168. package/lib/util/stream_utils.js +138 -27
  169. package/lib/util/text_parser.js +1 -1
  170. package/lib/util/ts_parser.js +470 -47
  171. package/lib/util/xml_utils.js +16 -3
  172. package/maintained-branches.md +2 -2
  173. package/package.json +4 -2
  174. package/roadmap.md +21 -6
  175. package/shaka-player.uncompiled.js +18 -0
  176. package/test/abr/simple_abr_manager_unit.js +32 -4
  177. package/test/ads/ad_manager_unit.js +18 -2
  178. package/test/cast/cast_utils_unit.js +7 -2
  179. package/test/cea/cea608_memory_unit.js +24 -0
  180. package/test/cea/cea_decoder_unit.js +33 -0
  181. package/test/dash/dash_parser_content_protection_unit.js +93 -3
  182. package/test/dash/dash_parser_live_unit.js +56 -13
  183. package/test/dash/dash_parser_manifest_unit.js +70 -2
  184. package/test/dash/dash_parser_segment_base_unit.js +14 -9
  185. package/test/dash/dash_parser_segment_template_unit.js +286 -6
  186. package/test/demo/demo_unit.js +5 -1
  187. package/test/hls/hls_live_unit.js +188 -28
  188. package/test/hls/hls_parser_unit.js +250 -109
  189. package/test/hls/manifest_text_parser_unit.js +18 -13
  190. package/test/media/adaptation_set_criteria_unit.js +46 -14
  191. package/test/media/adaptation_set_unit.js +2 -0
  192. package/test/media/drm_engine_integration.js +11 -8
  193. package/test/media/drm_engine_unit.js +220 -7
  194. package/test/media/media_source_engine_integration.js +122 -38
  195. package/test/media/media_source_engine_unit.js +133 -153
  196. package/test/media/playhead_unit.js +3 -0
  197. package/test/media/presentation_timeline_unit.js +51 -0
  198. package/test/media/segment_index_unit.js +52 -0
  199. package/test/media/segment_prefetch_unit.js +243 -0
  200. package/test/media/streaming_engine_integration.js +9 -3
  201. package/test/media/streaming_engine_unit.js +440 -59
  202. package/test/mss/mss_parser_content_protection_unit.js +49 -0
  203. package/test/mss/mss_parser_unit.js +472 -0
  204. package/test/mss/mss_player_integration.js +123 -0
  205. package/test/offline/manifest_convert_unit.js +9 -0
  206. package/test/offline/storage_integration.js +6 -1
  207. package/test/player_integration.js +4 -1
  208. package/test/player_unit.js +386 -133
  209. package/test/polyfill/media_capabilities_unit.js +18 -0
  210. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  211. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  212. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  213. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  214. package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
  215. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
  216. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  217. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  218. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  219. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  220. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  221. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  222. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  223. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  224. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
  225. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  226. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  227. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  228. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  229. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  230. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  231. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  232. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  233. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
  234. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
  235. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  236. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  237. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  238. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  239. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
  240. package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
  241. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  242. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  243. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  244. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  245. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  246. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  247. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  248. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  249. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  250. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  251. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  252. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  253. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  254. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  255. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
  256. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  257. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  258. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  259. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  260. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  261. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  262. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
  263. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  264. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  265. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  266. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  267. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  268. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  269. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
  270. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
  271. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  272. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  273. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  274. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  275. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
  276. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  277. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  278. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  279. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  280. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  281. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  282. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
  283. package/test/test/boot.js +7 -2
  284. package/test/test/util/fake_ad.js +99 -0
  285. package/test/test/util/fake_ad_manager.js +7 -1
  286. package/test/test/util/fake_networking_engine.js +41 -14
  287. package/test/test/util/fake_segment_prefetch.js +81 -0
  288. package/test/test/util/manifest_generator.js +19 -5
  289. package/test/test/util/mss_parser_util.js +115 -0
  290. package/test/test/util/offline_utils.js +1 -0
  291. package/test/test/util/simple_fakes.js +12 -3
  292. package/test/test/util/streaming_engine_util.js +14 -4
  293. package/test/test/util/ttml_utils.js +2 -2
  294. package/test/test/util/ui_utils.js +5 -1
  295. package/test/text/cue_integration.js +1 -1
  296. package/test/text/srt_text_parser_unit.js +78 -0
  297. package/test/text/text_engine_unit.js +17 -8
  298. package/test/text/ui_text_displayer_unit.js +4 -4
  299. package/test/text/vtt_text_parser_unit.js +59 -40
  300. package/test/text/web_vtt_generator_unit.js +9 -3
  301. package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
  302. package/test/transmuxer/transmuxer_engine_integration.js +60 -0
  303. package/test/transmuxer/transmuxer_integration.js +296 -0
  304. package/test/util/cmcd_manager_unit.js +162 -13
  305. package/test/util/language_utils_unit.js +9 -2
  306. package/test/util/mp4_box_parsers_unit.js +39 -4
  307. package/test/util/periods_unit.js +34 -26
  308. package/test/util/stream_utils_unit.js +60 -107
  309. package/ui/controls.js +19 -1
  310. package/ui/controls.less +1 -0
  311. package/ui/externs/ui.js +13 -3
  312. package/ui/language_utils.js +15 -0
  313. package/ui/less/thumbnails.less +26 -0
  314. package/ui/locales/oc.json +42 -0
  315. package/ui/pip_button.js +83 -2
  316. package/ui/range_element.js +15 -0
  317. package/ui/resolution_selection.js +9 -2
  318. package/ui/seek_bar.js +230 -1
  319. package/ui/ui.js +5 -0
  320. package/lib/cea/i_caption_decoder.js +0 -51
  321. package/lib/cea/i_cea_parser.js +0 -68
@@ -19,7 +19,6 @@ goog.require('shaka.media.PresentationTimeline');
19
19
  goog.require('shaka.media.SegmentIndex');
20
20
  goog.require('shaka.net.NetworkingEngine');
21
21
  goog.require('shaka.text.TextEngine');
22
- goog.require('shaka.util.CmcdManager');
23
22
  goog.require('shaka.util.Error');
24
23
  goog.require('shaka.util.Functional');
25
24
  goog.require('shaka.util.LanguageUtils');
@@ -222,15 +221,12 @@ shaka.dash.DashParser = class {
222
221
  */
223
222
  async requestManifest_() {
224
223
  const requestType = shaka.net.NetworkingEngine.RequestType.MANIFEST;
224
+ const type = shaka.net.NetworkingEngine.AdvancedRequestType.MPD;
225
225
  const request = shaka.net.NetworkingEngine.makeRequest(
226
226
  this.manifestUris_, this.config_.retryParameters);
227
227
  const networkingEngine = this.playerInterface_.networkingEngine;
228
-
229
- const format = shaka.util.CmcdManager.StreamingFormat.DASH;
230
- this.playerInterface_.modifyManifestRequest(request, {format: format});
231
-
232
228
  const startTime = Date.now();
233
- const operation = networkingEngine.request(requestType, request);
229
+ const operation = networkingEngine.request(requestType, request, {type});
234
230
  this.operationManager_.manage(operation);
235
231
 
236
232
  const response = await operation.promise;
@@ -489,6 +485,18 @@ shaka.dash.DashParser = class {
489
485
 
490
486
  await this.periodCombiner_.combinePeriods(periods, context.dynamic);
491
487
 
488
+ // Set minBufferTime to 0 for low-latency DASH live stream to achieve the
489
+ // best latency
490
+ if (this.lowLatencyMode_) {
491
+ minBufferTime = 0;
492
+ }
493
+
494
+ // Set updatePeriod_ to minTotalAvailabilityTimeOffset_ to achieve the best
495
+ // latency in LL streams
496
+ if (this.lowLatencyMode_ && this.minTotalAvailabilityTimeOffset_) {
497
+ this.updatePeriod_ = this.minTotalAvailabilityTimeOffset_;
498
+ }
499
+
492
500
  // These steps are not done on manifest update.
493
501
  if (!this.manifest_) {
494
502
  this.manifest_ = {
@@ -499,6 +507,9 @@ shaka.dash.DashParser = class {
499
507
  offlineSessionIds: [],
500
508
  minBufferTime: minBufferTime || 0,
501
509
  sequenceMode: this.config_.dash.sequenceMode,
510
+ ignoreManifestTimestampsInSegmentsMode: false,
511
+ type: shaka.media.ManifestParser.DASH,
512
+ serviceDescription: this.parseServiceDescription_(mpd),
502
513
  };
503
514
 
504
515
  // We only need to do clock sync when we're using presentation start
@@ -537,6 +548,39 @@ shaka.dash.DashParser = class {
537
548
  this.playerInterface_.makeTextStreamsForClosedCaptions(this.manifest_);
538
549
  }
539
550
 
551
+ /**
552
+ * Reads maxLatency and maxPlaybackRate properties from service
553
+ * description element.
554
+ *
555
+ * @param {!Element} mpd
556
+ * @return {?shaka.extern.ServiceDescription}
557
+ * @private
558
+ */
559
+ parseServiceDescription_(mpd) {
560
+ const XmlUtils = shaka.util.XmlUtils;
561
+ const elem = XmlUtils.findChild(mpd, 'ServiceDescription');
562
+
563
+ if (!elem ) {
564
+ return null;
565
+ }
566
+
567
+ const latencyNode = XmlUtils.findChild(elem, 'Latency');
568
+ const playbackRateNode = XmlUtils.findChild(elem, 'PlaybackRate');
569
+
570
+ if ((latencyNode && latencyNode.getAttribute('max')) || playbackRateNode) {
571
+ const maxLatency = latencyNode && latencyNode.getAttribute('max') ?
572
+ parseInt(latencyNode.getAttribute('max'), 10) / 1000 :
573
+ null;
574
+ const maxPlaybackRate = playbackRateNode ?
575
+ parseFloat(playbackRateNode.getAttribute('max')) :
576
+ null;
577
+
578
+ return {maxLatency, maxPlaybackRate};
579
+ }
580
+
581
+ return null;
582
+ }
583
+
540
584
  /**
541
585
  * Reads and parses the periods from the manifest. This first does some
542
586
  * partial parsing so the start and duration is available when parsing
@@ -546,7 +590,7 @@ shaka.dash.DashParser = class {
546
590
  * @param {!Array.<string>} baseUris
547
591
  * @param {!Element} mpd
548
592
  * @return {{
549
- * periods: !Array.<shaka.util.PeriodCombiner.Period>,
593
+ * periods: !Array.<shaka.extern.Period>,
550
594
  * duration: ?number,
551
595
  * durationDerivedFromPeriods: boolean
552
596
  * }}
@@ -698,7 +742,7 @@ shaka.dash.DashParser = class {
698
742
  * @param {shaka.dash.DashParser.Context} context
699
743
  * @param {!Array.<string>} baseUris
700
744
  * @param {shaka.dash.DashParser.PeriodInfo} periodInfo
701
- * @return {shaka.util.PeriodCombiner.Period}
745
+ * @return {shaka.extern.Period}
702
746
  * @private
703
747
  */
704
748
  parsePeriod_(context, baseUris, periodInfo) {
@@ -950,6 +994,8 @@ shaka.dash.DashParser = class {
950
994
  const accessibilities = XmlUtils.findChildren(elem, 'Accessibility');
951
995
  const LanguageUtils = shaka.util.LanguageUtils;
952
996
  const closedCaptions = new Map();
997
+ /** @type {?shaka.media.ManifestParser.AccessibilityPurpose} */
998
+ let accessibilityPurpose;
953
999
  for (const prop of accessibilities) {
954
1000
  const schemeId = prop.getAttribute('schemeIdUri');
955
1001
  const value = prop.getAttribute('value');
@@ -1032,6 +1078,15 @@ shaka.dash.DashParser = class {
1032
1078
  kind = ManifestParserUtils.TextStreamKind.CLOSED_CAPTION;
1033
1079
  }
1034
1080
  }
1081
+ } else if (schemeId == 'urn:tva:metadata:cs:AudioPurposeCS:2007') {
1082
+ // See DASH DVB Document A168 Rev.6 Table 5.
1083
+ if (value == '1') {
1084
+ accessibilityPurpose =
1085
+ shaka.media.ManifestParser.AccessibilityPurpose.VISUALLY_IMPAIRED;
1086
+ } else if (value == '2') {
1087
+ accessibilityPurpose =
1088
+ shaka.media.ManifestParser.AccessibilityPurpose.HARD_OF_HEARING;
1089
+ }
1035
1090
  }
1036
1091
  }
1037
1092
 
@@ -1053,8 +1108,8 @@ shaka.dash.DashParser = class {
1053
1108
  this.config_.dash.ignoreDrmInfo,
1054
1109
  this.config_.dash.keySystemsByURI);
1055
1110
 
1056
- const language =
1057
- shaka.util.LanguageUtils.normalize(elem.getAttribute('lang') || 'und');
1111
+ const language = shaka.util.LanguageUtils.normalize(
1112
+ context.adaptationSet.language || 'und');
1058
1113
 
1059
1114
  // This attribute is currently non-standard, but it is supported by Kaltura.
1060
1115
  let label = elem.getAttribute('label');
@@ -1074,7 +1129,7 @@ shaka.dash.DashParser = class {
1074
1129
  const streams = representations.map((representation) => {
1075
1130
  const parsedRepresentation = this.parseRepresentation_(context,
1076
1131
  contentProtection, kind, language, label, main, roleValues,
1077
- closedCaptions, representation);
1132
+ closedCaptions, representation, accessibilityPurpose);
1078
1133
  if (parsedRepresentation) {
1079
1134
  parsedRepresentation.hdr = parsedRepresentation.hdr || videoRange;
1080
1135
  }
@@ -1150,12 +1205,15 @@ shaka.dash.DashParser = class {
1150
1205
  * @param {!Array.<string>} roles
1151
1206
  * @param {Map.<string, string>} closedCaptions
1152
1207
  * @param {!Element} node
1208
+ * @param {?shaka.media.ManifestParser.AccessibilityPurpose}
1209
+ * accessibilityPurpose
1210
+ *
1153
1211
  * @return {?shaka.extern.Stream} The Stream, or null when there is a
1154
1212
  * non-critical parsing error.
1155
1213
  * @private
1156
1214
  */
1157
1215
  parseRepresentation_(context, contentProtection, kind, language, label,
1158
- isPrimary, roles, closedCaptions, node) {
1216
+ isPrimary, roles, closedCaptions, node, accessibilityPurpose) {
1159
1217
  const XmlUtils = shaka.util.XmlUtils;
1160
1218
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
1161
1219
 
@@ -1189,12 +1247,12 @@ shaka.dash.DashParser = class {
1189
1247
  const isImage = contentType == ContentType.IMAGE;
1190
1248
 
1191
1249
  try {
1192
- const requestInitSegment = (uris, startByte, endByte) => {
1193
- return this.requestInitSegment_(uris, startByte, endByte);
1250
+ const requestSegment = (uris, startByte, endByte, isInit) => {
1251
+ return this.requestSegment_(uris, startByte, endByte, isInit);
1194
1252
  };
1195
1253
  if (context.representation.segmentBase) {
1196
1254
  streamInfo = shaka.dash.SegmentBase.createStreamInfo(
1197
- context, requestInitSegment);
1255
+ context, requestSegment);
1198
1256
  } else if (context.representation.segmentList) {
1199
1257
  streamInfo = shaka.dash.SegmentList.createStreamInfo(
1200
1258
  context, this.streamMap_);
@@ -1202,7 +1260,7 @@ shaka.dash.DashParser = class {
1202
1260
  const hasManifest = !!this.manifest_;
1203
1261
 
1204
1262
  streamInfo = shaka.dash.SegmentTemplate.createStreamInfo(
1205
- context, requestInitSegment, this.streamMap_, hasManifest,
1263
+ context, requestSegment, this.streamMap_, hasManifest,
1206
1264
  this.config_.dash.initialSegmentLimit, this.periodDurations_);
1207
1265
  } else {
1208
1266
  goog.asserts.assert(isText,
@@ -1322,6 +1380,7 @@ shaka.dash.DashParser = class {
1322
1380
  drmInfos: contentProtection.drmInfos,
1323
1381
  keyIds,
1324
1382
  language,
1383
+ originalLanguage: context.adaptationSet.language,
1325
1384
  label,
1326
1385
  type: context.adaptationSet.contentType,
1327
1386
  primary: isPrimary,
@@ -1337,6 +1396,7 @@ shaka.dash.DashParser = class {
1337
1396
  hdr,
1338
1397
  tilesLayout,
1339
1398
  matchedStreams: [],
1399
+ accessibilityPurpose,
1340
1400
  external: false,
1341
1401
  };
1342
1402
  }
@@ -1378,6 +1438,10 @@ shaka.dash.DashParser = class {
1378
1438
 
1379
1439
  // Try updating again, but ensure we haven't been destroyed.
1380
1440
  if (this.playerInterface_) {
1441
+ if (this.config_.raiseFatalErrorOnManifestUpdateRequestFailure) {
1442
+ this.playerInterface_.onError(error);
1443
+ return;
1444
+ }
1381
1445
  // We will retry updating, so override the severity of the error.
1382
1446
  error.severity = shaka.util.Error.Severity.RECOVERABLE;
1383
1447
  this.playerInterface_.onError(error);
@@ -1410,7 +1474,6 @@ shaka.dash.DashParser = class {
1410
1474
  }
1411
1475
 
1412
1476
  const finalDelay = Math.max(
1413
- shaka.dash.DashParser.MIN_UPDATE_PERIOD_,
1414
1477
  this.updatePeriod_ - offset,
1415
1478
  this.averageUpdateDuration_.getEstimate());
1416
1479
 
@@ -1508,6 +1571,7 @@ shaka.dash.DashParser = class {
1508
1571
  pixelAspectRatio: pixelAspectRatio,
1509
1572
  emsgSchemeIdUris: emsgSchemeIdUris,
1510
1573
  id: elem.getAttribute('id'),
1574
+ language: elem.getAttribute('lang'),
1511
1575
  numChannels: numChannels,
1512
1576
  audioSamplingRate: audioSamplingRate,
1513
1577
  availabilityTimeOffset: availabilityTimeOffset,
@@ -1846,11 +1910,15 @@ shaka.dash.DashParser = class {
1846
1910
  * @param {!Array.<string>} uris
1847
1911
  * @param {?number} startByte
1848
1912
  * @param {?number} endByte
1913
+ * @param {boolean} isInit
1849
1914
  * @return {!Promise.<BufferSource>}
1850
1915
  * @private
1851
1916
  */
1852
- async requestInitSegment_(uris, startByte, endByte) {
1917
+ async requestSegment_(uris, startByte, endByte, isInit) {
1853
1918
  const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
1919
+ const type = isInit ?
1920
+ shaka.net.NetworkingEngine.AdvancedRequestType.INIT_SEGMENT :
1921
+ shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT;
1854
1922
 
1855
1923
  const request = shaka.util.Networking.createSegmentRequest(
1856
1924
  uris,
@@ -1859,7 +1927,7 @@ shaka.dash.DashParser = class {
1859
1927
  this.config_.retryParameters);
1860
1928
 
1861
1929
  const networkingEngine = this.playerInterface_.networkingEngine;
1862
- const operation = networkingEngine.request(requestType, request);
1930
+ const operation = networkingEngine.request(requestType, request, {type});
1863
1931
  this.operationManager_.manage(operation);
1864
1932
  const response = await operation.promise;
1865
1933
  return response.data;
@@ -1890,22 +1958,13 @@ shaka.dash.DashParser = class {
1890
1958
  };
1891
1959
 
1892
1960
 
1893
- /**
1894
- * Contains the minimum amount of time, in seconds, between manifest update
1895
- * requests.
1896
- *
1897
- * @private
1898
- * @const {number}
1899
- */
1900
- shaka.dash.DashParser.MIN_UPDATE_PERIOD_ = 3;
1901
-
1902
-
1903
1961
  /**
1904
1962
  * @typedef {
1905
- * function(!Array.<string>, ?number, ?number):!Promise.<BufferSource>
1963
+ * function(!Array.<string>, ?number, ?number, boolean):
1964
+ * !Promise.<BufferSource>
1906
1965
  * }
1907
1966
  */
1908
- shaka.dash.DashParser.RequestInitSegmentCallback;
1967
+ shaka.dash.DashParser.RequestSegmentCallback;
1909
1968
 
1910
1969
 
1911
1970
  /**
@@ -1923,6 +1982,7 @@ shaka.dash.DashParser.RequestInitSegmentCallback;
1923
1982
  * pixelAspectRatio: (string|undefined),
1924
1983
  * emsgSchemeIdUris: !Array.<string>,
1925
1984
  * id: ?string,
1985
+ * language: ?string,
1926
1986
  * numChannels: ?number,
1927
1987
  * audioSamplingRate: ?number,
1928
1988
  * availabilityTimeOffset: number
@@ -1958,6 +2018,8 @@ shaka.dash.DashParser.RequestInitSegmentCallback;
1958
2018
  * emsg registered schemeIdUris.
1959
2019
  * @property {?string} id
1960
2020
  * The ID of the element.
2021
+ * @property {?string} language
2022
+ * The original language of the element.
1961
2023
  * @property {?number} numChannels
1962
2024
  * The number of audio channels, or null if unknown.
1963
2025
  * @property {?number} audioSamplingRate
@@ -15,6 +15,7 @@ goog.require('shaka.util.Functional');
15
15
  goog.require('shaka.util.ManifestParserUtils');
16
16
  goog.require('shaka.util.XmlUtils');
17
17
  goog.requireType('shaka.dash.DashParser');
18
+ goog.requireType('shaka.media.PresentationTimeline');
18
19
 
19
20
 
20
21
  /**
@@ -121,7 +122,7 @@ shaka.dash.MpdUtils = class {
121
122
  * @param {number} unscaledPresentationTimeOffset
122
123
  * @param {number} periodDuration The Period's duration in seconds.
123
124
  * Infinity indicates that the Period continues indefinitely.
124
- * @return {!Array.<shaka.dash.MpdUtils.TimeRange>}
125
+ * @return {!Array.<shaka.media.PresentationTimeline.TimeRange>}
125
126
  */
126
127
  static createTimeline(
127
128
  segmentTimeline, timescale, unscaledPresentationTimeOffset,
@@ -137,7 +138,7 @@ shaka.dash.MpdUtils = class {
137
138
 
138
139
  const timePoints = XmlUtils.findChildren(segmentTimeline, 'S');
139
140
 
140
- /** @type {!Array.<shaka.dash.MpdUtils.TimeRange>} */
141
+ /** @type {!Array.<shaka.media.PresentationTimeline.TimeRange>} */
141
142
  const timeline = [];
142
143
  let lastEndTime = -unscaledPresentationTimeOffset;
143
144
 
@@ -289,7 +290,7 @@ shaka.dash.MpdUtils = class {
289
290
 
290
291
  const timelineNode =
291
292
  MpdUtils.inheritChild(context, callback, 'SegmentTimeline');
292
- /** @type {Array.<shaka.dash.MpdUtils.TimeRange>} */
293
+ /** @type {Array.<shaka.media.PresentationTimeline.TimeRange>} */
293
294
  let timeline = null;
294
295
  if (timelineNode) {
295
296
  timeline = MpdUtils.createTimeline(
@@ -538,26 +539,6 @@ shaka.dash.MpdUtils = class {
538
539
  };
539
540
 
540
541
 
541
- /**
542
- * @typedef {{
543
- * start: number,
544
- * unscaledStart: number,
545
- * end: number
546
- * }}
547
- *
548
- * @description
549
- * Defines a time range of a media segment. Times are in seconds.
550
- *
551
- * @property {number} start
552
- * The start time of the range.
553
- * @property {number} unscaledStart
554
- * The start time of the range in representation timescale units.
555
- * @property {number} end
556
- * The end time (exclusive) of the range.
557
- */
558
- shaka.dash.MpdUtils.TimeRange;
559
-
560
-
561
542
  /**
562
543
  * @typedef {{
563
544
  * timescale: number,
@@ -565,7 +546,7 @@ shaka.dash.MpdUtils.TimeRange;
565
546
  * startNumber: number,
566
547
  * scaledPresentationTimeOffset: number,
567
548
  * unscaledPresentationTimeOffset: number,
568
- * timeline: Array.<shaka.dash.MpdUtils.TimeRange>
549
+ * timeline: Array.<shaka.media.PresentationTimeline.TimeRange>
569
550
  * }}
570
551
  *
571
552
  * @description
@@ -581,7 +562,7 @@ shaka.dash.MpdUtils.TimeRange;
581
562
  * The presentation time offset of the representation, in seconds.
582
563
  * @property {number} unscaledPresentationTimeOffset
583
564
  * The presentation time offset of the representation, in timescale units.
584
- * @property {Array.<shaka.dash.MpdUtils.TimeRange>} timeline
565
+ * @property {Array.<shaka.media.PresentationTimeline.TimeRange>} timeline
585
566
  * The timeline of the representation, if given. Times in seconds.
586
567
  */
587
568
  shaka.dash.MpdUtils.SegmentInfo;
@@ -70,11 +70,10 @@ shaka.dash.SegmentBase = class {
70
70
  * Creates a new StreamInfo object.
71
71
  *
72
72
  * @param {shaka.dash.DashParser.Context} context
73
- * @param {shaka.dash.DashParser.RequestInitSegmentCallback}
74
- * requestInitSegment
73
+ * @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
75
74
  * @return {shaka.dash.DashParser.StreamInfo}
76
75
  */
77
- static createStreamInfo(context, requestInitSegment) {
76
+ static createStreamInfo(context, requestSegment) {
78
77
  goog.asserts.assert(context.representation.segmentBase,
79
78
  'Should only be called with SegmentBase');
80
79
  // Since SegmentBase does not need updates, simply treat any call as
@@ -111,7 +110,7 @@ shaka.dash.SegmentBase = class {
111
110
  return {
112
111
  generateSegmentIndex: () => {
113
112
  return SegmentBase.generateSegmentIndex_(
114
- shallowCopyOfContext, requestInitSegment, initSegmentReference,
113
+ shallowCopyOfContext, requestSegment, initSegmentReference,
115
114
  scaledPresentationTimeOffset);
116
115
  },
117
116
  };
@@ -121,8 +120,7 @@ shaka.dash.SegmentBase = class {
121
120
  * Creates a SegmentIndex for the given URIs and context.
122
121
  *
123
122
  * @param {shaka.dash.DashParser.Context} context
124
- * @param {shaka.dash.DashParser.RequestInitSegmentCallback}
125
- * requestInitSegment
123
+ * @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
126
124
  * @param {shaka.media.InitSegmentReference} initSegmentReference
127
125
  * @param {!Array.<string>} uris
128
126
  * @param {number} startByte
@@ -131,7 +129,7 @@ shaka.dash.SegmentBase = class {
131
129
  * @return {!Promise.<shaka.media.SegmentIndex>}
132
130
  */
133
131
  static async generateSegmentIndexFromUris(
134
- context, requestInitSegment, initSegmentReference, uris, startByte,
132
+ context, requestSegment, initSegmentReference, uris, startByte,
135
133
  endByte, scaledPresentationTimeOffset) {
136
134
  // Unpack context right away, before we start an async process.
137
135
  // This immunizes us against changes to the context object later.
@@ -143,16 +141,17 @@ shaka.dash.SegmentBase = class {
143
141
  const containerType = context.representation.mimeType.split('/')[1];
144
142
 
145
143
  // Create a local variable to bind to so we can set to null to help the GC.
146
- let localRequest = requestInitSegment;
144
+ let localRequest = requestSegment;
147
145
  let segmentIndex = null;
148
146
 
149
147
  const responses = [
150
- localRequest(uris, startByte, endByte),
148
+ localRequest(uris, startByte, endByte, /* isInit= */ false),
151
149
  containerType == 'webm' ?
152
150
  localRequest(
153
151
  initSegmentReference.getUris(),
154
152
  initSegmentReference.startByte,
155
- initSegmentReference.endByte) :
153
+ initSegmentReference.endByte,
154
+ /* isInit= */ true) :
156
155
  null,
157
156
  ];
158
157
 
@@ -327,15 +326,14 @@ shaka.dash.SegmentBase = class {
327
326
  * Generate a SegmentIndex from a Context object.
328
327
  *
329
328
  * @param {shaka.dash.DashParser.Context} context
330
- * @param {shaka.dash.DashParser.RequestInitSegmentCallback}
331
- * requestInitSegment
329
+ * @param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
332
330
  * @param {shaka.media.InitSegmentReference} initSegmentReference
333
331
  * @param {number} scaledPresentationTimeOffset
334
332
  * @return {!Promise.<shaka.media.SegmentIndex>}
335
333
  * @private
336
334
  */
337
335
  static generateSegmentIndex_(
338
- context, requestInitSegment, initSegmentReference,
336
+ context, requestSegment, initSegmentReference,
339
337
  scaledPresentationTimeOffset) {
340
338
  const SegmentBase = shaka.dash.SegmentBase;
341
339
 
@@ -344,7 +342,7 @@ shaka.dash.SegmentBase = class {
344
342
  goog.asserts.assert(indexRange, 'Index range should not be null!');
345
343
 
346
344
  return shaka.dash.SegmentBase.generateSegmentIndexFromUris(
347
- context, requestInitSegment, initSegmentReference, indexUris,
345
+ context, requestSegment, initSegmentReference, indexUris,
348
346
  indexRange.start, indexRange.end,
349
347
  scaledPresentationTimeOffset);
350
348
  }
@@ -18,6 +18,7 @@ goog.require('shaka.util.Functional');
18
18
  goog.require('shaka.util.ManifestParserUtils');
19
19
  goog.require('shaka.util.XmlUtils');
20
20
  goog.requireType('shaka.dash.DashParser');
21
+ goog.requireType('shaka.media.PresentationTimeline');
21
22
 
22
23
 
23
24
  /**
@@ -223,9 +224,6 @@ shaka.dash.SegmentList = class {
223
224
  let prevEndTime = info.startTime;
224
225
  for (let i = 0; i < max; i++) {
225
226
  const segment = info.mediaSegments[i];
226
- const mediaUri = ManifestParserUtils.resolveUris(
227
- baseUris, [segment.mediaUri]);
228
-
229
227
  const startTime = prevEndTime;
230
228
  let endTime;
231
229
 
@@ -243,7 +241,13 @@ shaka.dash.SegmentList = class {
243
241
  endTime = startTime + periodDuration;
244
242
  }
245
243
 
246
- const getUris = () => mediaUri;
244
+ let uris = null;
245
+ const getUris = () => {
246
+ if (uris == null) {
247
+ uris = ManifestParserUtils.resolveUris(baseUris, [segment.mediaUri]);
248
+ }
249
+ return uris;
250
+ };
247
251
  references.push(
248
252
  new shaka.media.SegmentReference(
249
253
  periodStart + startTime,
@@ -323,7 +327,7 @@ shaka.dash.SegmentList.MediaSegment;
323
327
  * startTime: number,
324
328
  * startNumber: number,
325
329
  * scaledPresentationTimeOffset: number,
326
- * timeline: Array.<shaka.dash.MpdUtils.TimeRange>,
330
+ * timeline: Array.<shaka.media.PresentationTimeline.TimeRange>,
327
331
  * mediaSegments: !Array.<shaka.dash.SegmentList.MediaSegment>
328
332
  * }}
329
333
  * @private
@@ -339,7 +343,7 @@ shaka.dash.SegmentList.MediaSegment;
339
343
  * The start number of the segments; 1 or greater.
340
344
  * @property {number} scaledPresentationTimeOffset
341
345
  * The scaledPresentationTimeOffset of the representation, in seconds.
342
- * @property {Array.<shaka.dash.MpdUtils.TimeRange>} timeline
346
+ * @property {Array.<shaka.media.PresentationTimeline.TimeRange>} timeline
343
347
  * The timeline of the representation, if given. Times in seconds.
344
348
  * @property {!Array.<shaka.dash.SegmentList.MediaSegment>} mediaSegments
345
349
  * The URI and byte-ranges of the media segments.