shaka-player 4.12.8 → 4.13.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 (261) hide show
  1. package/AUTHORS +1 -0
  2. package/CONTRIBUTORS +4 -0
  3. package/README.md +22 -21
  4. package/cspell.config.yaml +18 -0
  5. package/dist/controls.css +1 -1
  6. package/dist/controls.css.map +1 -1
  7. package/dist/deps.js +29 -24
  8. package/dist/locales.js +33 -33
  9. package/dist/shaka-player.compiled.d.ts +138 -36
  10. package/dist/shaka-player.compiled.debug.d.ts +138 -36
  11. package/dist/shaka-player.compiled.debug.externs.js +367 -107
  12. package/dist/shaka-player.compiled.debug.js +828 -765
  13. package/dist/shaka-player.compiled.debug.map +4 -4
  14. package/dist/shaka-player.compiled.externs.js +367 -107
  15. package/dist/shaka-player.compiled.js +1451 -1416
  16. package/dist/shaka-player.compiled.map +4 -4
  17. package/dist/shaka-player.ui.d.ts +172 -38
  18. package/dist/shaka-player.ui.debug.d.ts +172 -38
  19. package/dist/shaka-player.ui.debug.externs.js +406 -113
  20. package/dist/shaka-player.ui.debug.js +842 -766
  21. package/dist/shaka-player.ui.debug.map +4 -4
  22. package/dist/shaka-player.ui.externs.js +406 -113
  23. package/dist/shaka-player.ui.js +1670 -1628
  24. package/dist/shaka-player.ui.map +4 -4
  25. package/eslint.config.mjs +343 -0
  26. package/externs/airplay.js +1 -1
  27. package/externs/audiotrack.js +1 -1
  28. package/externs/awesomplete.js +1 -1
  29. package/externs/cast-sdk-v2.js +2 -2
  30. package/externs/cmcd.js +16 -1
  31. package/externs/device_sensor_event.js +1 -1
  32. package/externs/ima.js +8 -8
  33. package/externs/isoboxer.js +31 -31
  34. package/externs/jwk_set.js +1 -1
  35. package/externs/lcevc.js +8 -8
  36. package/externs/mediakeys.js +1 -1
  37. package/externs/mediasession.js +3 -2
  38. package/externs/mediatailor.js +18 -18
  39. package/externs/pictureinpicture.js +41 -1
  40. package/externs/playstation.js +2 -2
  41. package/externs/prefixed_eme.js +1 -1
  42. package/externs/shaka/abortable.js +4 -4
  43. package/externs/shaka/abr_manager.js +1 -1
  44. package/externs/shaka/ads.js +45 -6
  45. package/externs/shaka/cea.js +2 -2
  46. package/externs/shaka/codecs.js +4 -4
  47. package/externs/shaka/drm_info.js +6 -6
  48. package/externs/shaka/error.js +5 -5
  49. package/externs/shaka/manifest.js +51 -56
  50. package/externs/shaka/manifest_parser.js +3 -9
  51. package/externs/shaka/net.js +23 -20
  52. package/externs/shaka/offline.js +37 -37
  53. package/externs/shaka/offline_compat_v1.js +10 -10
  54. package/externs/shaka/offline_compat_v2.js +10 -10
  55. package/externs/shaka/player.js +139 -109
  56. package/externs/shaka/text.js +10 -3
  57. package/externs/shaka/transmuxer.js +1 -1
  58. package/externs/videotrack.js +1 -1
  59. package/lib/abr/ewma.js +1 -1
  60. package/lib/abr/simple_abr_manager.js +70 -22
  61. package/lib/ads/ad_manager.js +43 -18
  62. package/lib/ads/ad_utils.js +160 -58
  63. package/lib/ads/ads_stats.js +1 -1
  64. package/lib/ads/client_side_ad_manager.js +2 -2
  65. package/lib/ads/interstitial_ad.js +16 -11
  66. package/lib/ads/interstitial_ad_manager.js +419 -72
  67. package/lib/ads/interstitial_static_ad.js +299 -0
  68. package/lib/ads/media_tailor_ad.js +1 -0
  69. package/lib/ads/media_tailor_ad_manager.js +37 -36
  70. package/lib/ads/server_side_ad_manager.js +7 -6
  71. package/lib/cast/cast_receiver.js +5 -3
  72. package/lib/cast/cast_sender.js +2 -2
  73. package/lib/cast/cast_utils.js +20 -13
  74. package/lib/cea/cea608_data_channel.js +53 -53
  75. package/lib/cea/cea708_service.js +42 -40
  76. package/lib/cea/cea708_window.js +5 -2
  77. package/lib/cea/cea_decoder.js +5 -7
  78. package/lib/cea/mp4_cea_parser.js +1 -1
  79. package/lib/cea/sei_processor.js +1 -1
  80. package/lib/dash/content_protection.js +62 -192
  81. package/lib/dash/dash_parser.js +119 -119
  82. package/lib/dash/mpd_utils.js +14 -13
  83. package/lib/dash/segment_base.js +5 -5
  84. package/lib/dash/segment_list.js +10 -10
  85. package/lib/dash/segment_template.js +55 -53
  86. package/lib/debug/log.js +2 -2
  87. package/lib/dependencies/all.js +2 -1
  88. package/lib/{media → drm}/drm_engine.js +274 -143
  89. package/lib/{util → drm}/drm_utils.js +20 -11
  90. package/lib/drm/playready.js +233 -0
  91. package/lib/hls/hls_classes.js +14 -14
  92. package/lib/hls/hls_parser.js +257 -196
  93. package/lib/hls/hls_utils.js +14 -14
  94. package/lib/hls/manifest_text_parser.js +10 -10
  95. package/lib/media/adaptation_set.js +6 -5
  96. package/lib/media/adaptation_set_criteria.js +51 -379
  97. package/lib/media/buffering_observer.js +5 -4
  98. package/lib/media/closed_caption_parser.js +2 -2
  99. package/lib/media/content_workarounds.js +2 -2
  100. package/lib/media/example_based_criteria.js +69 -0
  101. package/lib/media/gap_jumping_controller.js +14 -1
  102. package/lib/media/manifest_filterer.js +8 -8
  103. package/lib/media/manifest_parser.js +2 -2
  104. package/lib/media/media_source_capabilities.js +20 -1
  105. package/lib/media/media_source_engine.js +84 -35
  106. package/lib/media/mp4_segment_index_parser.js +5 -5
  107. package/lib/media/playhead.js +2 -8
  108. package/lib/media/playhead_observer.js +1 -1
  109. package/lib/media/preference_based_criteria.js +333 -0
  110. package/lib/media/preload_manager.js +53 -37
  111. package/lib/media/presentation_timeline.js +2 -2
  112. package/lib/media/quality_observer.js +35 -35
  113. package/lib/media/region_observer.js +2 -2
  114. package/lib/media/region_timeline.js +3 -3
  115. package/lib/media/segment_index.js +14 -14
  116. package/lib/media/segment_prefetch.js +17 -13
  117. package/lib/media/segment_reference.js +7 -7
  118. package/lib/media/segment_utils.js +9 -9
  119. package/lib/media/streaming_engine.js +77 -38
  120. package/lib/media/time_ranges_utils.js +1 -1
  121. package/lib/media/video_wrapper.js +1 -1
  122. package/lib/media/webm_segment_index_parser.js +4 -4
  123. package/lib/mss/content_protection.js +17 -222
  124. package/lib/mss/mss_parser.js +23 -24
  125. package/lib/net/data_uri_plugin.js +1 -0
  126. package/lib/net/http_fetch_plugin.js +8 -7
  127. package/lib/net/http_plugin_utils.js +5 -2
  128. package/lib/net/http_xhr_plugin.js +4 -3
  129. package/lib/net/networking_engine.js +72 -17
  130. package/lib/net/networking_utils.js +5 -2
  131. package/lib/offline/download_info.js +5 -1
  132. package/lib/offline/download_manager.js +15 -4
  133. package/lib/offline/download_progress_estimator.js +1 -1
  134. package/lib/offline/indexeddb/base_storage_cell.js +9 -9
  135. package/lib/offline/indexeddb/db_connection.js +1 -1
  136. package/lib/offline/indexeddb/db_operation.js +2 -2
  137. package/lib/offline/indexeddb/eme_session_storage_cell.js +1 -1
  138. package/lib/offline/indexeddb/storage_mechanism.js +1 -1
  139. package/lib/offline/indexeddb/v1_storage_cell.js +3 -3
  140. package/lib/offline/indexeddb/v2_storage_cell.js +2 -2
  141. package/lib/offline/manifest_converter.js +11 -12
  142. package/lib/offline/offline_scheme.js +8 -4
  143. package/lib/offline/session_deleter.js +11 -11
  144. package/lib/offline/storage.js +137 -88
  145. package/lib/offline/storage_muxer.js +8 -8
  146. package/lib/offline/stored_content_utils.js +3 -3
  147. package/lib/offline/stream_bandwidth_estimator.js +1 -1
  148. package/lib/player.js +291 -207
  149. package/lib/polyfill/all.js +1 -1
  150. package/lib/polyfill/media_capabilities.js +5 -5
  151. package/lib/polyfill/patchedmediakeys_apple.js +6 -6
  152. package/lib/polyfill/patchedmediakeys_webkit.js +8 -8
  153. package/lib/polyfill/video_play_promise.js +0 -1
  154. package/lib/text/cue.js +3 -2
  155. package/lib/text/lrc_text_parser.js +1 -1
  156. package/lib/text/mp4_ttml_parser.js +1 -1
  157. package/lib/text/mp4_vtt_parser.js +3 -3
  158. package/lib/text/sbv_text_parser.js +1 -1
  159. package/lib/text/simple_text_displayer.js +37 -10
  160. package/lib/text/ssa_text_parser.js +3 -1
  161. package/lib/text/stub_text_displayer.js +12 -5
  162. package/lib/text/text_engine.js +5 -4
  163. package/lib/text/text_utils.js +4 -4
  164. package/lib/text/ttml_text_parser.js +21 -20
  165. package/lib/text/ui_text_displayer.js +20 -13
  166. package/lib/text/vtt_text_parser.js +10 -10
  167. package/lib/text/web_vtt_generator.js +2 -2
  168. package/lib/transmuxer/aac_transmuxer.js +2 -2
  169. package/lib/transmuxer/ac3_transmuxer.js +2 -2
  170. package/lib/transmuxer/adts.js +2 -0
  171. package/lib/transmuxer/ec3.js +3 -3
  172. package/lib/transmuxer/ec3_transmuxer.js +2 -2
  173. package/lib/transmuxer/h264.js +5 -5
  174. package/lib/transmuxer/h265.js +3 -3
  175. package/lib/transmuxer/mp3_transmuxer.js +2 -2
  176. package/lib/transmuxer/mpeg_audio.js +6 -6
  177. package/lib/transmuxer/mss_transmuxer.js +2 -0
  178. package/lib/transmuxer/transmuxer_engine.js +1 -1
  179. package/lib/transmuxer/ts_transmuxer.js +10 -10
  180. package/lib/util/abortable_operation.js +10 -10
  181. package/lib/util/array_utils.js +6 -6
  182. package/lib/util/cmcd_manager.js +149 -18
  183. package/lib/util/cmsd_manager.js +11 -11
  184. package/lib/util/config_utils.js +3 -3
  185. package/lib/util/content_steering_manager.js +17 -17
  186. package/lib/util/data_view_reader.js +3 -3
  187. package/lib/util/ebml_parser.js +1 -1
  188. package/lib/util/error.js +11 -6
  189. package/lib/util/event_manager.js +1 -1
  190. package/lib/util/exp_golomb.js +1 -1
  191. package/lib/util/fairplay_utils.js +6 -1
  192. package/lib/util/fake_event.js +3 -2
  193. package/lib/util/fake_event_target.js +1 -1
  194. package/lib/util/functional.js +8 -8
  195. package/lib/util/id3_utils.js +1 -1
  196. package/lib/util/iterables.js +6 -6
  197. package/lib/util/language_utils.js +17 -17
  198. package/lib/util/manifest_parser_utils.js +13 -13
  199. package/lib/util/map_utils.js +6 -6
  200. package/lib/util/media_ready_state_utils.js +1 -1
  201. package/lib/util/mime_utils.js +15 -4
  202. package/lib/util/mp4_box_parsers.js +5 -5
  203. package/lib/util/mp4_generator.js +31 -30
  204. package/lib/util/mp4_parser.js +2 -2
  205. package/lib/util/multi_map.js +5 -5
  206. package/lib/util/mutex.js +1 -1
  207. package/lib/util/networking.js +1 -1
  208. package/lib/util/object_utils.js +5 -1
  209. package/lib/util/operation_manager.js +1 -1
  210. package/lib/util/periods.js +24 -24
  211. package/lib/util/platform.js +8 -4
  212. package/lib/util/player_configuration.js +50 -17
  213. package/lib/util/pssh.js +34 -6
  214. package/lib/util/public_promise.js +2 -2
  215. package/lib/util/state_history.js +2 -2
  216. package/lib/util/stream_utils.js +138 -120
  217. package/lib/util/string_utils.js +4 -3
  218. package/lib/util/switch_history.js +2 -2
  219. package/lib/util/tXml.js +22 -17
  220. package/lib/util/text_parser.js +2 -2
  221. package/lib/util/timer.js +1 -1
  222. package/lib/util/ts_parser.js +22 -22
  223. package/lib/util/xml_utils.js +1 -0
  224. package/package.json +7 -4
  225. package/project-words.txt +485 -0
  226. package/shaka-player.uncompiled.js +1 -1
  227. package/third_party/closure-uri/uri.js +2 -2
  228. package/third_party/closure-uri/utils.js +2 -2
  229. package/third_party/language-mapping-list/language-mapping-list.js +1 -1
  230. package/ui/ad_statistics_button.js +9 -5
  231. package/ui/airplay_button.js +1 -0
  232. package/ui/audio_language_selection.js +2 -1
  233. package/ui/context_menu.js +2 -2
  234. package/ui/controls.js +7 -7
  235. package/ui/externs/ui.js +29 -21
  236. package/ui/externs/watermark.js +64 -0
  237. package/ui/fast_forward_button.js +1 -1
  238. package/ui/gl_matrix/matrix_4x4.js +11 -5
  239. package/ui/hidden_fast_forward_button.js +1 -1
  240. package/ui/hidden_seek_button.js +1 -1
  241. package/ui/language_utils.js +27 -26
  242. package/ui/less/buttons.less +2 -2
  243. package/ui/localization.js +21 -21
  244. package/ui/loop_button.js +2 -2
  245. package/ui/overflow_menu.js +2 -2
  246. package/ui/playback_rate_selection.js +1 -1
  247. package/ui/presentation_time.js +4 -1
  248. package/ui/range_element.js +2 -2
  249. package/ui/resolution_selection.js +42 -6
  250. package/ui/rewind_button.js +1 -1
  251. package/ui/seek_bar.js +5 -5
  252. package/ui/statistics_button.js +8 -4
  253. package/ui/text_selection.js +3 -2
  254. package/ui/ui.js +32 -2
  255. package/ui/vr_manager.js +3 -3
  256. package/ui/vr_utils.js +14 -14
  257. package/ui/vr_webgl.js +5 -5
  258. package/ui/watermark.js +313 -0
  259. package/.eslintignore +0 -4
  260. package/.eslintrc.js +0 -310
  261. package/lib/polyfill/patchedmediakeys_nop.js +0 -148
