shaka-player 4.12.9 → 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 (259) 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 +36 -36
  9. package/dist/shaka-player.compiled.d.ts +131 -36
  10. package/dist/shaka-player.compiled.debug.d.ts +131 -36
  11. package/dist/shaka-player.compiled.debug.externs.js +355 -107
  12. package/dist/shaka-player.compiled.debug.js +799 -742
  13. package/dist/shaka-player.compiled.debug.map +4 -4
  14. package/dist/shaka-player.compiled.externs.js +355 -107
  15. package/dist/shaka-player.compiled.js +1456 -1423
  16. package/dist/shaka-player.compiled.map +4 -4
  17. package/dist/shaka-player.ui.d.ts +165 -38
  18. package/dist/shaka-player.ui.debug.d.ts +165 -38
  19. package/dist/shaka-player.ui.debug.externs.js +394 -113
  20. package/dist/shaka-player.ui.debug.js +808 -738
  21. package/dist/shaka-player.ui.debug.map +4 -4
  22. package/dist/shaka-player.ui.externs.js +394 -113
  23. package/dist/shaka-player.ui.js +1671 -1632
  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 +137 -108
  56. package/externs/shaka/text.js +3 -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 +34 -24
  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 +98 -108
  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 +14 -14
  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/manifest_filterer.js +8 -8
  102. package/lib/media/manifest_parser.js +2 -2
  103. package/lib/media/media_source_capabilities.js +20 -1
  104. package/lib/media/media_source_engine.js +71 -26
  105. package/lib/media/mp4_segment_index_parser.js +5 -5
  106. package/lib/media/playhead.js +2 -8
  107. package/lib/media/playhead_observer.js +1 -1
  108. package/lib/media/preference_based_criteria.js +333 -0
  109. package/lib/media/preload_manager.js +53 -37
  110. package/lib/media/presentation_timeline.js +2 -2
  111. package/lib/media/quality_observer.js +35 -35
  112. package/lib/media/region_observer.js +2 -2
  113. package/lib/media/region_timeline.js +3 -3
  114. package/lib/media/segment_index.js +14 -14
  115. package/lib/media/segment_prefetch.js +17 -13
  116. package/lib/media/segment_reference.js +7 -7
  117. package/lib/media/segment_utils.js +9 -9
  118. package/lib/media/streaming_engine.js +77 -38
  119. package/lib/media/time_ranges_utils.js +1 -1
  120. package/lib/media/video_wrapper.js +1 -1
  121. package/lib/media/webm_segment_index_parser.js +4 -4
  122. package/lib/mss/content_protection.js +17 -222
  123. package/lib/mss/mss_parser.js +23 -24
  124. package/lib/net/data_uri_plugin.js +1 -0
  125. package/lib/net/http_fetch_plugin.js +8 -7
  126. package/lib/net/http_plugin_utils.js +5 -2
  127. package/lib/net/http_xhr_plugin.js +4 -3
  128. package/lib/net/networking_engine.js +72 -17
  129. package/lib/net/networking_utils.js +5 -2
  130. package/lib/offline/download_info.js +5 -1
  131. package/lib/offline/download_manager.js +15 -4
  132. package/lib/offline/download_progress_estimator.js +1 -1
  133. package/lib/offline/indexeddb/base_storage_cell.js +9 -9
  134. package/lib/offline/indexeddb/db_connection.js +1 -1
  135. package/lib/offline/indexeddb/db_operation.js +2 -2
  136. package/lib/offline/indexeddb/eme_session_storage_cell.js +1 -1
  137. package/lib/offline/indexeddb/storage_mechanism.js +1 -1
  138. package/lib/offline/indexeddb/v1_storage_cell.js +3 -3
  139. package/lib/offline/indexeddb/v2_storage_cell.js +2 -2
  140. package/lib/offline/manifest_converter.js +11 -12
  141. package/lib/offline/offline_scheme.js +8 -4
  142. package/lib/offline/session_deleter.js +11 -11
  143. package/lib/offline/storage.js +137 -88
  144. package/lib/offline/storage_muxer.js +8 -8
  145. package/lib/offline/stored_content_utils.js +3 -3
  146. package/lib/offline/stream_bandwidth_estimator.js +1 -1
  147. package/lib/player.js +270 -207
  148. package/lib/polyfill/all.js +1 -1
  149. package/lib/polyfill/media_capabilities.js +5 -5
  150. package/lib/polyfill/patchedmediakeys_apple.js +6 -6
  151. package/lib/polyfill/patchedmediakeys_webkit.js +8 -8
  152. package/lib/polyfill/video_play_promise.js +0 -1
  153. package/lib/text/cue.js +3 -2
  154. package/lib/text/lrc_text_parser.js +1 -1
  155. package/lib/text/mp4_ttml_parser.js +1 -1
  156. package/lib/text/mp4_vtt_parser.js +3 -3
  157. package/lib/text/sbv_text_parser.js +1 -1
  158. package/lib/text/ssa_text_parser.js +3 -1
  159. package/lib/text/stub_text_displayer.js +5 -5
  160. package/lib/text/text_engine.js +5 -4
  161. package/lib/text/text_utils.js +4 -4
  162. package/lib/text/ttml_text_parser.js +21 -20
  163. package/lib/text/ui_text_displayer.js +13 -13
  164. package/lib/text/vtt_text_parser.js +10 -10
  165. package/lib/text/web_vtt_generator.js +2 -2
  166. package/lib/transmuxer/aac_transmuxer.js +2 -2
  167. package/lib/transmuxer/ac3_transmuxer.js +2 -2
  168. package/lib/transmuxer/adts.js +2 -0
  169. package/lib/transmuxer/ec3.js +3 -3
  170. package/lib/transmuxer/ec3_transmuxer.js +2 -2
  171. package/lib/transmuxer/h264.js +5 -5
  172. package/lib/transmuxer/h265.js +3 -3
  173. package/lib/transmuxer/mp3_transmuxer.js +2 -2
  174. package/lib/transmuxer/mpeg_audio.js +6 -6
  175. package/lib/transmuxer/mss_transmuxer.js +2 -0
  176. package/lib/transmuxer/transmuxer_engine.js +1 -1
  177. package/lib/transmuxer/ts_transmuxer.js +10 -10
  178. package/lib/util/abortable_operation.js +10 -10
  179. package/lib/util/array_utils.js +6 -6
  180. package/lib/util/cmcd_manager.js +149 -18
  181. package/lib/util/cmsd_manager.js +11 -11
  182. package/lib/util/config_utils.js +3 -3
  183. package/lib/util/content_steering_manager.js +17 -17
  184. package/lib/util/data_view_reader.js +3 -3
  185. package/lib/util/ebml_parser.js +1 -1
  186. package/lib/util/error.js +11 -6
  187. package/lib/util/event_manager.js +1 -1
  188. package/lib/util/exp_golomb.js +1 -1
  189. package/lib/util/fairplay_utils.js +6 -1
  190. package/lib/util/fake_event.js +3 -2
  191. package/lib/util/fake_event_target.js +1 -1
  192. package/lib/util/functional.js +8 -8
  193. package/lib/util/id3_utils.js +1 -1
  194. package/lib/util/iterables.js +6 -6
  195. package/lib/util/language_utils.js +17 -17
  196. package/lib/util/manifest_parser_utils.js +13 -13
  197. package/lib/util/map_utils.js +6 -6
  198. package/lib/util/media_ready_state_utils.js +1 -1
  199. package/lib/util/mime_utils.js +15 -4
  200. package/lib/util/mp4_box_parsers.js +5 -5
  201. package/lib/util/mp4_generator.js +31 -30
  202. package/lib/util/mp4_parser.js +2 -2
  203. package/lib/util/multi_map.js +5 -5
  204. package/lib/util/mutex.js +1 -1
  205. package/lib/util/networking.js +1 -1
  206. package/lib/util/object_utils.js +5 -1
  207. package/lib/util/operation_manager.js +1 -1
  208. package/lib/util/periods.js +24 -24
  209. package/lib/util/platform.js +8 -4
  210. package/lib/util/player_configuration.js +50 -17
  211. package/lib/util/pssh.js +34 -6
  212. package/lib/util/public_promise.js +2 -2
  213. package/lib/util/state_history.js +2 -2
  214. package/lib/util/stream_utils.js +138 -120
  215. package/lib/util/string_utils.js +4 -3
  216. package/lib/util/switch_history.js +2 -2
  217. package/lib/util/tXml.js +22 -17
  218. package/lib/util/text_parser.js +2 -2
  219. package/lib/util/timer.js +1 -1
  220. package/lib/util/ts_parser.js +22 -22
  221. package/lib/util/xml_utils.js +1 -0
  222. package/package.json +7 -4
  223. package/project-words.txt +485 -0
  224. package/shaka-player.uncompiled.js +1 -1
  225. package/third_party/closure-uri/uri.js +2 -2
  226. package/third_party/closure-uri/utils.js +2 -2
  227. package/third_party/language-mapping-list/language-mapping-list.js +1 -1
  228. package/ui/ad_statistics_button.js +9 -5
  229. package/ui/airplay_button.js +1 -0
  230. package/ui/audio_language_selection.js +2 -1
  231. package/ui/context_menu.js +2 -2
  232. package/ui/controls.js +7 -7
  233. package/ui/externs/ui.js +29 -21
  234. package/ui/externs/watermark.js +64 -0
  235. package/ui/fast_forward_button.js +1 -1
  236. package/ui/gl_matrix/matrix_4x4.js +11 -5
  237. package/ui/hidden_fast_forward_button.js +1 -1
  238. package/ui/hidden_seek_button.js +1 -1
  239. package/ui/language_utils.js +27 -26
  240. package/ui/less/buttons.less +2 -2
  241. package/ui/localization.js +21 -21
  242. package/ui/loop_button.js +2 -2
  243. package/ui/overflow_menu.js +2 -2
  244. package/ui/playback_rate_selection.js +1 -1
  245. package/ui/presentation_time.js +4 -1
  246. package/ui/range_element.js +2 -2
  247. package/ui/resolution_selection.js +42 -6
  248. package/ui/rewind_button.js +1 -1
  249. package/ui/seek_bar.js +5 -5
  250. package/ui/statistics_button.js +8 -4
  251. package/ui/text_selection.js +3 -2
  252. package/ui/ui.js +32 -2
  253. package/ui/vr_manager.js +3 -3
  254. package/ui/vr_utils.js +14 -14
  255. package/ui/vr_webgl.js +5 -5
  256. package/ui/watermark.js +313 -0
  257. package/.eslintignore +0 -4
  258. package/.eslintrc.js +0 -310
  259. package/lib/polyfill/patchedmediakeys_nop.js +0 -148
