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
@@ -0,0 +1,358 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.util.ContentSteeringManager');
8
+
9
+ goog.require('goog.Uri');
10
+ goog.require('shaka.media.ManifestParser');
11
+ goog.require('shaka.net.NetworkingEngine');
12
+ goog.require('shaka.util.Error');
13
+ goog.require('shaka.util.IDestroyable');
14
+ goog.require('shaka.util.ManifestParserUtils');
15
+ goog.require('shaka.util.OperationManager');
16
+ goog.require('shaka.util.StringUtils');
17
+ goog.require('shaka.util.Timer');
18
+
19
+
20
+ /**
21
+ * Create a Content Steering manager.
22
+ *
23
+ * @implements {shaka.util.IDestroyable}
24
+ */
25
+ shaka.util.ContentSteeringManager = class {
26
+ /**
27
+ * @param {shaka.extern.ManifestParser.PlayerInterface} playerInterface
28
+ */
29
+ constructor(playerInterface) {
30
+ /** @private {?shaka.extern.ManifestConfiguration} */
31
+ this.config_ = null;
32
+
33
+ /** @private {?shaka.extern.ManifestParser.PlayerInterface} */
34
+ this.playerInterface_ = playerInterface;
35
+
36
+ /** @private {!shaka.util.OperationManager} */
37
+ this.operationManager_ = new shaka.util.OperationManager();
38
+
39
+ /** @private {!Array.<string>} */
40
+ this.baseUris_ = [];
41
+
42
+ /** @private {?string} */
43
+ this.defaultPathwayId_ = null;
44
+
45
+ /** @private {!Array.<string>} */
46
+ this.pathwayPriority_ = [];
47
+
48
+ /** @private {?string} */
49
+ this.lastPathwayUsed_ = null;
50
+
51
+ /** @private {!Array.<shaka.util.ContentSteeringManager.PathawayClone>} */
52
+ this.pathwayClones_ = [];
53
+
54
+ /**
55
+ * Default to 5 minutes. Value in seconds.
56
+ *
57
+ * @private {number}
58
+ */
59
+ this.lastTTL_ = 300;
60
+
61
+ /** @private {!Map.<(string|number), !Map.<string, string>>} */
62
+ this.locations_ = new Map();
63
+
64
+ /** @private {!Map.<string, number>} */
65
+ this.bannedLocations_ = new Map();
66
+
67
+ /** @private {?shaka.util.Timer} */
68
+ this.updateTimer_ = null;
69
+
70
+ /** @private {string} */
71
+ this.manifestType_ = shaka.media.ManifestParser.UNKNOWN;
72
+ }
73
+
74
+ /**
75
+ * @param {shaka.extern.ManifestConfiguration} config
76
+ */
77
+ configure(config) {
78
+ this.config_ = config;
79
+ }
80
+
81
+
82
+ /** @override */
83
+ destroy() {
84
+ this.config_ = null;
85
+ this.playerInterface_ = null;
86
+ this.baseUris_ = [];
87
+ this.defaultPathwayId_ = null;
88
+ this.pathwayPriority_ = [];
89
+ this.pathwayClones_ = [];
90
+ this.locations_.clear();
91
+
92
+ if (this.updateTimer_ != null) {
93
+ this.updateTimer_.stop();
94
+ this.updateTimer_ = null;
95
+ }
96
+
97
+ return this.operationManager_.destroy();
98
+ }
99
+
100
+ /**
101
+ * @param {string} manifestType
102
+ */
103
+ setManifestType(manifestType) {
104
+ this.manifestType_ = manifestType;
105
+ }
106
+
107
+ /**
108
+ * @param {!Array.<string>} baseUris
109
+ */
110
+ setBaseUris(baseUris) {
111
+ this.baseUris_ = baseUris;
112
+ }
113
+
114
+ /**
115
+ * @param {?string} defaultPathwayId
116
+ */
117
+ setDefaultPathwayId(defaultPathwayId) {
118
+ this.defaultPathwayId_ = defaultPathwayId;
119
+ }
120
+
121
+ /**
122
+ * Request the Content Steering info.
123
+ *
124
+ * @param {string} uri
125
+ * @return {!Promise}
126
+ */
127
+ async requestInfo(uri) {
128
+ const uris = shaka.util.ManifestParserUtils.resolveUris(
129
+ this.baseUris_, [this.addQueryParams_(uri)]);
130
+ const type = shaka.net.NetworkingEngine.RequestType.CONTENT_STEERING;
131
+ const request = shaka.net.NetworkingEngine.makeRequest(
132
+ uris, this.config_.retryParameters);
133
+
134
+ const op = this.playerInterface_.networkingEngine.request(type, request);
135
+ this.operationManager_.manage(op);
136
+ try {
137
+ const response = await op.promise;
138
+ const str = shaka.util.StringUtils.fromUTF8(response.data);
139
+ const steeringManifest =
140
+ /** @type {shaka.util.ContentSteeringManager.SteeringManifest} */
141
+ (JSON.parse(str));
142
+ if (steeringManifest.VERSION == 1) {
143
+ this.processManifest_(steeringManifest, response.uri);
144
+ }
145
+ } catch (e) {
146
+ if (e && e.code == shaka.util.Error.Code.OPERATION_ABORTED) {
147
+ return;
148
+ }
149
+ if (this.updateTimer_ != null) {
150
+ this.updateTimer_.stop();
151
+ this.updateTimer_ = null;
152
+ }
153
+ this.updateTimer_ = new shaka.util.Timer(() => {
154
+ this.requestInfo(uri);
155
+ });
156
+ this.updateTimer_.tickAfter(this.lastTTL_);
157
+ }
158
+ }
159
+
160
+ /** @private */
161
+ addQueryParams_(uri) {
162
+ if (!this.pathwayPriority_.length) {
163
+ return uri;
164
+ }
165
+ const finalUri = new goog.Uri(uri);
166
+ const currentPathwayID = this.lastPathwayUsed_ || this.pathwayPriority_[0];
167
+ const currentBandwidth =
168
+ Math.round(this.playerInterface_.getBandwidthEstimate());
169
+ const queryData = finalUri.getQueryData();
170
+ if (this.manifestType_ == shaka.media.ManifestParser.DASH) {
171
+ queryData.add('_DASH_pathway', currentPathwayID);
172
+ queryData.add('_DASH_throughput', String(currentBandwidth));
173
+ } else if (this.manifestType_ == shaka.media.ManifestParser.HLS) {
174
+ queryData.add('_HLS_pathway', currentPathwayID);
175
+ queryData.add('_HLS_throughput', String(currentBandwidth));
176
+ }
177
+ if (queryData.getCount()) {
178
+ finalUri.setQueryData(queryData);
179
+ }
180
+ return finalUri.toString();
181
+ }
182
+
183
+ /**
184
+ * @param {shaka.util.ContentSteeringManager.SteeringManifest} manifest
185
+ * @param {string} finalManifestUri
186
+ * @private
187
+ */
188
+ processManifest_(manifest, finalManifestUri) {
189
+ if (this.updateTimer_ != null) {
190
+ this.updateTimer_.stop();
191
+ this.updateTimer_ = null;
192
+ }
193
+ const uri = manifest['RELOAD-URI'] || finalManifestUri;
194
+ this.updateTimer_ = new shaka.util.Timer(() => {
195
+ this.requestInfo(uri);
196
+ });
197
+ const newTTL = manifest['TTL'];
198
+ if (newTTL) {
199
+ this.lastTTL_ = newTTL;
200
+ }
201
+ this.updateTimer_.tickAfter(this.lastTTL_);
202
+ this.pathwayPriority_ = manifest['PATHWAY-PRIORITY'] || [];
203
+ this.pathwayClones_ = manifest['PATHWAY-CLONES'] || [];
204
+ }
205
+
206
+ /**
207
+ * Clear the previous locations added.
208
+ */
209
+ clearPreviousLocations() {
210
+ this.locations_.clear();
211
+ }
212
+
213
+ /**
214
+ * @param {string|number} streamId
215
+ * @param {string} pathwayId
216
+ * @param {string} uri
217
+ */
218
+ addLocation(streamId, pathwayId, uri) {
219
+ let streamLocations = this.locations_.get(streamId);
220
+ if (!streamLocations) {
221
+ streamLocations = new Map();
222
+ }
223
+ streamLocations.set(pathwayId, uri);
224
+ this.locations_.set(streamId, streamLocations);
225
+ }
226
+
227
+ /**
228
+ * @param {string} uri
229
+ */
230
+ banLocation(uri) {
231
+ const bannedUntil = Date.now() + 60000;
232
+ this.bannedLocations_.set(uri, bannedUntil);
233
+ }
234
+
235
+ /**
236
+ * Get the base locations ordered according the priority.
237
+ *
238
+ * @param {string|number} streamId
239
+ * @return {!Array.<string>}
240
+ */
241
+ getLocations(streamId) {
242
+ const streamLocations = this.locations_.get(streamId) || new Map();
243
+ /** @type {!Array.<!{pathwayId: string, location: string}>} */
244
+ let locationsPathwayIdMap = [];
245
+ for (const pathwayId of this.pathwayPriority_) {
246
+ const location = streamLocations.get(pathwayId);
247
+ if (location) {
248
+ locationsPathwayIdMap.push({pathwayId, location});
249
+ } else {
250
+ const clone = this.pathwayClones_.find((c) => c.ID == pathwayId);
251
+ if (clone) {
252
+ const cloneLocation = streamLocations.get(clone['BASE-ID']);
253
+ if (cloneLocation) {
254
+ if (clone['URI-REPLACEMENT'].HOST) {
255
+ const uri = new goog.Uri(cloneLocation);
256
+ uri.setDomain(clone['URI-REPLACEMENT'].HOST);
257
+ locationsPathwayIdMap.push({
258
+ pathwayId: pathwayId,
259
+ location: uri.toString(),
260
+ });
261
+ } else {
262
+ locationsPathwayIdMap.push({
263
+ pathwayId: pathwayId,
264
+ location: cloneLocation,
265
+ });
266
+ }
267
+ }
268
+ }
269
+ }
270
+ }
271
+
272
+ const now = Date.now();
273
+ for (const uri of this.bannedLocations_.keys()) {
274
+ const bannedUntil = this.bannedLocations_.get(uri);
275
+ if (now > bannedUntil) {
276
+ this.bannedLocations_.delete(uri);
277
+ }
278
+ }
279
+ locationsPathwayIdMap = locationsPathwayIdMap.filter((l) => {
280
+ for (const uri of this.bannedLocations_.keys()) {
281
+ if (uri.includes(new goog.Uri(l.location).getDomain())) {
282
+ return false;
283
+ }
284
+ }
285
+ return true;
286
+ });
287
+
288
+ if (locationsPathwayIdMap.length) {
289
+ this.lastPathwayUsed_ = locationsPathwayIdMap[0].pathwayId;
290
+ }
291
+
292
+ const locations = locationsPathwayIdMap.map((l) => l.location);
293
+
294
+ if (!locations.length && this.defaultPathwayId_) {
295
+ for (const pathwayId of this.defaultPathwayId_.split(',')) {
296
+ const location = streamLocations.get(pathwayId);
297
+ if (location) {
298
+ this.lastPathwayUsed_ = this.defaultPathwayId_;
299
+ locations.push(location);
300
+ }
301
+ }
302
+ }
303
+ if (!locations.length) {
304
+ for (const location of streamLocations.values()) {
305
+ locations.push(location);
306
+ }
307
+ }
308
+ return shaka.util.ManifestParserUtils.resolveUris(
309
+ this.baseUris_, locations);
310
+ }
311
+ };
312
+
313
+
314
+ /**
315
+ * @typedef {{
316
+ * VERSION: number,
317
+ * TTL: number,
318
+ * RELOAD-URI: string,
319
+ * PATHWAY-PRIORITY: !Array.<string>,
320
+ * PATHWAY-CLONES: !Array.<shaka.util.ContentSteeringManager.PathawayClone>
321
+ * }}
322
+ *
323
+ * @description
324
+ * Contains information about the Steering Manifest
325
+ *
326
+ * @property {string} VERSION
327
+ * @property {number} TTL
328
+ * @property {string RELOAD-URI
329
+ * @property {!Array.<string>} PATHWAY-PRIORITY
330
+ * @property {!Array.<
331
+ * shaka.util.ContentSteeringManager.PathawayClone>} PATHWAY-CLONES
332
+ */
333
+ shaka.util.ContentSteeringManager.SteeringManifest;
334
+
335
+
336
+ /**
337
+ * @typedef {{
338
+ * BASE-ID: string,
339
+ * ID: string,
340
+ * URI-REPLACEMENT: !Array.<shaka.util.ContentSteeringManager.UriReplacement>
341
+ * }}
342
+ *
343
+ * @property {string} BASE-ID
344
+ * @property {string} ID
345
+ * @property {!Array.<
346
+ * shaka.util.ContentSteeringManager.UriReplacement>} URI-REPLACEMENT
347
+ */
348
+ shaka.util.ContentSteeringManager.PathawayClone;
349
+
350
+
351
+ /**
352
+ * @typedef {{
353
+ * HOST: string
354
+ * }}
355
+ *
356
+ * @property {string} HOST
357
+ */
358
+ shaka.util.ContentSteeringManager.UriReplacement;
package/lib/util/error.js CHANGED
@@ -330,7 +330,7 @@ shaka.util.Error.Code = {
330
330
 
331
331
  /**
332
332
  * Unable to guess mime type of the text.
333
- * <br> error.data[0] is the text file's extension.
333
+ * <br> error.data[0] is the text file's uri.
334
334
  */
335
335
  'TEXT_COULD_NOT_GUESS_MIME_TYPE': 2011,
336
336
 
@@ -360,11 +360,7 @@ shaka.util.Error.Code = {
360
360
  */
361
361
  'CHAPTERS_TRACK_FAILED': 2015,
362
362
 
363
- /**
364
- * External thumbnails tracks cannot be added in src= because native platform
365
- * doesn't support it.
366
- */
367
- 'CANNOT_ADD_EXTERNAL_THUMBNAILS_TO_SRC_EQUALS': 2016,
363
+ // RETIRED: 'CANNOT_ADD_EXTERNAL_THUMBNAILS_TO_SRC_EQUALS': 2016,
368
364
 
369
365
  /**
370
366
  * Only external urls of WebVTT type are supported.
@@ -728,15 +724,8 @@ shaka.util.Error.Code = {
728
724
  */
729
725
  'NO_WEB_CRYPTO_API': 4042,
730
726
 
731
- /**
732
- * AES-128 iv length should be 16 bytes.
733
- */
734
- 'HLS_AES_128_INVALID_IV_LENGTH': 4043,
735
-
736
- /**
737
- * AES-128 encryption key length should be 16 bytes.
738
- */
739
- 'HLS_AES_128_INVALID_KEY_LENGTH': 4044,
727
+ // RETIRED: 'HLS_AES_128_INVALID_IV_LENGTH': 4043,
728
+ // RETIRED: 'HLS_AES_128_INVALID_KEY_LENGTH': 4044,
740
729
 
741
730
  /**
742
731
  * External thumbnails tracks cannot be added to live streams.
@@ -754,6 +743,26 @@ shaka.util.Error.Code = {
754
743
  */
755
744
  'MSS_LIVE_CONTENT_NOT_SUPPORTED': 4047,
756
745
 
746
+ /**
747
+ * AES-128 iv length should be 16 bytes.
748
+ */
749
+ 'AES_128_INVALID_IV_LENGTH': 4048,
750
+
751
+ /**
752
+ * AES-128 encryption key length should be 16 bytes.
753
+ */
754
+ 'AES_128_INVALID_KEY_LENGTH': 4049,
755
+
756
+ /**
757
+ * The DASH Manifest specifies conflicting AES-128 keys.
758
+ */
759
+ 'DASH_CONFLICTING_AES_128': 4050,
760
+
761
+ /**
762
+ * The DASH Manifest specifies a unsupported AES-128 encryption.
763
+ */
764
+ 'DASH_UNSUPPORTED_AES_128': 4051,
765
+
757
766
 
758
767
  // RETIRED: 'INCONSISTENT_BUFFER_STATE': 5000,
759
768
  // RETIRED: 'INVALID_SEGMENT_INDEX': 5001,
@@ -1107,4 +1116,10 @@ shaka.util.Error.Code = {
1107
1116
  * for the previous request to complete before initiating a new one.
1108
1117
  */
1109
1118
  'CURRENT_DAI_REQUEST_NOT_FINISHED': 10004,
1119
+
1120
+ /**
1121
+ * MediaTailor Ad Manager needs to be initialized to enable MediaTailor
1122
+ * Ad Insertion. Call adManager.initMediaTailor() to do it.
1123
+ */
1124
+ 'MT_AD_MANAGER_NOT_INITIALIZED': 10005,
1110
1125
  };
@@ -17,6 +17,7 @@
17
17
 
18
18
  goog.provide('shaka.util.ExpGolomb');
19
19
 
20
+ goog.require('shaka.util.BufferUtils');
20
21
  goog.require('shaka.util.DataViewReader');
21
22
 
22
23
 
@@ -31,13 +32,17 @@ goog.require('shaka.util.DataViewReader');
31
32
  shaka.util.ExpGolomb = class {
32
33
  /**
33
34
  * @param {!Uint8Array} data
35
+ * @param {boolean=} convertEbsp2rbsp
34
36
  */
35
- constructor(data) {
37
+ constructor(data, convertEbsp2rbsp = false) {
36
38
  /** @private {!Uint8Array} */
37
39
  this.data_ = data;
40
+ if (convertEbsp2rbsp) {
41
+ this.data_ = this.ebsp2rbsp_(data);
42
+ }
38
43
 
39
44
  /** @private {number} */
40
- this.workingBytesAvailable_ = data.byteLength;
45
+ this.workingBytesAvailable_ = this.data_.byteLength;
41
46
 
42
47
  // the current word being examined
43
48
  /** @private {number} */
@@ -48,6 +53,29 @@ shaka.util.ExpGolomb = class {
48
53
  this.workingBitsAvailable_ = 0;
49
54
  }
50
55
 
56
+ /**
57
+ * @param {!Uint8Array} data
58
+ * @return {!Uint8Array}
59
+ * @private
60
+ */
61
+ ebsp2rbsp_(data) {
62
+ const ret = new Uint8Array(data.byteLength);
63
+ let retIndex = 0;
64
+
65
+ for (let i = 0; i < data.byteLength; i++) {
66
+ if (i >= 2) {
67
+ // Unescape: Skip 0x03 after 00 00
68
+ if (data[i] == 0x03 && data[i - 1] == 0x00 && data[i - 2] == 0x00) {
69
+ continue;
70
+ }
71
+ }
72
+ ret[retIndex] = data[i];
73
+ retIndex++;
74
+ }
75
+
76
+ return shaka.util.BufferUtils.toUint8(ret, 0, retIndex);
77
+ }
78
+
51
79
  /**
52
80
  * Load the next word
53
81
  *
@@ -205,7 +205,7 @@ shaka.util.FairPlayUtils = class {
205
205
  const stringToArray = (string) => {
206
206
  // 2 bytes for each char
207
207
  const buffer = new ArrayBuffer(string.length * 2);
208
- const array = new Uint16Array(buffer);
208
+ const array = shaka.util.BufferUtils.toUint16(buffer);
209
209
  for (let i = 0, strLen = string.length; i < strLen; i++) {
210
210
  array[i] = string.charCodeAt(i);
211
211
  }
@@ -156,6 +156,7 @@ shaka.util.FakeEvent.EventName = {
156
156
  AbrStatusChanged: 'abrstatuschanged',
157
157
  Adaptation: 'adaptation',
158
158
  Buffering: 'buffering',
159
+ Complete: 'complete',
159
160
  DownloadFailed: 'downloadfailed',
160
161
  DownloadHeadersReceived: 'downloadheadersreceived',
161
162
  DrmSessionUpdate: 'drmsessionupdate',
@@ -163,21 +164,27 @@ shaka.util.FakeEvent.EventName = {
163
164
  Prft: 'prft',
164
165
  Error: 'error',
165
166
  ExpirationUpdated: 'expirationupdated',
167
+ FirstQuartile: 'firstquartile',
166
168
  GapJumped: 'gapjumped',
169
+ KeyStatusChanged: 'keystatuschanged',
167
170
  Loaded: 'loaded',
168
171
  Loading: 'loading',
169
172
  ManifestParsed: 'manifestparsed',
173
+ ManifestUpdated: 'manifestupdated',
170
174
  MediaQualityChanged: 'mediaqualitychanged',
171
175
  Metadata: 'metadata',
176
+ Midpoint: 'midpoint',
172
177
  OnStateChange: 'onstatechange',
173
- OnStateIdle: 'onstateidle',
174
178
  RateChange: 'ratechange',
175
179
  SegmentAppended: 'segmentappended',
176
180
  SessionDataEvent: 'sessiondata',
177
181
  StallDetected: 'stalldetected',
182
+ Started: 'started',
183
+ StateChanged: 'statechanged',
178
184
  Streaming: 'streaming',
179
185
  TextChanged: 'textchanged',
180
186
  TextTrackVisibility: 'texttrackvisibility',
187
+ ThirdQuartile: 'thirdquartile',
181
188
  TimelineRegionAdded: 'timelineregionadded',
182
189
  TimelineRegionEnter: 'timelineregionenter',
183
190
  TimelineRegionExit: 'timelineregionexit',
@@ -140,9 +140,58 @@ shaka.util.Id3Utils = class {
140
140
  key: frame.type,
141
141
  description: '',
142
142
  data: '',
143
+ mimeType: null,
144
+ pictureType: null,
143
145
  };
144
146
 
145
- if (frame.type === 'TXXX') {
147
+ if (frame.type === 'APIC') {
148
+ /*
149
+ * Format:
150
+ * [0] = {Text Encoding}
151
+ * [1 - X] = {MIME Type}\0
152
+ * [X+1] = {Picture Type}
153
+ * [X+2 - Y] = {Description}\0
154
+ * [Y - ?] = {Picture Data or Picture URL}
155
+ */
156
+ if (frame.size < 2) {
157
+ return null;
158
+ }
159
+ if (frame.data[0] !== shaka.util.Id3Utils.UTF8_encoding) {
160
+ shaka.log.warning('Ignore frame with unrecognized character ' +
161
+ 'encoding');
162
+ return null;
163
+ }
164
+
165
+ const mimeTypeEndIndex = frame.data.subarray(1).indexOf(0);
166
+ if (mimeTypeEndIndex === -1) {
167
+ return null;
168
+ }
169
+ const mimeType = StringUtils.fromUTF8(
170
+ BufferUtils.toUint8(frame.data, 1, mimeTypeEndIndex));
171
+ const pictureType = frame.data[2 + mimeTypeEndIndex];
172
+ const descriptionEndIndex = frame.data.subarray(3 + mimeTypeEndIndex)
173
+ .indexOf(0);
174
+ if (descriptionEndIndex === -1) {
175
+ return null;
176
+ }
177
+ const description = StringUtils.fromUTF8(
178
+ BufferUtils.toUint8(frame.data, 3 + mimeTypeEndIndex,
179
+ descriptionEndIndex));
180
+ let data;
181
+ if (mimeType === '-->') {
182
+ data = StringUtils.fromUTF8(
183
+ BufferUtils.toUint8(
184
+ frame.data, 4 + mimeTypeEndIndex + descriptionEndIndex));
185
+ } else {
186
+ data = BufferUtils.toArrayBuffer(
187
+ frame.data.subarray(4 + mimeTypeEndIndex + descriptionEndIndex));
188
+ }
189
+ metadataFrame.mimeType = mimeType;
190
+ metadataFrame.pictureType = pictureType;
191
+ metadataFrame.description = description;
192
+ metadataFrame.data = data;
193
+ return metadataFrame;
194
+ } else if (frame.type === 'TXXX') {
146
195
  /*
147
196
  * Format:
148
197
  * [0] = {Text Encoding}
@@ -8,7 +8,6 @@ goog.provide('shaka.util.ManifestParserUtils');
8
8
 
9
9
  goog.require('goog.Uri');
10
10
  goog.require('shaka.util.Error');
11
- goog.require('shaka.util.Functional');
12
11
 
13
12
 
14
13
  /**
@@ -27,7 +26,6 @@ shaka.util.ManifestParserUtils = class {
27
26
  * @return {!Array.<string>}
28
27
  */
29
28
  static resolveUris(baseUris, relativeUris) {
30
- const Functional = shaka.util.Functional;
31
29
  if (relativeUris.length == 0) {
32
30
  return baseUris;
33
31
  }
@@ -39,12 +37,18 @@ shaka.util.ManifestParserUtils = class {
39
37
  }
40
38
 
41
39
  const relativeAsGoog = relativeUris.map((uri) => new goog.Uri(uri));
42
- // Resolve each URI relative to each base URI, creating an Array of Arrays.
43
- // Then flatten the Arrays into a single Array.
44
- return baseUris.map((uri) => {
45
- const base = new goog.Uri(uri);
46
- return relativeAsGoog.map((i) => base.resolve(i).toString());
47
- }).reduce(Functional.collapseArrays, []);
40
+
41
+ // For each base URI, this code resolves it with every relative URI.
42
+ // The result is a single array containing all the resolved URIs.
43
+ const resolvedUris = [];
44
+ for (const baseStr of baseUris) {
45
+ const base = new goog.Uri(baseStr);
46
+ for (const relative of relativeAsGoog) {
47
+ resolvedUris.push(base.resolve(relative).toString());
48
+ }
49
+ }
50
+
51
+ return resolvedUris;
48
52
  }
49
53
 
50
54
 
@@ -624,7 +624,6 @@ shaka.util.Mp4Generator = class {
624
624
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
625
625
 
626
626
  const id = streamInfo.id + 1;
627
- const bandwidth = streamInfo.stream.bandwidth || 0;
628
627
  const channelsCount = streamInfo.stream.channelsCount || 2;
629
628
  const audioSamplingRate = streamInfo.stream.audioSamplingRate || 44100;
630
629
 
@@ -670,9 +669,10 @@ shaka.util.Mp4Generator = class {
670
669
  0x11, // length
671
670
  0x40, // object type
672
671
  0x15, // streamType
673
- 0x00, 0x06, 0x00, // bufferSizeDB
674
- ...this.breakNumberIntoBytes_(bandwidth, 4), // maxBitrate
675
- ...this.breakNumberIntoBytes_(bandwidth, 4), // avgBitrate
672
+ 0x00, 0x00, 0x00, // bufferSizeDB
673
+ 0x00, 0x00, 0x00, 0x00, // maxBitrate
674
+ 0x00, 0x00, 0x00, 0x00, // avgBitrate
675
+
676
676
  // DecoderSpecificInfo
677
677
  0x05, // tag, DecoderSpecificInfoTag
678
678
  0x02, // length
@@ -1037,10 +1037,8 @@ shaka.util.Mp4Generator = class {
1037
1037
  mdat_(streamInfo) {
1038
1038
  const Mp4Generator = shaka.util.Mp4Generator;
1039
1039
  const samples = streamInfo.data ? streamInfo.data.samples : [];
1040
- let bytes = new Uint8Array([]);
1041
- for (const sample of samples) {
1042
- bytes = shaka.util.Uint8ArrayUtils.concat(bytes, sample.data);
1043
- }
1040
+ const allData = samples.map((sample) => sample.data);
1041
+ const bytes = shaka.util.Uint8ArrayUtils.concat(...allData);
1044
1042
  return Mp4Generator.box('mdat', bytes);
1045
1043
  }
1046
1044