@@ -38,8 +38,8 @@ shaka.extern.TextParser = class {
38
38
  * for each cue.
39
39
  * @param {?(string|undefined)} uri
40
40
  * The media uri.
41
- * @param {!Array.<string>} images
42
- * @return {!Array.<!shaka.text.Cue>}
41
+ * @param {!Array<string>} images
42
+ * @return {!Array<!shaka.text.Cue>}
43
43
  *
44
44
  * @exportDoc
45
45
  */
@@ -143,7 +143,7 @@ shaka.extern.TextDisplayer = class {
143
143
  /**
144
144
  * Append given text cues to the list of cues to be displayed.
145
145
  *
146
- * @param {!Array.<!shaka.text.Cue>} cues
146
+ * @param {!Array<!shaka.text.Cue>} cues
147
147
  * Text cues to be appended.
148
148
  *
149
149
  * @exportDoc
@@ -192,6 +192,13 @@ shaka.extern.TextDisplayer = class {
192
192
  * @exportDoc
193
193
  */
194
194
  setTextLanguage(language) {}
195
+
196
+ /**
197
+ * Enable the current text displayer.
198
+ *
199
+ * @exportDoc
200
+ */
201
+ enableTextDisplayer() {}
195
202
  };
196
203
 
197
204
 
@@ -53,7 +53,7 @@ shaka.extern.Transmuxer = class {
53
53
  * null for init segments
54
54
  * @param {number} duration
55
55
  * @param {string} contentType
56
- * @return {!Promise.<!Uint8Array>}
56
+ * @return {!Promise<!Uint8Array>}
57
57
  */
58
58
  transmux(data, stream, reference, duration, contentType) {}
59
59
  };
@@ -34,7 +34,7 @@ VideoTrack.prototype.sourceBuffer;
34
34
 
35
35
 
36
36
  /**
37
- * @extends {IArrayLike.<VideoTrack>}
37
+ * @extends {IArrayLike<VideoTrack>}
38
38
  * @extends {EventTarget}
39
39
  * @interface
40
40
  */
package/lib/abr/ewma.js CHANGED
@@ -11,7 +11,7 @@ goog.require('goog.asserts');
11
11
 
12
12
  /**
13
13
  * @summary
14
- * This class computes an exponentionally-weighted moving average.
14
+ * This class computes an exponentially-weighted moving average.
15
15
  */
16
16
  shaka.abr.Ewma = class {
17
17
  /**
@@ -79,7 +79,7 @@ shaka.abr.SimpleAbrManager = class {
79
79
 
80
80
  /**
81
81
  * A filtered list of Variants to choose from.
82
- * @private {!Array.<!shaka.extern.Variant>}
82
+ * @private {!Array<!shaka.extern.Variant>}
83
83
  */
84
84
  this.variants_ = [];
85
85
 
@@ -107,7 +107,8 @@ shaka.abr.SimpleAbrManager = class {
107
107
 
108
108
  /** @private {shaka.util.Timer} */
109
109
  this.resizeObserverTimer_ = new shaka.util.Timer(() => {
110
- if (this.enabled_ && this.config_.restrictToElementSize) {
110
+ if (this.enabled_ && (this.config_.restrictToElementSize ||
111
+ this.config_.restrictToScreenSize)) {
111
112
  const chosenVariant = this.chooseVariant();
112
113
  if (chosenVariant) {
113
114
  this.switch_(chosenVariant, this.config_.clearBufferSwitch,
@@ -116,6 +117,29 @@ shaka.abr.SimpleAbrManager = class {
116
117
  }
117
118
  });
118
119
 
120
+ /** @private {Window} */
121
+ this.windowToCheck_ = window;
122
+
123
+ if ('documentPictureInPicture' in window) {
124
+ this.eventManager_.listen(
125
+ window.documentPictureInPicture, 'enter', () => {
126
+ this.windowToCheck_ = window.documentPictureInPicture.window;
127
+ if (this.resizeObserverTimer_) {
128
+ this.resizeObserverTimer_.tickNow();
129
+ }
130
+ this.eventManager_.listenOnce(
131
+ this.windowToCheck_, 'pagehide', () => {
132
+ this.windowToCheck_ = window;
133
+ if (this.resizeObserverTimer_) {
134
+ this.resizeObserverTimer_.tickNow();
135
+ }
136
+ });
137
+ });
138
+ }
139
+
140
+ /** @private {PictureInPictureWindow} */
141
+ this.pictureInPictureWindow_ = null;
142
+
119
143
  /** @private {?shaka.util.CmsdManager} */
120
144
  this.cmsdManager_ = null;
121
145
  }
@@ -140,6 +164,8 @@ shaka.abr.SimpleAbrManager = class {
140
164
 
141
165
  this.resizeObserverTimer_.stop();
142
166
 
167
+ this.pictureInPictureWindow_ = null;
168
+
143
169
  this.cmsdManager_ = null;
144
170
 
145
171
  // Don't reset |startupComplete_|: if we've left the startup interval, we
@@ -176,19 +202,24 @@ shaka.abr.SimpleAbrManager = class {
176
202
  let maxWidth = Infinity;
177
203
 
178
204
  if (this.config_.restrictToScreenSize) {
179
- const devicePixelRatio =
180
- this.config_.ignoreDevicePixelRatio ? 1 : window.devicePixelRatio;
181
- maxHeight = window.screen.height * devicePixelRatio;
182
- maxWidth = window.screen.width * devicePixelRatio;
205
+ const devicePixelRatio = this.config_.ignoreDevicePixelRatio ?
206
+ 1 : this.windowToCheck_.devicePixelRatio;
207
+ maxHeight = this.windowToCheck_.screen.height * devicePixelRatio;
208
+ maxWidth = this.windowToCheck_.screen.width * devicePixelRatio;
183
209
  }
184
210
 
185
211
  if (this.resizeObserver_ && this.config_.restrictToElementSize) {
186
- const devicePixelRatio =
187
- this.config_.ignoreDevicePixelRatio ? 1 : window.devicePixelRatio;
188
- maxHeight = Math.min(
189
- maxHeight, this.mediaElement_.clientHeight * devicePixelRatio);
190
- maxWidth = Math.min(
191
- maxWidth, this.mediaElement_.clientWidth * devicePixelRatio);
212
+ const devicePixelRatio = this.config_.ignoreDevicePixelRatio ?
213
+ 1 : this.windowToCheck_.devicePixelRatio;
214
+ let height = this.mediaElement_.clientHeight;
215
+ let width = this.mediaElement_.clientWidth;
216
+ if (this.pictureInPictureWindow_ && document.pictureInPictureElement &&
217
+ document.pictureInPictureElement == this.mediaElement_) {
218
+ height = this.pictureInPictureWindow_.height;
219
+ width = this.pictureInPictureWindow_.width;
220
+ }
221
+ maxHeight = Math.min(maxHeight, height * devicePixelRatio);
222
+ maxWidth = Math.min(maxWidth, width * devicePixelRatio);
192
223
  }
193
224
 
194
225
  let normalVariants = this.variants_.filter((variant) => {
@@ -386,15 +417,32 @@ shaka.abr.SimpleAbrManager = class {
386
417
  this.resizeObserver_.disconnect();
387
418
  this.resizeObserver_ = null;
388
419
  }
420
+ const onResize = () => {
421
+ const SimpleAbrManager = shaka.abr.SimpleAbrManager;
422
+ // Batch up resize changes before checking them.
423
+ this.resizeObserverTimer_.tickAfter(
424
+ /* seconds= */ SimpleAbrManager.RESIZE_OBSERVER_BATCH_TIME);
425
+ };
389
426
  if (this.mediaElement_ && 'ResizeObserver' in window) {
390
- this.resizeObserver_ = new ResizeObserver(() => {
391
- const SimpleAbrManager = shaka.abr.SimpleAbrManager;
392
- // Batch up resize changes before checking them.
393
- this.resizeObserverTimer_.tickAfter(
394
- /* seconds= */ SimpleAbrManager.RESIZE_OBSERVER_BATCH_TIME);
395
- });
427
+ this.resizeObserver_ = new ResizeObserver(onResize);
396
428
  this.resizeObserver_.observe(this.mediaElement_);
397
429
  }
430
+
431
+ this.eventManager_.listen(mediaElement, 'enterpictureinpicture', (e) => {
432
+ const event = /** @type {PictureInPictureEvent} */(e);
433
+ if (event.pictureInPictureWindow) {
434
+ this.pictureInPictureWindow_ = event.pictureInPictureWindow;
435
+ this.eventManager_.listen(
436
+ this.pictureInPictureWindow_, 'resize', onResize);
437
+ }
438
+ });
439
+ this.eventManager_.listen(mediaElement, 'leavepictureinpicture', () => {
440
+ if (this.pictureInPictureWindow_) {
441
+ this.eventManager_.unlisten(
442
+ this.pictureInPictureWindow_, 'resize', onResize);
443
+ }
444
+ this.pictureInPictureWindow_ = null;
445
+ });
398
446
  }
399
447
 
400
448
 
@@ -485,10 +533,10 @@ shaka.abr.SimpleAbrManager = class {
485
533
 
486
534
  /**
487
535
  * @param {?shaka.extern.Restrictions} restrictions
488
- * @param {!Array.<shaka.extern.Variant>} variants
536
+ * @param {!Array<shaka.extern.Variant>} variants
489
537
  * @param {!number} maxHeight
490
538
  * @param {!number} maxWidth
491
- * @return {!Array.<shaka.extern.Variant>} variants filtered according to
539
+ * @return {!Array<shaka.extern.Variant>} variants filtered according to
492
540
  * |restrictions| and sorted in ascending order of bandwidth.
493
541
  * @private
494
542
  */
@@ -523,8 +571,8 @@ shaka.abr.SimpleAbrManager = class {
523
571
  }
524
572
 
525
573
  /**
526
- * @param {!Array.<shaka.extern.Variant>} variants
527
- * @return {!Array.<{height: number, width: number}>}
574
+ * @param {!Array<shaka.extern.Variant>} variants
575
+ * @return {!Array<{height: number, width: number}>}
528
576
  * @private
529
577
  */
530
578
  getResolutionList_(variants) {
@@ -21,6 +21,7 @@ goog.require('shaka.util.Error');
21
21
  goog.require('shaka.util.FakeEvent');
22
22
  goog.require('shaka.util.FakeEventTarget');
23
23
  goog.require('shaka.util.IReleasable');
24
+ goog.require('shaka.util.TXml');
24
25
 
25
26
 
26
27
  /**
@@ -177,7 +178,7 @@ goog.require('shaka.util.IReleasable');
177
178
  * change.
178
179
  * @property {string} type
179
180
  * 'ad-cue-points-changed'
180
- * @property {!Array.<!shaka.extern.AdCuePoint>} cuepoints
181
+ * @property {!Array<!shaka.extern.AdCuePoint>} cuepoints
181
182
  * The ad cue points, if available.
182
183
  * @exportDoc
183
184
  */
@@ -537,9 +538,9 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
537
538
 
538
539
 
539
540
  /**
540
- * @override
541
- * @export
542
- */
541
+ * @override
542
+ * @export
543
+ */
543
544
  onAssetUnload() {
544
545
  if (this.interstitialAdManager_) {
545
546
  this.interstitialAdManager_.stop();
@@ -614,7 +615,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
614
615
  * @param {string} url
615
616
  * @param {Object} adsParams
616
617
  * @param {string=} backupUrl
617
- * @return {!Promise.<string>}
618
+ * @return {!Promise<string>}
618
619
  * @override
619
620
  * @export
620
621
  */
@@ -681,7 +682,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
681
682
  /**
682
683
  * @param {!google.ima.dai.api.StreamRequest} imaRequest
683
684
  * @param {string=} backupUrl
684
- * @return {!Promise.<string>}
685
+ * @return {!Promise<string>}
685
686
  * @override
686
687
  * @export
687
688
  */
@@ -701,7 +702,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
701
702
  if (adTagParams['mpt'] || adTagParams['mpv']) {
702
703
  shaka.log.alwaysWarn('You have attempted to set "mpt" and/or "mpv" ' +
703
704
  'parameters of the ad tag. Please note that those parameters are ' +
704
- 'used for Shaka adoption tracking and will be overriden.');
705
+ 'used for Shaka adoption tracking and will be overridden.');
705
706
  }
706
707
 
707
708
  // Set player and version parameters for tracking
@@ -726,7 +727,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
726
727
  if (adTagParameters['mpt'] || adTagParameters['mpv']) {
727
728
  shaka.log.alwaysWarn('You have attempted to set "mpt" and/or "mpv" ' +
728
729
  'parameters of the ad tag. Please note that those parameters are ' +
729
- 'used for Shaka adoption tracking and will be overriden.');
730
+ 'used for Shaka adoption tracking and will be overridden.');
730
731
  }
731
732
 
732
733
  adTagParameters['mpt'] = 'Shaka Player';
@@ -737,7 +738,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
737
738
 
738
739
 
739
740
  /**
740
- * @return {!Array.<!shaka.extern.AdCuePoint>}
741
+ * @return {!Array<!shaka.extern.AdCuePoint>}
741
742
  * @override
742
743
  * @export
743
744
  */
@@ -750,7 +751,7 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
750
751
 
751
752
 
752
753
  /**
753
- * @return {!Array.<!shaka.extern.AdCuePoint>}
754
+ * @return {!Array<!shaka.extern.AdCuePoint>}
754
755
  * @override
755
756
  * @export
756
757
  */
@@ -843,14 +844,24 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
843
844
  if (this.config_ && this.config_.disableDASHInterstitial) {
844
845
  return;
845
846
  }
846
- if (region.schemeIdUri != 'urn:mpeg:dash:event:alternativeMPD:2022') {
847
- return;
848
- }
849
- if (!this.interstitialAdManager_) {
850
- this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
851
- }
852
- if (this.interstitialAdManager_) {
853
- this.interstitialAdManager_.addRegion(region);
847
+ const schemeIdUri = region.schemeIdUri;
848
+ if (schemeIdUri == 'urn:mpeg:dash:event:alternativeMPD:insert:2025' ||
849
+ schemeIdUri == 'urn:mpeg:dash:event:alternativeMPD:replace:2025') {
850
+ if (!this.interstitialAdManager_) {
851
+ this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
852
+ }
853
+ if (this.interstitialAdManager_) {
854
+ this.interstitialAdManager_.addRegion(region);
855
+ }
856
+ } else if (schemeIdUri == 'urn:mpeg:dash:event:2012' &&
857
+ region.eventNode &&
858
+ shaka.util.TXml.findChild(region.eventNode, 'OverlayEvent')) {
859
+ if (!this.interstitialAdManager_) {
860
+ this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
861
+ }
862
+ if (this.interstitialAdManager_) {
863
+ this.interstitialAdManager_.addOverlayRegion(region);
864
+ }
854
865
  }
855
866
  }
856
867
 
@@ -882,6 +893,20 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
882
893
  return this.interstitialAdManager_.addAdUrlInterstitial(url);
883
894
  }
884
895
 
896
+ /**
897
+ * @override
898
+ * @export
899
+ */
900
+ getInterstitialPlayer() {
901
+ if (!this.interstitialAdManager_) {
902
+ throw new shaka.util.Error(
903
+ shaka.util.Error.Severity.RECOVERABLE,
904
+ shaka.util.Error.Category.ADS,
905
+ shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
906
+ }
907
+ return this.interstitialAdManager_.getPlayer();
908
+ }
909
+
885
910
  /**
886
911
  * @param {!shaka.util.FakeEvent} event
887
912
  * @private
@@ -19,18 +19,13 @@ shaka.ads.Utils = class {
19
19
  /**
20
20
  * @param {!shaka.extern.xml.Node} vast
21
21
  * @param {?number} currentTime
22
- * @return {!Array.<shaka.extern.AdInterstitial>}
22
+ * @return {!Array<shaka.extern.AdInterstitial>}
23
23
  */
24
24
  static parseVastToInterstitials(vast, currentTime) {
25
25
  const TXml = shaka.util.TXml;
26
- /** @type {!Array.<shaka.extern.AdInterstitial>} */
26
+ /** @type {!Array<shaka.extern.AdInterstitial>} */
27
27
  const interstitials = [];
28
28
 
29
- let startTime = 0;
30
- if (currentTime != null) {
31
- startTime = currentTime;
32
- }
33
-
34
29
  for (const ad of TXml.findChildren(vast, 'Ad')) {
35
30
  const inline = TXml.findChild(ad, 'InLine');
36
31
  if (!inline) {
@@ -42,70 +37,177 @@ shaka.ads.Utils = class {
42
37
  }
43
38
  for (const creative of TXml.findChildren(creatives, 'Creative')) {
44
39
  const linear = TXml.findChild(creative, 'Linear');
45
- if (!linear) {
46
- continue;
47
- }
48
- let skipOffset = null;
49
- if (linear.attributes['skipoffset']) {
50
- skipOffset = shaka.util.TextParser.parseTime(
51
- linear.attributes['skipoffset']);
52
- if (isNaN(skipOffset)) {
53
- skipOffset = null;
54
- }
55
- }
56
- const mediaFiles = TXml.findChild(linear, 'MediaFiles');
57
- if (!mediaFiles) {
58
- continue;
59
- }
60
- const medias = TXml.findChildren(mediaFiles, 'MediaFile');
61
- let checkMedias = medias;
62
- const streamingMedias = medias.filter((media) => {
63
- return media.attributes['delivery'] == 'streaming';
64
- });
65
- if (streamingMedias.length) {
66
- checkMedias = streamingMedias;
40
+ if (linear) {
41
+ shaka.ads.Utils.processLinearAd_(
42
+ interstitials, currentTime, linear);
67
43
  }
68
- const sortedMedias = checkMedias.sort((a, b) => {
69
- const aHeight = parseInt(a.attributes['height'], 10) || 0;
70
- const bHeight = parseInt(b.attributes['height'], 10) || 0;
71
- return bHeight - aHeight;
72
- });
73
- for (const media of sortedMedias) {
74
- const adUrl = TXml.getTextContents(media);
75
- if (!adUrl) {
76
- continue;
44
+ const nonLinearAds = TXml.findChild(creative, 'NonLinearAds');
45
+ if (nonLinearAds) {
46
+ const nonLinears = TXml.findChildren(nonLinearAds, 'NonLinear');
47
+ for (const nonLinear of nonLinears) {
48
+ shaka.ads.Utils.processNonLinearAd_(
49
+ interstitials, currentTime, nonLinear);
77
50
  }
78
- interstitials.push({
79
- id: null,
80
- startTime: startTime,
81
- endTime: null,
82
- uri: adUrl,
83
- mimeType: media.attributes['type'] || null,
84
- isSkippable: skipOffset != null,
85
- skipOffset,
86
- skipFor: null,
87
- canJump: false,
88
- resumeOffset: 0,
89
- playoutLimit: null,
90
- once: true,
91
- pre: currentTime == null,
92
- post: currentTime == Infinity,
93
- timelineRange: false,
94
- });
95
- break;
96
51
  }
97
52
  }
98
53
  }
99
54
  return interstitials;
100
55
  }
101
56
 
57
+ /**
58
+ * @param {!Array<shaka.extern.AdInterstitial>} interstitials
59
+ * @param {?number} currentTime
60
+ * @param {!shaka.extern.xml.Node} linear
61
+ * @private
62
+ */
63
+ static processLinearAd_(interstitials, currentTime, linear) {
64
+ const TXml = shaka.util.TXml;
65
+ let startTime = 0;
66
+ if (currentTime != null) {
67
+ startTime = currentTime;
68
+ }
69
+ let skipOffset = null;
70
+ if (linear.attributes['skipoffset']) {
71
+ skipOffset = shaka.util.TextParser.parseTime(
72
+ linear.attributes['skipoffset']);
73
+ if (isNaN(skipOffset)) {
74
+ skipOffset = null;
75
+ }
76
+ }
77
+ const mediaFiles = TXml.findChild(linear, 'MediaFiles');
78
+ if (!mediaFiles) {
79
+ return;
80
+ }
81
+ const medias = TXml.findChildren(mediaFiles, 'MediaFile');
82
+ let checkMedias = medias;
83
+ const streamingMedias = medias.filter((media) => {
84
+ return media.attributes['delivery'] == 'streaming';
85
+ });
86
+ if (streamingMedias.length) {
87
+ checkMedias = streamingMedias;
88
+ }
89
+ const sortedMedias = checkMedias.sort((a, b) => {
90
+ const aHeight = parseInt(a.attributes['height'], 10) || 0;
91
+ const bHeight = parseInt(b.attributes['height'], 10) || 0;
92
+ return bHeight - aHeight;
93
+ });
94
+ for (const media of sortedMedias) {
95
+ if (media.attributes['apiFramework']) {
96
+ continue;
97
+ }
98
+ const adUrl = TXml.getContents(media);
99
+ if (!adUrl) {
100
+ continue;
101
+ }
102
+ interstitials.push({
103
+ id: null,
104
+ groupId: null,
105
+ startTime: startTime,
106
+ endTime: null,
107
+ uri: adUrl,
108
+ mimeType: media.attributes['type'] || null,
109
+ isSkippable: skipOffset != null,
110
+ skipOffset,
111
+ skipFor: null,
112
+ canJump: false,
113
+ resumeOffset: 0,
114
+ playoutLimit: null,
115
+ once: true,
116
+ pre: currentTime == null,
117
+ post: currentTime == Infinity,
118
+ timelineRange: false,
119
+ loop: false,
120
+ overlay: null,
121
+ });
122
+ break;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * @param {!Array<shaka.extern.AdInterstitial>} interstitials
128
+ * @param {?number} currentTime
129
+ * @param {!shaka.extern.xml.Node} nonLinear
130
+ * @private
131
+ */
132
+ static processNonLinearAd_(interstitials, currentTime, nonLinear) {
133
+ const TXml = shaka.util.TXml;
134
+ let mimeType = null;
135
+ let resource = TXml.findChild(nonLinear, 'StaticResource');
136
+ if (resource) {
137
+ mimeType = resource.attributes['creativeType'];
138
+ } else {
139
+ resource = TXml.findChild(nonLinear, 'HTMLResource');
140
+ if (!resource) {
141
+ return;
142
+ }
143
+ mimeType = 'text/html';
144
+ }
145
+ let adUrl = TXml.getContents(resource);
146
+ if (!adUrl) {
147
+ return;
148
+ }
149
+ if (mimeType === 'text/html') {
150
+ adUrl = 'data:text/html;charset=UTF-8,' + encodeURIComponent(adUrl);
151
+ }
152
+ const width = TXml.parseAttr(nonLinear, 'width', TXml.parseInt) ||
153
+ TXml.parseAttr(nonLinear, 'expandedWidth', TXml.parseInt);
154
+ const height = TXml.parseAttr(nonLinear, 'height', TXml.parseInt) ||
155
+ TXml.parseAttr(nonLinear, 'expandedHeight', TXml.parseInt);
156
+ if (!width && !height) {
157
+ return;
158
+ }
159
+ let playoutLimit = null;
160
+ const minSuggestedDuration =
161
+ nonLinear.attributes['minSuggestedDuration'];
162
+ if (minSuggestedDuration) {
163
+ playoutLimit = shaka.util.TextParser.parseTime(minSuggestedDuration);
164
+ }
165
+ let startTime = 0;
166
+ if (currentTime != null) {
167
+ startTime = currentTime;
168
+ }
169
+ interstitials.push({
170
+ id: null,
171
+ groupId: null,
172
+ startTime: startTime,
173
+ endTime: null,
174
+ uri: adUrl,
175
+ mimeType,
176
+ isSkippable: false,
177
+ skipOffset: null,
178
+ skipFor: null,
179
+ canJump: false,
180
+ resumeOffset: 0,
181
+ playoutLimit,
182
+ once: true,
183
+ pre: currentTime == null,
184
+ post: currentTime == Infinity,
185
+ timelineRange: false,
186
+ loop: false,
187
+ overlay: {
188
+ viewport: {
189
+ x: 0,
190
+ y: 0,
191
+ },
192
+ topLeft: {
193
+ x: 0,
194
+ y: 0,
195
+ },
196
+ size: {
197
+ x: width || 0,
198
+ y: height || 0,
199
+ },
200
+ },
201
+ });
202
+ }
203
+
102
204
  /**
103
205
  * @param {!shaka.extern.xml.Node} vmap
104
- * @return {!Array.<{time: ?number, uri: string}>}
206
+ * @return {!Array<{time: ?number, uri: string}>}
105
207
  */
106
208
  static parseVMAP(vmap) {
107
209
  const TXml = shaka.util.TXml;
108
- /** @type {!Array.<{time: ?number, uri: string}>} */
210
+ /** @type {!Array<{time: ?number, uri: string}>} */
109
211
  const ads = [];
110
212
  for (const adBreak of TXml.findChildren(vmap, 'vmap:AdBreak')) {
111
213
  const timeOffset = adBreak.attributes['timeOffset'];
@@ -16,7 +16,7 @@ goog.provide('shaka.ads.AdsStats');
16
16
  shaka.ads.AdsStats = class {
17
17
  /** */
18
18
  constructor() {
19
- /** @private {!Array.<number>} */
19
+ /** @private {!Array<number>} */
20
20
  this.loadTimes_ = [];
21
21
  /** @private {number} */
22
22
  this.started_ = 0;
@@ -250,7 +250,7 @@ shaka.ads.ClientSideAdManager = class {
250
250
 
251
251
  const cuePointStarts = this.imaAdsManager_.getCuePoints();
252
252
  if (cuePointStarts.length) {
253
- /** @type {!Array.<!shaka.extern.AdCuePoint>} */
253
+ /** @type {!Array<!shaka.extern.AdCuePoint>} */
254
254
  const cuePoints = [];
255
255
  for (const start of cuePointStarts) {
256
256
  /** @type {shaka.extern.AdCuePoint} */
@@ -303,7 +303,7 @@ shaka.ads.ClientSideAdManager = class {
303
303
  }
304
304
 
305
305
  // Single video and overlay ads will start at this time
306
- // TODO (ismena): Need a better inderstanding of what this does.
306
+ // TODO (ismena): Need a better understanding of what this does.
307
307
  // The docs say it's called to 'start playing the ads,' but I haven't
308
308
  // seen the ads actually play until requestAds() is called.
309
309
  // Note: We listen for a play event to avoid autoplay issues that might