@@ -42,7 +42,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
42
42
  * The current mappings that will be used when requests are made. Since
43
43
  * nothing has been loaded yet, there will be nothing in this map.
44
44
  *
45
- * @private {!Map.<string, string>}
45
+ * @private {!Map<string, string>}
46
46
  */
47
47
  this.currentMap_ = new Map();
48
48
 
@@ -51,7 +51,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
51
51
  * have anything when we first initialize, an empty set means "no
52
52
  * preference".
53
53
  *
54
- * @private {!Set.<string>}
54
+ * @private {!Set<string>}
55
55
  */
56
56
  this.currentLocales_ = new Set();
57
57
 
@@ -60,7 +60,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
60
60
  * - The outer map is a mapping from locale code to localizations.
61
61
  * - The inner map is a mapping from id to localized text.
62
62
  *
63
- * @private {!Map.<string, !Map.<string, string>>}
63
+ * @private {!Map<string, !Map<string, string>>}
64
64
  */
65
65
  this.localizations_ = new Map();
66
66
  }
@@ -81,7 +81,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
81
81
  * an event identifying which locales it does not know. The localization
82
82
  * system will then continue to operate using the closest matches it has.
83
83
  *
84
- * @param {!Iterable.<string>} locales
84
+ * @param {!Iterable<string>} locales
85
85
  * The locale codes for the requested locales in order of preference.
86
86
  * @export
87
87
  */
@@ -128,7 +128,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
128
128
  *
129
129
  * @param {string} locale
130
130
  * The locale that the localizations should be added to.
131
- * @param {!Map.<string, string>} localizations
131
+ * @param {!Map<string, string>} localizations
132
132
  * A mapping of id to localized text that should used to modify the internal
133
133
  * collection of localizations.
134
134
  * @param {shaka.ui.Localization.ConflictResolution=} conflictResolution
@@ -183,7 +183,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
183
183
  * dictionary.set(key, localization.resolve(key));
184
184
  * }
185
185
  *
186
- * @param {!Map.<string, string>} dictionary
186
+ * @param {!Map<string, string>} dictionary
187
187
  * @export
188
188
  */
189
189
  resolveDictionary(dictionary) {
@@ -233,7 +233,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
233
233
  /**
234
234
  * The locales currently used. An empty set means "no preference".
235
235
  *
236
- * @return {!Set.<string>}
236
+ * @return {!Set<string>}
237
237
  * @export
238
238
  */
239
239
  getCurrentLocales() {
@@ -246,11 +246,11 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
246
246
  updateCurrentMap_() {
247
247
  const LanguageUtils = shaka.util.LanguageUtils;
248
248
 
249
- /** @type {!Map.<string, !Map.<string, string>>} */
249
+ /** @type {!Map<string, !Map<string, string>>} */
250
250
  const localizations = this.localizations_;
251
251
  /** @type {string} */
252
252
  const fallbackLocale = this.fallbackLocale_;
253
- /** @type {!Iterable.<string>} */
253
+ /** @type {!Iterable<string>} */
254
254
  const preferredLocales = this.currentLocales_;
255
255
 
256
256
  /**
@@ -275,12 +275,12 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
275
275
  * // Preference 2 base
276
276
  * 'dwarfish',
277
277
  * // Preference 2 Siblings
278
- * 'dwarfish-MOUNTAIN', 'dwarfish-NORTH', "dwarish-SOUTH",
278
+ * 'dwarfish-MOUNTAIN', 'dwarfish-NORTH', "dwarfish-SOUTH",
279
279
  * // Fallback
280
280
  * 'common-HUMAN',
281
281
  * ])
282
282
  *
283
- * @type {!Set.<string>}
283
+ * @type {!Set<string>}
284
284
  */
285
285
  const localeOrder = new Set();
286
286
 
@@ -316,7 +316,7 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
316
316
  localeOrder.add(fallbackLocale);
317
317
 
318
318
  // Add all the sibling maps.
319
- /** @type {!Array.<!Map.<string, string>>} */
319
+ /** @type {!Array<!Map<string, string>>} */
320
320
  const mergeOrder = [];
321
321
  for (const locale of localeOrder) {
322
322
  const map = localizations.get(locale);
@@ -343,10 +343,10 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
343
343
  // missing entries. This will allow app developers to find holes in their
344
344
  // localizations.
345
345
 
346
- /** @type {!Iterable.<string>} */
346
+ /** @type {!Iterable<string>} */
347
347
  const allKeys = this.currentMap_.keys();
348
348
 
349
- /** @type {!Set.<string>} */
349
+ /** @type {!Set<string>} */
350
350
  const missing = new Set();
351
351
 
352
352
  for (const locale of this.currentLocales_) {
@@ -373,9 +373,9 @@ shaka.ui.Localization = class extends shaka.util.FakeEventTarget {
373
373
  * Go through a map and add all the keys that are in |keys| but not in
374
374
  * |map| to |missing|.
375
375
  *
376
- * @param {!Map.<string, string>} map
377
- * @param {!Iterable.<string>} keys
378
- * @param {!Set.<string>} missing
376
+ * @param {!Map<string, string>} map
377
+ * @param {!Iterable<string>} keys
378
+ * @param {!Set<string>} missing
379
379
  * @private
380
380
  */
381
381
  static findMissingKeys_(map, keys, missing) {
@@ -454,7 +454,7 @@ shaka.ui.Localization.LOCALE_UPDATED = 'locale-updated';
454
454
  * @event shaka.ui.Localization.UnknownLocalesEvent
455
455
  * @property {string} type
456
456
  * 'unknown-locales'
457
- * @property {!Array.<string>} locales
457
+ * @property {!Array<string>} locales
458
458
  * The locales that the user wanted but could not be found.
459
459
  * @exportDoc
460
460
  */
@@ -463,7 +463,7 @@ shaka.ui.Localization.LOCALE_UPDATED = 'locale-updated';
463
463
  * @event shaka.ui.Localization.MissingLocalizationsEvent
464
464
  * @property {string} type
465
465
  * 'unknown-localization'
466
- * @property {!Array.<string>} locales
466
+ * @property {!Array<string>} locales
467
467
  * The locales that the user wanted.
468
468
  * @property {string} missing
469
469
  * The id of the unknown entry.
@@ -476,7 +476,7 @@ shaka.ui.Localization.LOCALE_UPDATED = 'locale-updated';
476
476
  * 'missing-localizations'
477
477
  * @property {string} locale
478
478
  * The locale that the user wanted.
479
- * @property {!Array.<string>} missing
479
+ * @property {!Array<string>} missing
480
480
  * The ids of the missing entries.
481
481
  * @exportDoc
482
482
  */
@@ -485,7 +485,7 @@ shaka.ui.Localization.LOCALE_UPDATED = 'locale-updated';
485
485
  * @event shaka.ui.Localization.LocaleChangedEvent
486
486
  * @property {string} type
487
487
  * 'locale-changed'
488
- * @property {!Array.<string>} locales
488
+ * @property {!Array<string>} locales
489
489
  * The new set of locales that user wanted,
490
490
  * and that were successfully found.
491
491
  * @exportDoc
package/ui/loop_button.js CHANGED
@@ -87,9 +87,9 @@ shaka.ui.LoopButton = class extends shaka.ui.Element {
87
87
  // 2) create a timer that checks the state of the loop property
88
88
  // regularly.
89
89
  // I (ismena) opted to go for #2 as at least video.currentTime
90
- // will be changing constatntly during playback, to say nothing
90
+ // will be changing constantly during playback, to say nothing
91
91
  // about other video properties. I expect the timer to be less
92
- // of a performence hit.
92
+ // of a performance hit.
93
93
  /**
94
94
  * The timer that tracks down the ad progress.
95
95
  *
@@ -39,7 +39,7 @@ shaka.ui.OverflowMenu = class extends shaka.ui.Element {
39
39
  /** @private {HTMLElement} */
40
40
  this.controlsContainer_ = this.controls.getControlsContainer();
41
41
 
42
- /** @private {!Array.<shaka.extern.IUIElement>} */
42
+ /** @private {!Array<shaka.extern.IUIElement>} */
43
43
  this.children_ = [];
44
44
 
45
45
  this.addOverflowMenuButton_();
@@ -217,6 +217,6 @@ shaka.ui.Controls.registerElement(
217
217
  'overflow_menu', new shaka.ui.OverflowMenu.Factory());
218
218
 
219
219
 
220
- /** @private {!Map.<string, !shaka.extern.IUIElement.Factory>} */
220
+ /** @private {!Map<string, !shaka.extern.IUIElement.Factory>} */
221
221
  shaka.ui.OverflowMenu.elementNamesToFactories_ = new Map();
222
222
 
@@ -52,7 +52,7 @@ shaka.ui.PlaybackRateSelection = class extends shaka.ui.SettingsMenu {
52
52
  this.updatePlaybackRateSelection_(this.player.getPlaybackRate());
53
53
  });
54
54
 
55
- /** @type {!Map.<string, number>} */
55
+ /** @type {!Map<string, number>} */
56
56
  this.playbackRates_ = new Map(this.controls.getConfig().playbackRates
57
57
  .map((rate) => [rate + 'x', rate]));
58
58
 
@@ -64,7 +64,10 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
64
64
  });
65
65
  }
66
66
 
67
- /** @private */
67
+ /**
68
+ * @param {string} value
69
+ * @private
70
+ */
68
71
  setValue_(value) {
69
72
  // To avoid constant updates to the DOM, which makes debugging more
70
73
  // difficult, only set the value if it has changed. If we don't do this
@@ -30,8 +30,8 @@ shaka.ui.RangeElement = class extends shaka.ui.Element {
30
30
  /**
31
31
  * @param {!HTMLElement} parent
32
32
  * @param {!shaka.ui.Controls} controls
33
- * @param {!Array.<string>} containerClassNames
34
- * @param {!Array.<string>} barClassNames
33
+ * @param {!Array<string>} containerClassNames
34
+ * @param {!Array<string>} barClassNames
35
35
  */
36
36
  constructor(parent, controls, containerClassNames, barClassNames) {
37
37
  super(parent, controls);
@@ -20,6 +20,7 @@ goog.require('shaka.ui.Utils');
20
20
  goog.require('shaka.util.Dom');
21
21
  goog.require('shaka.util.FakeEvent');
22
22
  goog.require('shaka.util.Functional');
23
+ goog.require('shaka.util.MimeUtils');
23
24
  goog.requireType('shaka.ui.Controls');
24
25
 
25
26
 
@@ -74,7 +75,7 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
74
75
  /** @private */
75
76
  updateResolutionSelection_() {
76
77
  const TrackLabelFormat = shaka.ui.Overlay.TrackLabelFormat;
77
- /** @type {!Array.<shaka.extern.Track>} */
78
+ /** @type {!Array<shaka.extern.Track>} */
78
79
  let tracks = [];
79
80
  // When played with src=, the variant tracks available from
80
81
  // player.getVariantTracks() represent languages, not resolutions.
@@ -125,11 +126,17 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
125
126
  tracks = tracks.filter((track, idx) => {
126
127
  // Keep the first one with the same height and framerate or bandwidth.
127
128
  const otherIdx = tracks.findIndex((t) => {
128
- return t.height == track.height &&
129
+ let ret = t.height == track.height &&
129
130
  t.videoBandwidth == track.videoBandwidth &&
130
131
  t.frameRate == track.frameRate &&
131
132
  t.hdr == track.hdr &&
132
133
  t.videoLayout == track.videoLayout;
134
+ if (ret && this.controls.getConfig().showVideoCodec &&
135
+ t.videoCodec && track.videoCodec) {
136
+ ret = shaka.util.MimeUtils.getNormalizedCodec(t.videoCodec) ==
137
+ shaka.util.MimeUtils.getNormalizedCodec(track.videoCodec);
138
+ }
139
+ return ret;
133
140
  });
134
141
  return otherIdx == idx;
135
142
  });
@@ -137,11 +144,17 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
137
144
  tracks = tracks.filter((track, idx) => {
138
145
  // Keep the first one with the same height and framerate or bandwidth.
139
146
  const otherIdx = tracks.findIndex((t) => {
140
- return t.height == track.height &&
147
+ let ret = t.height == track.height &&
141
148
  t.bandwidth == track.bandwidth &&
142
149
  t.frameRate == track.frameRate &&
143
150
  t.hdr == track.hdr &&
144
151
  t.videoLayout == track.videoLayout;
152
+ if (ret && this.controls.getConfig().showVideoCodec &&
153
+ t.videoCodec && track.videoCodec) {
154
+ ret = shaka.util.MimeUtils.getNormalizedCodec(t.videoCodec) ==
155
+ shaka.util.MimeUtils.getNormalizedCodec(track.videoCodec);
156
+ }
157
+ return ret;
145
158
  });
146
159
  return otherIdx == idx;
147
160
  });
@@ -246,7 +259,7 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
246
259
 
247
260
  /**
248
261
  * @param {!shaka.extern.Track} track
249
- * @param {!Array.<!shaka.extern.Track>} tracks
262
+ * @param {!Array<!shaka.extern.Track>} tracks
250
263
  * @return {string}
251
264
  * @private
252
265
  */
@@ -284,8 +297,31 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
284
297
  return otherTrack != track && otherTrack.height == track.height;
285
298
  });
286
299
  if (hasDuplicateResolution) {
287
- const bandwidth = track.videoBandwidth || track.bandwidth;
288
- text += ' (' + Math.round(bandwidth / 1000) + ' kbits/s)';
300
+ const hasDuplicateBandwidth = tracks.some((otherTrack) => {
301
+ return otherTrack != track && otherTrack.height == track.height &&
302
+ (otherTrack.videoBandwidth || otherTrack.bandwidth) ==
303
+ (track.videoBandwidth || track.bandwidth);
304
+ });
305
+ if (!hasDuplicateBandwidth) {
306
+ const bandwidth = track.videoBandwidth || track.bandwidth;
307
+ text += ' (' + Math.round(bandwidth / 1000) + ' kbits/s)';
308
+ }
309
+
310
+ if (this.controls.getConfig().showVideoCodec) {
311
+ const getVideoCodecName = (videoCodec) => {
312
+ let name = '';
313
+ if (videoCodec) {
314
+ const codec = shaka.util.MimeUtils.getNormalizedCodec(videoCodec);
315
+ if (codec.startsWith('dovi-')) {
316
+ name = 'Dolby Vision';
317
+ } else {
318
+ name = codec.toUpperCase();
319
+ }
320
+ }
321
+ return name ? ' ' + name : name;
322
+ };
323
+ text += getVideoCodecName(track.videoCodec);
324
+ }
289
325
  }
290
326
  return text;
291
327
  }
@@ -40,7 +40,7 @@ shaka.ui.RewindButton = class extends shaka.ui.Element {
40
40
  this.parent.appendChild(this.button_);
41
41
  this.updateAriaLabel_();
42
42
 
43
- /** @private {!Array.<number>} */
43
+ /** @private {!Array<number>} */
44
44
  this.rewindRates_ = this.controls.getConfig().rewindRates;
45
45
 
46
46
  this.eventManager.listen(
package/ui/seek_bar.js CHANGED
@@ -143,7 +143,7 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
143
143
  this.hideThumbnail_();
144
144
  });
145
145
 
146
- /** @private {!Array.<!shaka.extern.AdCuePoint>} */
146
+ /** @private {!Array<!shaka.extern.AdCuePoint>} */
147
147
  this.adCuePoints_ = [];
148
148
 
149
149
  this.eventManager.listen(this.localization,
@@ -313,7 +313,7 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
313
313
 
314
314
  /**
315
315
  * @override
316
- */
316
+ */
317
317
  isShowing() {
318
318
  // It is showing by default, so it is hidden if shaka-hidden is in the list.
319
319
  return !this.container.classList.contains('shaka-hidden');
@@ -442,12 +442,12 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
442
442
 
443
443
  /**
444
444
  * @param {string} color
445
- * @param {number} fract
445
+ * @param {number} fraction
446
446
  * @return {string}
447
447
  * @private
448
448
  */
449
- makeColor_(color, fract) {
450
- return color + ' ' + (fract * 100) + '%';
449
+ makeColor_(color, fraction) {
450
+ return color + ' ' + (fraction * 100) + '%';
451
451
  }
452
452
 
453
453
 
@@ -77,10 +77,10 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
77
77
  /** @private {!Array} */
78
78
  this.skippedStats_ = ['stateHistory', 'switchHistory'];
79
79
 
80
- /** @private {!Object.<string, number>} */
80
+ /** @private {!Object<string, number>} */
81
81
  this.currentStats_ = this.player.getStats();
82
82
 
83
- /** @private {!Object.<string, HTMLElement>} */
83
+ /** @private {!Object<string, HTMLElement>} */
84
84
  this.displayedElements_ = {};
85
85
 
86
86
 
@@ -136,7 +136,7 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
136
136
  }
137
137
  };
138
138
 
139
- /** @private {!Object.<string, function(string):string>} */
139
+ /** @private {!Object<string, function(string): string>} */
140
140
  this.parseFrom_ = {
141
141
  'width': parsePx,
142
142
  'height': parsePx,
@@ -220,7 +220,11 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
220
220
  this.stateSpan_.textContent = this.localization.resolve(labelText);
221
221
  }
222
222
 
223
- /** @private */
223
+ /**
224
+ * @param {string} name
225
+ * @return {!HTMLElement}
226
+ * @private
227
+ */
224
228
  generateComponent_(name) {
225
229
  const section = shaka.util.Dom.createHTMLElement('div');
226
230
 
@@ -140,7 +140,8 @@ shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {
140
140
  this.currentSelection,
141
141
  this.localization,
142
142
  this.controls.getConfig().textTrackLabelFormat,
143
- this.controls.getConfig().showAudioChannelCountVariants);
143
+ this.controls.getConfig().showAudioChannelCountVariants,
144
+ this.controls.getConfig().showAudioCodec);
144
145
 
145
146
  // Add the Off button
146
147
  const offButton = shaka.util.Dom.createButton();
@@ -178,7 +179,7 @@ shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {
178
179
  */
179
180
  async onTextTrackSelected_(track) {
180
181
  // setTextTrackVisibility should be called after selectTextTrack.
181
- // selectTextTrack sets a text stream, and setTextTrackVisiblity(true)
182
+ // selectTextTrack sets a text stream, and setTextTrackVisibility(true)
182
183
  // will set a text stream if it isn't already set. Consequently, reversing
183
184
  // the order of these calls makes two languages display simultaneously
184
185
  // if captions are turned off -> on in a different language.
package/ui/ui.js CHANGED
@@ -14,6 +14,7 @@ goog.require('shaka.Player');
14
14
  goog.require('shaka.log');
15
15
  goog.require('shaka.polyfill');
16
16
  goog.require('shaka.ui.Controls');
17
+ goog.require('shaka.ui.Watermark');
17
18
  goog.require('shaka.util.ConfigUtils');
18
19
  goog.require('shaka.util.Dom');
19
20
  goog.require('shaka.util.FakeEvent');
@@ -66,6 +67,11 @@ shaka.ui.Overlay = class {
66
67
 
67
68
  videoContainer['ui'] = this;
68
69
  video['ui'] = this;
70
+ /** @private {shaka.ui.Watermark} */
71
+ this.watermark_ = new shaka.ui.Watermark(
72
+ this.videoContainer_,
73
+ this.controls_,
74
+ );
69
75
  }
70
76
 
71
77
 
@@ -83,6 +89,7 @@ shaka.ui.Overlay = class {
83
89
  await this.player_.destroy();
84
90
  }
85
91
  this.player_ = null;
92
+ this.watermark_ = null;
86
93
  }
87
94
 
88
95
 
@@ -168,6 +175,27 @@ shaka.ui.Overlay = class {
168
175
  }
169
176
 
170
177
 
178
+ /**
179
+ * @param {string} text
180
+ * @param {?shaka.ui.Watermark.Options=} options
181
+ * @export
182
+ */
183
+ setTextWatermark(text, options) {
184
+ if (this.watermark_) {
185
+ this.watermark_.setTextWatermark(text, options);
186
+ }
187
+ }
188
+
189
+ /**
190
+ * @export
191
+ */
192
+ removeWatermark() {
193
+ if (this.watermark_) {
194
+ this.watermark_.removeWatermark();
195
+ }
196
+ }
197
+
198
+
171
199
  /**
172
200
  * @return {!shaka.extern.UIConfiguration}
173
201
  * @private
@@ -274,6 +302,8 @@ shaka.ui.Overlay = class {
274
302
  defaultVrProjectionMode: 'equirectangular',
275
303
  setupMediaSession: true,
276
304
  preferVideoFullScreenInVisionOS: false,
305
+ showAudioCodec: true,
306
+ showVideoCodec: true,
277
307
  };
278
308
 
279
309
  // eslint-disable-next-line no-restricted-syntax
@@ -515,8 +545,8 @@ shaka.ui.Overlay = class {
515
545
 
516
546
  /**
517
547
  * @param {!Element} container
518
- * @param {!NodeList.<!Element>} canvases
519
- * @param {!NodeList.<!Element>} vrCanvases
548
+ * @param {!NodeList<!Element>} canvases
549
+ * @param {!NodeList<!Element>} vrCanvases
520
550
  * @return {{lcevcCanvas: !Element, vrCanvas: !Element}}
521
551
  * @private
522
552
  */
package/ui/vr_manager.js CHANGED
@@ -338,7 +338,7 @@ shaka.ui.VRManager = class extends shaka.util.FakeEventTarget {
338
338
  if (this.gl_ && this.canvas_) {
339
339
  this.vrWebgl_ = new shaka.ui.VRWebgl(
340
340
  this.video_, this.player_, this.canvas_, this.gl_, projectionMode);
341
- this.setupVRListerners_();
341
+ this.setupVRListeners_();
342
342
  }
343
343
  }
344
344
 
@@ -371,7 +371,7 @@ shaka.ui.VRManager = class extends shaka.util.FakeEventTarget {
371
371
  /**
372
372
  * @private
373
373
  */
374
- setupVRListerners_() {
374
+ setupVRListeners_() {
375
375
  // Start
376
376
  this.eventManager_.listen(this.container_, 'mousedown', (event) => {
377
377
  if (!this.onGesture_) {
@@ -551,7 +551,7 @@ shaka.ui.VRManager = class extends shaka.util.FakeEventTarget {
551
551
  };
552
552
 
553
553
  /**
554
- * @constant {number}
554
+ * @const {number}
555
555
  * @private
556
556
  */
557
557
  shaka.ui.VRManager.TO_RADIANS_ = Math.PI / 180;
package/ui/vr_utils.js CHANGED
@@ -11,15 +11,15 @@ goog.provide('shaka.ui.VRUtils');
11
11
  shaka.ui.VRUtils = class {
12
12
  /**
13
13
  * @param {number} resolution
14
- * @return {{vertices: !Array.<number>, textureCoords: !Array.<number>,
15
- * indices: !Array.<number>}}
14
+ * @return {{vertices: !Array<number>, textureCoords: !Array<number>,
15
+ * indices: !Array<number>}}
16
16
  */
17
17
  static generateSphere(resolution) {
18
- /** @type {!Array.<number>} */
18
+ /** @type {!Array<number>} */
19
19
  const vertices = [];
20
- /** @type {!Array.<number>} */
20
+ /** @type {!Array<number>} */
21
21
  const textureCoords = [];
22
- /** @type {!Array.<number>} */
22
+ /** @type {!Array<number>} */
23
23
  const indices = [];
24
24
 
25
25
  for (let i = 0; i <= resolution; i++) {
@@ -62,11 +62,11 @@ shaka.ui.VRUtils = class {
62
62
  }
63
63
 
64
64
  /**
65
- * @return {{vertices: !Array.<number>, textureCoords: !Array.<number>,
66
- * indices: !Array.<number>}}
65
+ * @return {{vertices: !Array<number>, textureCoords: !Array<number>,
66
+ * indices: !Array<number>}}
67
67
  */
68
68
  static generateCube() {
69
- /** @type {!Array.<number>} */
69
+ /** @type {!Array<number>} */
70
70
  const vertices = [
71
71
  // order : left top back right bottom front
72
72
  // Front face 3
@@ -100,7 +100,7 @@ shaka.ui.VRUtils = class {
100
100
  1.0, 1.0, -1.0,
101
101
  1.0, -1.0, -1.0,
102
102
  ];
103
- /** @type {!Array.<number>} */
103
+ /** @type {!Array<number>} */
104
104
  const textureCoords = [
105
105
  // Left Face
106
106
  2 / 3, 0.5,
@@ -133,7 +133,7 @@ shaka.ui.VRUtils = class {
133
133
  2 / 3, 0.5,
134
134
  2 / 3, 1.0,
135
135
  ];
136
- /** @type {!Array.<number>} */
136
+ /** @type {!Array<number>} */
137
137
  const indices = [
138
138
  // Front face
139
139
  0, 1, 2,
@@ -162,7 +162,7 @@ shaka.ui.VRUtils = class {
162
162
  /**
163
163
  * Sphere vertex shader.
164
164
  *
165
- * @constant {string}
165
+ * @const {string}
166
166
  */
167
167
  shaka.ui.VRUtils.VERTEX_SPHERE_SHADER =
168
168
  `attribute vec4 a_vPosition;
@@ -183,7 +183,7 @@ void main()
183
183
  /**
184
184
  * Sphere fragment shader.
185
185
  *
186
- * @constant {string}
186
+ * @const {string}
187
187
  */
188
188
  shaka.ui.VRUtils.FRAGMENT_SPHERE_SHADER =
189
189
  `precision highp float;
@@ -204,7 +204,7 @@ highp vec4 texelColor =
204
204
  /**
205
205
  * Cube vertex shader.
206
206
  *
207
- * @constant {string}
207
+ * @const {string}
208
208
  */
209
209
  shaka.ui.VRUtils.VERTEX_CUBE_SHADER =
210
210
  `attribute vec4 aVertexPosition;
@@ -221,7 +221,7 @@ void main(void) {
221
221
  /**
222
222
  * Cube fragment shader.
223
223
  *
224
- * @constant {string}
224
+ * @const {string}
225
225
  */
226
226
  shaka.ui.VRUtils.FRAGMENT_CUBE_SHADER =
227
227
  `varying highp vec2 vTextureCoord;
package/ui/vr_webgl.js CHANGED
@@ -94,8 +94,8 @@ shaka.ui.VRWebgl = class {
94
94
  this.previousCanvasHeight_ = 0;
95
95
 
96
96
  /**
97
- * @private {?{vertices: !Array.<number>, textureCoords: !Array.<number>,
98
- * indices: !Array.<number>}}
97
+ * @private {?{vertices: !Array<number>, textureCoords: !Array<number>,
98
+ * indices: !Array<number>}}
99
99
  */
100
100
  this.geometry_ = null;
101
101
 
@@ -188,7 +188,7 @@ shaka.ui.VRWebgl = class {
188
188
  }
189
189
 
190
190
  /**
191
- * Toogle stereoscopic mode
191
+ * Toggle stereoscopic mode
192
192
  */
193
193
  toggleStereoscopicMode() {
194
194
  this.stereoscopicMode_ = !this.stereoscopicMode_;
@@ -574,7 +574,7 @@ shaka.ui.VRWebgl = class {
574
574
  shaka.ui.Matrix4x4.multiply(matrix, out, matrix);
575
575
  } else {
576
576
  // Doing this we restart the value to the previous position,
577
- // to not mantain a value over 90º or under -90º.
577
+ // to not maintain a value over 90º or under -90º.
578
578
  this.positionY_ -= pitch;
579
579
  }
580
580
 
@@ -694,6 +694,6 @@ shaka.ui.VRWebgl = class {
694
694
  };
695
695
 
696
696
  /**
697
- * @constant {number}
697
+ * @const {number}
698
698
  */
699
699
  shaka.ui.VRWebgl.ANIMATION_DURATION_ = 0.5;