@gcorevideo/player 2.18.3 → 2.19.1

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 (404) hide show
  1. package/assets/audio-selector/style.scss +156 -0
  2. package/assets/audio-selector/track-selector.ejs +12 -0
  3. package/assets/big-mute-button/big-mute-button.ejs +3 -0
  4. package/assets/big-mute-button/big-mute-button.scss +57 -0
  5. package/assets/bottom-gear/bottomgear.ejs +12 -0
  6. package/assets/bottom-gear/gear-sub-menu.scss +95 -0
  7. package/assets/bottom-gear/gear.scss +79 -0
  8. package/assets/clappr-nerd-stats/button.ejs +4 -0
  9. package/assets/clappr-nerd-stats/clappr-nerd-stats.ejs +212 -0
  10. package/assets/clappr-nerd-stats/clappr-nerd-stats.scss +488 -0
  11. package/assets/clappr-nerd-stats/options-list.ejs +9 -0
  12. package/assets/clappr-nerd-stats/settings.ejs +12 -0
  13. package/assets/clappr-nerd-stats/speedtest/speedtest.worker.js +775 -0
  14. package/assets/clips/clips.scss +3 -0
  15. package/assets/context-menu/context_menu.ejs +8 -0
  16. package/assets/context-menu/context_menu.scss +31 -0
  17. package/assets/dvr-controls/dvr_controls.scss +136 -0
  18. package/assets/dvr-controls/index.ejs +2 -0
  19. package/assets/error-screen/error_screen.ejs +13 -0
  20. package/assets/error-screen/error_screen.scss +40 -0
  21. package/assets/icons/new/arrow-left.svg +5 -0
  22. package/assets/icons/new/arrow-right.svg +5 -0
  23. package/assets/icons/new/check.svg +5 -0
  24. package/assets/icons/new/close.svg +12 -0
  25. package/assets/icons/new/full.svg +8 -0
  26. package/assets/icons/new/fullscreen-off.svg +14 -0
  27. package/assets/icons/new/fullscreen-on.svg +14 -0
  28. package/assets/icons/new/gear-hd.svg +16 -0
  29. package/assets/icons/new/gear.svg +12 -0
  30. package/assets/icons/new/hd.svg +8 -0
  31. package/assets/icons/new/pause.svg +5 -0
  32. package/assets/icons/new/pip.svg +5 -0
  33. package/assets/icons/new/play.svg +10 -0
  34. package/assets/icons/new/replayleft.svg +5 -0
  35. package/assets/icons/new/replayright.svg +5 -0
  36. package/assets/icons/new/speed.svg +5 -0
  37. package/assets/icons/new/stats.svg +3 -0
  38. package/assets/icons/new/stop.svg +3 -0
  39. package/assets/icons/new/subtitles-off.svg +5 -0
  40. package/assets/icons/new/subtitles-on.svg +6 -0
  41. package/assets/icons/new/volume-max.svg +5 -0
  42. package/assets/icons/new/volume-min.svg +5 -0
  43. package/assets/icons/new/volume-off.svg +5 -0
  44. package/assets/icons/old/cardboard.svg +4 -0
  45. package/assets/icons/old/close-share.svg +13 -0
  46. package/assets/icons/old/close.svg +13 -0
  47. package/assets/icons/old/fb.svg +13 -0
  48. package/assets/icons/old/fullscreen.svg +12 -0
  49. package/assets/icons/old/language.svg +1 -0
  50. package/assets/icons/old/pause.svg +12 -0
  51. package/assets/icons/old/play.svg +12 -0
  52. package/assets/icons/old/quality-arrow.svg +13 -0
  53. package/assets/icons/old/reload.svg +4 -0
  54. package/assets/icons/old/share.svg +13 -0
  55. package/assets/icons/old/sound-off.svg +15 -0
  56. package/assets/icons/old/sound-on.svg +15 -0
  57. package/assets/icons/old/streams.svg +3 -0
  58. package/assets/icons/old/twitter.svg +13 -0
  59. package/assets/icons/old/wn.svg +15 -0
  60. package/assets/icons/standard/01-play.svg +3 -0
  61. package/assets/icons/standard/02-pause.svg +3 -0
  62. package/assets/icons/standard/03-stop.svg +3 -0
  63. package/assets/icons/standard/04-volume.svg +3 -0
  64. package/assets/icons/standard/05-mute.svg +3 -0
  65. package/assets/icons/standard/06-expand.svg +3 -0
  66. package/assets/icons/standard/07-shrink.svg +3 -0
  67. package/assets/icons/standard/08-hd.svg +3 -0
  68. package/assets/icons/standard/09-cc.svg +8 -0
  69. package/assets/icons/standard/10-reload.svg +4 -0
  70. package/assets/level-selector/button.ejs +8 -0
  71. package/assets/level-selector/list.ejs +22 -0
  72. package/assets/level-selector/style.scss +4 -0
  73. package/assets/logo/styles/logo.scss +10 -0
  74. package/assets/logo/templates/logo.ejs +3 -0
  75. package/assets/media-control/closed-hand.cur +0 -0
  76. package/assets/media-control/container.scss +57 -0
  77. package/assets/media-control/media-control.ejs +133 -0
  78. package/assets/media-control/media-control.scss +390 -0
  79. package/assets/media-control/plugins.scss +94 -0
  80. package/assets/media-control/width270.scss +50 -0
  81. package/assets/media-control/width370.scss +263 -0
  82. package/assets/multi-camera/multicamera.ejs +29 -0
  83. package/assets/multi-camera/style.scss +176 -0
  84. package/assets/picture-in-picture/button.ejs +3 -0
  85. package/assets/picture-in-picture/button.scss +11 -0
  86. package/assets/playback-rate/button.ejs +6 -0
  87. package/assets/playback-rate/list.ejs +14 -0
  88. package/assets/playback-rate/playback-rate-selector.ejs +9 -0
  89. package/assets/poster/poster.ejs +1 -0
  90. package/assets/poster/poster.scss +32 -0
  91. package/assets/seek-time/seek-time.html +2 -0
  92. package/assets/seek-time/seek-time.scss +38 -0
  93. package/assets/share/share.ejs +37 -0
  94. package/assets/share/style.scss +104 -0
  95. package/assets/skip-time/skip-time.ejs +8 -0
  96. package/assets/skip-time/style.scss +24 -0
  97. package/assets/spinner-three-bounce/spinner.ejs +3 -0
  98. package/assets/spinner-three-bounce/spinner.scss +44 -0
  99. package/assets/style/main.scss +50 -0
  100. package/assets/style/theme.scss +42 -0
  101. package/assets/style/variables.scss +7 -0
  102. package/assets/subtitles/combobox copy.ejs +16 -0
  103. package/assets/subtitles/combobox.ejs +16 -0
  104. package/assets/subtitles/string.ejs +3 -0
  105. package/assets/subtitles/style.scss +99 -0
  106. package/assets/thumbnails/scrub-thumbnails.ejs +10 -0
  107. package/assets/thumbnails/style.scss +75 -0
  108. package/assets/vast-ads/style.scss +112 -0
  109. package/assets/video360/button.ejs +1 -0
  110. package/assets/video360/style.scss +8 -0
  111. package/build/vite-raw-plugin.js +18 -0
  112. package/dist/index.js +1 -1
  113. package/dist/plugins/index.css +2164 -0
  114. package/dist/{index-C02TmVOf.js → plugins/index.js/index.plugins.js} +29283 -29567
  115. package/lib/index.core.d.ts +15 -0
  116. package/lib/index.core.d.ts.map +1 -0
  117. package/lib/index.core.js +14 -0
  118. package/lib/index.d.ts +2 -14
  119. package/lib/index.d.ts.map +1 -1
  120. package/lib/index.js +2 -14
  121. package/lib/index.plugins.d.ts +37 -0
  122. package/lib/index.plugins.d.ts.map +1 -0
  123. package/lib/index.plugins.js +39 -0
  124. package/lib/plugins/audio-selector/AudioSelector.d.ts +3 -3
  125. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
  126. package/lib/plugins/audio-selector/AudioSelector.js +6 -12
  127. package/lib/plugins/big-mute-button/BigMuteButton.d.ts +2 -2
  128. package/lib/plugins/big-mute-button/BigMuteButton.d.ts.map +1 -1
  129. package/lib/plugins/big-mute-button/BigMuteButton.js +7 -12
  130. package/lib/plugins/bottom-gear/BottomGear.d.ts +4 -3
  131. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  132. package/lib/plugins/bottom-gear/BottomGear.js +11 -16
  133. package/lib/plugins/build.d.ts +2 -0
  134. package/lib/plugins/build.d.ts.map +1 -0
  135. package/lib/plugins/build.js +1 -0
  136. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +44 -0
  137. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -0
  138. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +294 -0
  139. package/lib/plugins/clappr-nerd-stats/formatter.d.ts +8 -0
  140. package/lib/plugins/clappr-nerd-stats/formatter.d.ts.map +1 -0
  141. package/lib/plugins/clappr-nerd-stats/formatter.js +91 -0
  142. package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.d.ts +54 -0
  143. package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.d.ts.map +1 -0
  144. package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.js +335 -0
  145. package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts +9 -0
  146. package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts.map +1 -0
  147. package/lib/plugins/clappr-nerd-stats/speedtest/index.js +154 -0
  148. package/lib/plugins/clappr-nerd-stats/speedtest/types.d.ts +6 -0
  149. package/lib/plugins/clappr-nerd-stats/speedtest/types.d.ts.map +1 -0
  150. package/lib/plugins/clappr-nerd-stats/types.d.ts +4 -0
  151. package/lib/plugins/clappr-nerd-stats/types.d.ts.map +1 -0
  152. package/lib/plugins/clappr-stats/ClapprStats.d.ts +56 -0
  153. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -0
  154. package/lib/plugins/clappr-stats/ClapprStats.js +332 -0
  155. package/lib/plugins/clappr-stats/types.d.ts +50 -0
  156. package/lib/plugins/clappr-stats/types.d.ts.map +1 -0
  157. package/lib/plugins/clappr-stats/types.js +5 -0
  158. package/lib/plugins/clappr-stats/utils.d.ts +3 -0
  159. package/lib/plugins/clappr-stats/utils.d.ts.map +1 -0
  160. package/lib/plugins/clappr-stats/utils.js +40 -0
  161. package/lib/plugins/click-to-pause/ClickToPause.d.ts +2 -2
  162. package/lib/plugins/click-to-pause/ClickToPause.d.ts.map +1 -1
  163. package/lib/plugins/click-to-pause/ClickToPause.js +4 -6
  164. package/lib/plugins/clips/Clips.d.ts +23 -0
  165. package/lib/plugins/clips/Clips.d.ts.map +1 -0
  166. package/lib/plugins/clips/Clips.js +109 -0
  167. package/lib/plugins/context-menu/ContextMenu.d.ts +36 -0
  168. package/lib/plugins/context-menu/ContextMenu.d.ts.map +1 -0
  169. package/lib/plugins/context-menu/ContextMenu.js +102 -0
  170. package/lib/plugins/disable-controls/DisableControls.d.ts +1 -1
  171. package/lib/plugins/disable-controls/DisableControls.d.ts.map +1 -1
  172. package/lib/plugins/disable-controls/DisableControls.js +3 -5
  173. package/lib/plugins/dvr-controls/{DVRControls.d.ts → DvrControls.d.ts} +4 -4
  174. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -0
  175. package/lib/plugins/dvr-controls/{DVRControls.js → DvrControls.js} +5 -4
  176. package/lib/plugins/error-screen/ErrorScreen.d.ts +44 -0
  177. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -0
  178. package/lib/plugins/error-screen/ErrorScreen.js +179 -0
  179. package/lib/plugins/favicon/Favicon.d.ts +24 -0
  180. package/lib/plugins/favicon/Favicon.d.ts.map +1 -0
  181. package/lib/plugins/favicon/Favicon.js +106 -0
  182. package/lib/plugins/google-analytics/GoogleAnalytics.d.ts +30 -0
  183. package/lib/plugins/google-analytics/GoogleAnalytics.d.ts.map +1 -0
  184. package/lib/plugins/google-analytics/GoogleAnalytics.js +114 -0
  185. package/lib/plugins/index.d.ts +38 -0
  186. package/lib/plugins/index.d.ts.map +1 -0
  187. package/lib/plugins/index.js +40 -0
  188. package/lib/plugins/kibo/index.d.ts +23 -0
  189. package/lib/plugins/kibo/index.d.ts.map +1 -0
  190. package/lib/plugins/kibo/index.js +199 -0
  191. package/lib/plugins/level-selector/LevelSelector.d.ts +48 -17
  192. package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
  193. package/lib/plugins/level-selector/LevelSelector.js +169 -155
  194. package/lib/plugins/logo/Logo.d.ts +29 -0
  195. package/lib/plugins/logo/Logo.d.ts.map +1 -0
  196. package/lib/plugins/logo/Logo.js +181 -0
  197. package/lib/plugins/logo/utils/index.d.ts +22 -0
  198. package/lib/plugins/logo/utils/index.d.ts.map +1 -0
  199. package/lib/plugins/logo/utils/index.js +32 -0
  200. package/lib/plugins/media-control/MediaControl.d.ts +20 -25
  201. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  202. package/lib/plugins/media-control/MediaControl.js +136 -106
  203. package/lib/plugins/multi-camera/MultiCamera.d.ts +59 -0
  204. package/lib/plugins/multi-camera/MultiCamera.d.ts.map +1 -0
  205. package/lib/plugins/multi-camera/MultiCamera.js +353 -0
  206. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +20 -0
  207. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -0
  208. package/lib/plugins/picture-in-picture/PictureInPicture.js +68 -0
  209. package/lib/plugins/playback-rate/PlaybackRate.d.ts +42 -0
  210. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -0
  211. package/lib/plugins/playback-rate/PlaybackRate.js +205 -0
  212. package/lib/plugins/poster/Poster.d.ts +18 -17
  213. package/lib/plugins/poster/Poster.d.ts.map +1 -1
  214. package/lib/plugins/poster/Poster.js +83 -37
  215. package/lib/plugins/seek-time/SeekTime.d.ts +38 -0
  216. package/lib/plugins/seek-time/SeekTime.d.ts.map +1 -0
  217. package/lib/plugins/seek-time/SeekTime.js +153 -0
  218. package/lib/plugins/share/Share.d.ts +38 -0
  219. package/lib/plugins/share/Share.d.ts.map +1 -0
  220. package/lib/plugins/share/Share.js +122 -0
  221. package/lib/plugins/skip-time/SkipTime.d.ts +28 -0
  222. package/lib/plugins/skip-time/SkipTime.d.ts.map +1 -0
  223. package/lib/plugins/skip-time/SkipTime.js +86 -0
  224. package/lib/plugins/source-controller/SourceController.d.ts +41 -0
  225. package/lib/plugins/source-controller/SourceController.d.ts.map +1 -0
  226. package/lib/plugins/source-controller/SourceController.js +199 -0
  227. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts +26 -0
  228. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts.map +1 -0
  229. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +117 -0
  230. package/lib/plugins/statistics/Statistics.d.ts +52 -0
  231. package/lib/plugins/statistics/Statistics.d.ts.map +1 -0
  232. package/lib/plugins/statistics/Statistics.js +130 -0
  233. package/lib/plugins/subtitles/Subtitles.d.ts +61 -0
  234. package/lib/plugins/subtitles/Subtitles.d.ts.map +1 -0
  235. package/lib/plugins/subtitles/Subtitles.js +354 -0
  236. package/lib/plugins/thumbnails/Thumbnails.d.ts +47 -0
  237. package/lib/plugins/thumbnails/Thumbnails.d.ts.map +1 -0
  238. package/lib/plugins/thumbnails/Thumbnails.js +414 -0
  239. package/lib/plugins/types.d.ts +8 -0
  240. package/lib/plugins/types.d.ts.map +1 -0
  241. package/lib/plugins/types.js +1 -0
  242. package/lib/plugins/utils.d.ts +5 -0
  243. package/lib/plugins/utils.d.ts.map +1 -0
  244. package/lib/plugins/utils.js +68 -0
  245. package/lib/plugins/vast-ads/VastAds.d.ts +72 -0
  246. package/lib/plugins/vast-ads/VastAds.d.ts.map +1 -0
  247. package/lib/plugins/vast-ads/VastAds.js +686 -0
  248. package/lib/plugins/vast-ads/loaderxml.d.ts +32 -0
  249. package/lib/plugins/vast-ads/loaderxml.d.ts.map +1 -0
  250. package/lib/plugins/vast-ads/loaderxml.js +226 -0
  251. package/lib/plugins/vast-ads/roll.d.ts +60 -0
  252. package/lib/plugins/vast-ads/roll.d.ts.map +1 -0
  253. package/lib/plugins/vast-ads/roll.js +415 -0
  254. package/lib/plugins/vast-ads/rollmanager.d.ts +62 -0
  255. package/lib/plugins/vast-ads/rollmanager.d.ts.map +1 -0
  256. package/lib/plugins/vast-ads/rollmanager.js +347 -0
  257. package/lib/plugins/vast-ads/sctemanager.d.ts +18 -0
  258. package/lib/plugins/vast-ads/sctemanager.d.ts.map +1 -0
  259. package/lib/plugins/vast-ads/sctemanager.js +116 -0
  260. package/lib/plugins/vast-ads/types.d.ts +12 -0
  261. package/lib/plugins/vast-ads/types.d.ts.map +1 -0
  262. package/lib/plugins/vast-ads/types.js +1 -0
  263. package/lib/plugins/vast-ads/urlhandler.d.ts +4 -0
  264. package/lib/plugins/vast-ads/urlhandler.d.ts.map +1 -0
  265. package/lib/plugins/vast-ads/urlhandler.js +30 -0
  266. package/lib/plugins/vast-ads/xmlhttprequest.d.ts +6 -0
  267. package/lib/plugins/vast-ads/xmlhttprequest.d.ts.map +1 -0
  268. package/lib/plugins/vast-ads/xmlhttprequest.js +39 -0
  269. package/lib/plugins/vast-ads/xmlmerge.d.ts +12 -0
  270. package/lib/plugins/vast-ads/xmlmerge.d.ts.map +1 -0
  271. package/lib/plugins/vast-ads/xmlmerge.js +82 -0
  272. package/lib/plugins/volume-fade/VolumeFade.d.ts +21 -0
  273. package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -0
  274. package/lib/plugins/volume-fade/VolumeFade.js +90 -0
  275. package/package.json +10 -2
  276. package/rollup.config.js +32 -2
  277. package/src/index.core.ts +15 -0
  278. package/src/index.plugins.ts +41 -0
  279. package/src/index.ts +2 -15
  280. package/src/plugins/audio-selector/AudioSelector.ts +370 -0
  281. package/src/plugins/big-mute-button/BigMuteButton.ts +187 -0
  282. package/src/plugins/bottom-gear/BottomGear.ts +122 -0
  283. package/src/plugins/build.ts +1 -0
  284. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +369 -0
  285. package/src/plugins/clappr-nerd-stats/formatter.ts +109 -0
  286. package/src/plugins/clappr-nerd-stats/speedtest/Speedtest.ts +414 -0
  287. package/src/plugins/clappr-nerd-stats/speedtest/index.ts +183 -0
  288. package/src/plugins/clappr-nerd-stats/speedtest/types.ts +5 -0
  289. package/src/plugins/clappr-nerd-stats/types.ts +3 -0
  290. package/src/plugins/clappr-stats/ClapprStats.ts +441 -0
  291. package/src/plugins/clappr-stats/types.ts +52 -0
  292. package/src/plugins/clappr-stats/utils.ts +42 -0
  293. package/src/plugins/click-to-pause/ClickToPause.ts +93 -0
  294. package/src/plugins/clips/Clips.ts +152 -0
  295. package/src/plugins/context-menu/ContextMenu.ts +134 -0
  296. package/src/plugins/disable-controls/DisableControls.ts +81 -0
  297. package/src/plugins/dvr-controls/DvrControls.ts +131 -0
  298. package/src/plugins/error-screen/ErrorScreen.ts +241 -0
  299. package/src/plugins/favicon/Favicon.ts +137 -0
  300. package/src/plugins/ga-events/GaEvents.js +395 -0
  301. package/src/plugins/ga-events/ga-tracking.js +46 -0
  302. package/src/plugins/google-analytics/GoogleAnalytics.ts +147 -0
  303. package/src/plugins/index.ts +42 -0
  304. package/src/plugins/kibo/index.ts +244 -0
  305. package/src/plugins/level-selector/LevelSelector.ts +400 -0
  306. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +72 -0
  307. package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +11 -0
  308. package/src/plugins/logo/Logo.ts +233 -0
  309. package/src/plugins/logo/utils/index.ts +46 -0
  310. package/src/plugins/media-control/MediaControl.ts +1383 -0
  311. package/src/plugins/multi-camera/MultiCamera copy.xts +414 -0
  312. package/src/plugins/multi-camera/MultiCamera.ts +426 -0
  313. package/src/plugins/picture-in-picture/PictureInPicture.ts +87 -0
  314. package/src/plugins/playback-rate/PlaybackRate.ts +269 -0
  315. package/src/plugins/poster/Poster.ts +298 -0
  316. package/src/plugins/seek-time/SeekTime.ts +191 -0
  317. package/src/plugins/share/Share.ts +148 -0
  318. package/src/plugins/skip-time/SkipTime.ts +109 -0
  319. package/src/plugins/source-controller/SourceController.ts +239 -0
  320. package/src/plugins/source-controller/__tests__/SourceController.test.ts +230 -0
  321. package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +135 -0
  322. package/src/plugins/statistics/Statistics copy.xts +296 -0
  323. package/src/plugins/statistics/Statistics.ts +207 -0
  324. package/src/plugins/subtitles/Subtitles.ts +505 -0
  325. package/src/plugins/thumbnails/Thumbnails.ts +530 -0
  326. package/src/plugins/types.ts +7 -0
  327. package/src/plugins/typings/globals.d.ts +10 -0
  328. package/src/plugins/typings/parse-srt.d.ts +14 -0
  329. package/src/plugins/typings/workers.d.ts +3 -0
  330. package/src/plugins/utils.ts +77 -0
  331. package/src/plugins/vast-ads/VastAds.ts +915 -0
  332. package/src/plugins/vast-ads/loaderxml.ts +260 -0
  333. package/src/plugins/vast-ads/roll.ts +492 -0
  334. package/src/plugins/vast-ads/rollmanager.ts +403 -0
  335. package/src/plugins/vast-ads/sctemanager.ts +134 -0
  336. package/src/plugins/vast-ads/types.ts +14 -0
  337. package/src/plugins/vast-ads/urlhandler.ts +37 -0
  338. package/src/plugins/vast-ads/xmlhttprequest.ts +44 -0
  339. package/src/plugins/vast-ads/xmlmerge.ts +96 -0
  340. package/src/plugins/video360/VRControls.js +104 -0
  341. package/src/plugins/video360/VREffect.js +422 -0
  342. package/src/plugins/video360/Video360.js +979 -0
  343. package/src/plugins/video360/orbit-oriention-controls.js +1002 -0
  344. package/src/plugins/video360/utils.js +49 -0
  345. package/src/plugins/volume-fade/VolumeFade.ts +109 -0
  346. package/tsconfig.tsbuildinfo +1 -1
  347. package/dist/HlsPlayback-D9EmONbV.js +0 -747
  348. package/dist/player.d.ts +0 -646
  349. package/lib/backend.d.ts +0 -3
  350. package/lib/backend.d.ts.map +0 -1
  351. package/lib/backend.js +0 -10
  352. package/lib/constants.d.ts +0 -1
  353. package/lib/constants.d.ts.map +0 -1
  354. package/lib/constants.js +0 -1
  355. package/lib/gcore.types.d.ts +0 -84
  356. package/lib/gcore.types.d.ts.map +0 -1
  357. package/lib/gcore.types.js +0 -9
  358. package/lib/plugins/dash-playback/DashPlayback.d.ts +0 -73
  359. package/lib/plugins/dash-playback/DashPlayback.d.ts.map +0 -1
  360. package/lib/plugins/dash-playback/DashPlayback.js +0 -455
  361. package/lib/plugins/dash-playback/types.d.ts +0 -6
  362. package/lib/plugins/dash-playback/types.d.ts.map +0 -1
  363. package/lib/plugins/dash-plugin/DashPlayback.d.ts +0 -86
  364. package/lib/plugins/dash-plugin/DashPlayback.d.ts.map +0 -1
  365. package/lib/plugins/dash-plugin/DashPlayback.js +0 -659
  366. package/lib/plugins/dvr-controls/DVRControls.d.ts.map +0 -1
  367. package/lib/plugins/hls-playback/HlsPlayback.d.ts +0 -102
  368. package/lib/plugins/hls-playback/HlsPlayback.d.ts.map +0 -1
  369. package/lib/plugins/hls-playback/HlsPlayback.js +0 -815
  370. package/lib/trace/LogTracer.d.ts +0 -12
  371. package/lib/trace/LogTracer.d.ts.map +0 -1
  372. package/lib/trace/LogTracer.js +0 -17
  373. package/lib/trace/SentryTracer.d.ts +0 -12
  374. package/lib/trace/SentryTracer.d.ts.map +0 -1
  375. package/lib/trace/SentryTracer.js +0 -23
  376. package/lib/trace/Tracer.d.ts +0 -13
  377. package/lib/trace/Tracer.d.ts.map +0 -1
  378. package/lib/trace/Tracer.js +0 -15
  379. package/lib/trace/index.d.ts +0 -18
  380. package/lib/trace/index.d.ts.map +0 -1
  381. package/lib/trace/index.js +0 -27
  382. package/lib/trace/types.d.ts +0 -8
  383. package/lib/trace/types.d.ts.map +0 -1
  384. package/lib/tsdoc-metadata.json +0 -11
  385. package/lib/utils/Logger.d.ts +0 -23
  386. package/lib/utils/Logger.d.ts.map +0 -1
  387. package/lib/utils/Logger.js +0 -81
  388. package/lib/utils/canAutoplay.d.ts +0 -6
  389. package/lib/utils/canAutoplay.d.ts.map +0 -1
  390. package/lib/utils/canAutoplay.js +0 -30
  391. package/lib/utils/queryParams.d.ts +0 -2
  392. package/lib/utils/queryParams.d.ts.map +0 -1
  393. package/lib/utils/queryParams.js +0 -4
  394. package/lib/utils/scripts-load.d.ts +0 -2
  395. package/lib/utils/scripts-load.d.ts.map +0 -1
  396. package/lib/utils/scripts-load.js +0 -20
  397. package/lib/utils/testUtils.d.ts +0 -3
  398. package/lib/utils/testUtils.d.ts.map +0 -1
  399. package/lib/utils/testUtils.js +0 -12
  400. package/lib/utils/utils.d.ts +0 -3
  401. package/lib/utils/utils.d.ts.map +0 -1
  402. package/lib/utils/utils.js +0 -31
  403. /package/lib/plugins/{dash-playback → clappr-nerd-stats/speedtest}/types.js +0 -0
  404. /package/lib/{trace → plugins/clappr-nerd-stats}/types.js +0 -0
@@ -0,0 +1,1383 @@
1
+ // Copyright 2014 Globo.com Player authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+
5
+ /**
6
+ * The MediaControl is responsible for displaying the Player controls.
7
+ */
8
+
9
+ import assert from 'assert'
10
+ import {
11
+ Events,
12
+ UICorePlugin,
13
+ Browser,
14
+ Playback,
15
+ Player as PlayerClappr,
16
+ Utils,
17
+ template,
18
+ $,
19
+ } from '@clappr/core'
20
+ import { type TimeProgress } from '../..//playback.types'
21
+ import { reportError } from '@gcorevideo/utils';
22
+
23
+ import { Kibo } from '../kibo/index.js'
24
+
25
+ import { CLAPPR_VERSION } from '../build.js'
26
+ import { TimerId, ZeptoResult } from '../types'
27
+ import { getPageX, isFullscreen } from '../utils.js'
28
+
29
+ import '../../../assets/media-control/media-control.scss'
30
+ import '../../../assets/media-control/plugins.scss'
31
+
32
+ import mediaControlHTML from '../../../assets/media-control/media-control.ejs'
33
+ import playIcon from '../../../assets/icons/new/play.svg'
34
+ import pauseIcon from '../../../assets/icons/new/pause.svg'
35
+ import stopIcon from '../../../assets/icons/new/stop.svg'
36
+ import volumeMaxIcon from '../../../assets/icons/new/volume-max.svg'
37
+ import volumeOffIcon from '../../../assets/icons/new/volume-off.svg'
38
+ import fullscreenOffIcon from '../../../assets/icons/new/fullscreen-off.svg'
39
+ import fullscreenOnIcon from '../../../assets/icons/new/fullscreen-on.svg'
40
+
41
+ type MediaControlElement = 'pip' // TODO
42
+
43
+ const T = 'plugins.media_control'
44
+
45
+ const { Config, Fullscreen, formatTime, extend, removeArrayItem } = Utils
46
+
47
+ function orderByOrderPattern(arr: string[], order: string[]): string[] {
48
+ const arrWithoutDuplicates = [...new Set(arr)]
49
+ const ordered = order.filter((item) => arrWithoutDuplicates.includes(item))
50
+
51
+ const rest = arrWithoutDuplicates.filter((item) => !order.includes(item))
52
+
53
+ return [...ordered, ...rest]
54
+ }
55
+
56
+ type DisabledClickable = {
57
+ el: ZeptoResult
58
+ pointerEventValue: string
59
+ }
60
+
61
+ export class MediaControl extends UICorePlugin {
62
+ private advertisementPlaying = false
63
+
64
+ private buttonsColor: string | null = null
65
+
66
+ private currentDurationValue: number = 0
67
+ private currentPositionValue: number = 0
68
+ private currentSeekBarPercentage: number | null = null
69
+
70
+ private disabledClickableList: DisabledClickable[] = []
71
+ private displayedDuration: string | null = null
72
+ private displayedPosition: string | null = null
73
+ private displayedSeekBarPercentage: number | null = null
74
+
75
+ private draggingSeekBar = false
76
+ private draggingVolumeBar = false
77
+
78
+ private fullScreenOnVideoTagSupported: boolean | null = null
79
+
80
+ private hideId: ReturnType<typeof setTimeout> | null = null
81
+ private hideVolumeId: ReturnType<typeof setTimeout> | null = null
82
+
83
+ private intendedVolume = 100
84
+
85
+ private isHD = false
86
+
87
+ private keepVisible = false
88
+
89
+ private kibo: Kibo
90
+
91
+ private lastMouseX = 0
92
+ private lastMouseY = 0
93
+
94
+ private persistConfig: boolean
95
+
96
+ private rendered = false
97
+
98
+ private settings: Record<string, unknown> = {}
99
+
100
+ private svgMask: ZeptoResult | null = null
101
+
102
+ private userDisabled = false
103
+
104
+ private userKeepVisible = false
105
+
106
+ private verticalVolume = false
107
+
108
+ private $audioTracksSelector: ZeptoResult | null = null
109
+
110
+ private $bottomGear: ZeptoResult | null = null
111
+
112
+ private $clipText: ZeptoResult | null = null
113
+
114
+ private $clipTextContainer: ZeptoResult | null = null
115
+
116
+ private $duration: ZeptoResult | null = null
117
+
118
+ private $fullscreenToggle: ZeptoResult | null = null
119
+
120
+ private $multiCameraSelector: ZeptoResult | null = null
121
+
122
+ private $pip: ZeptoResult | null = null
123
+
124
+ private $playPauseToggle: ZeptoResult | null = null
125
+
126
+ private $playStopToggle: ZeptoResult | null = null
127
+
128
+ private $playbackRate: ZeptoResult | null = null
129
+
130
+ private $position: ZeptoResult | null = null
131
+
132
+ private $seekBarContainer: ZeptoResult | null = null
133
+
134
+ private $seekBarHover: ZeptoResult | null = null
135
+
136
+ private $seekBarLoaded: ZeptoResult | null = null
137
+
138
+ private $seekBarPosition: ZeptoResult | null = null
139
+
140
+ private $seekBarScrubber: ZeptoResult | null = null
141
+
142
+ private $subtitlesSelector: ZeptoResult | null = null
143
+
144
+ private $volumeBarContainer: ZeptoResult | null = null
145
+
146
+ private $volumeBarBackground: ZeptoResult | null = null
147
+
148
+ private $volumeBarFill: ZeptoResult | null = null
149
+
150
+ private $volumeBarScrubber: ZeptoResult | null = null
151
+
152
+ private $volumeContainer: ZeptoResult | null = null
153
+
154
+ private $volumeIcon: ZeptoResult | null = null
155
+
156
+ get name() {
157
+ return 'media_control'
158
+ }
159
+
160
+ get supportedVersion() {
161
+ return { min: CLAPPR_VERSION }
162
+ }
163
+
164
+ get disabled() {
165
+ const playbackIsNOOP =
166
+ this.container && this.container.getPlaybackType() === Playback.NO_OP
167
+
168
+ return this.userDisabled || playbackIsNOOP
169
+ }
170
+
171
+ get container() {
172
+ return this.core && this.core.activeContainer
173
+ }
174
+
175
+ get playback() {
176
+ return this.core && this.core.activePlayback
177
+ }
178
+
179
+ override get attributes() {
180
+ return {
181
+ class: 'media-control-skin-1',
182
+ 'data-media-control-skin-1': '',
183
+ }
184
+ }
185
+
186
+ override get events() {
187
+ return {
188
+ 'click [data-play]': 'play',
189
+ 'click [data-pause]': 'pause',
190
+ 'click [data-playpause]': 'togglePlayPause',
191
+ 'click [data-stop]': 'stop',
192
+ 'click [data-playstop]': 'togglePlayStop',
193
+ 'click [data-fullscreen]': 'handleFullScreenOnBtn',
194
+ 'click .bar-container[data-seekbar]': 'seek',
195
+ 'click .bar-container[data-volume]': 'onVolumeClick',
196
+ 'click .drawer-icon[data-volume]': 'toggleMute',
197
+ 'mouseenter .drawer-container[data-volume]': 'showVolumeBar',
198
+ 'mouseleave .drawer-container[data-volume]': 'hideVolumeBar',
199
+ 'mousedown .bar-container[data-volume]': 'startVolumeDrag',
200
+ 'touchstart .bar-container[data-volume]': 'startVolumeDrag',
201
+ 'mousemove .bar-container[data-volume]': 'mousemoveOnVolumeBar',
202
+ 'touchmove .bar-container[data-volume]': 'mousemoveOnVolumeBar',
203
+ 'mousedown .bar-scrubber[data-seekbar]': 'startSeekDrag',
204
+ 'mousedown .bar-container[data-seekbar]': 'startSeekDrag',
205
+ 'touchstart .bar-scrubber[data-seekbar]': 'startSeekDrag',
206
+ 'touchstart .bar-container[data-seekbar]': 'startSeekDrag',
207
+ 'mousemove .bar-container[data-seekbar]': 'mousemoveOnSeekBar',
208
+ 'touchmove .bar-container[data-seekbar]': 'mousemoveOnSeekBar',
209
+ 'mouseleave .bar-container[data-seekbar]': 'mouseleaveOnSeekBar',
210
+ 'touchend .bar-container[data-seekbar]': 'mouseleaveOnSeekBar',
211
+ 'mouseenter .media-control-layer[data-controls]': 'setUserKeepVisible',
212
+ 'mouseleave .media-control-layer[data-controls]': 'resetUserKeepVisible',
213
+ }
214
+ }
215
+
216
+ get template() {
217
+ return template(mediaControlHTML)
218
+ }
219
+
220
+ get volume() {
221
+ return this.container && this.container.isReady
222
+ ? this.container.volume
223
+ : this.intendedVolume
224
+ }
225
+
226
+ get muted() {
227
+ return this.volume === 0
228
+ }
229
+
230
+ constructor(core: PlayerClappr) {
231
+ super(core)
232
+ this.persistConfig = this.options.persistConfig
233
+ this.setInitialVolume()
234
+
235
+ this.kibo = new Kibo(this.options.focusElement)
236
+ this.bindKeyEvents()
237
+
238
+ this.userDisabled = false
239
+ if (
240
+ (this.container && this.container.mediaControlDisabled) ||
241
+ this.options.chromeless
242
+ ) {
243
+ this.disable()
244
+ }
245
+
246
+ $(document).bind('mouseup', this.stopDrag)
247
+ $(document).bind('mousemove', this.updateDrag)
248
+
249
+ $(document).bind('touchend', this.stopDrag)
250
+ $(document).bind('touchmove', this.updateDrag)
251
+ }
252
+
253
+ override getExternalInterface() {
254
+ return {
255
+ setVolume: this.setVolume,
256
+ getVolume: () => this.volume,
257
+ }
258
+ }
259
+
260
+ override bindEvents() {
261
+ // @ts-ignore
262
+ this.stopListening()
263
+ this.listenTo(
264
+ this.core,
265
+ Events.CORE_ACTIVE_CONTAINER_CHANGED,
266
+ this.onActiveContainerChanged,
267
+ )
268
+ this.listenTo(this.core, Events.CORE_MOUSE_MOVE, this.show)
269
+ this.listenTo(this.core, Events.CORE_MOUSE_LEAVE, () =>
270
+ this.hide(this.options.hideMediaControlDelay),
271
+ )
272
+ this.listenTo(this.core, Events.CORE_FULLSCREEN, this.show)
273
+ this.listenTo(this.core, Events.CORE_OPTIONS_CHANGE, this.configure)
274
+ this.listenTo(this.core, Events.CORE_RESIZE, this.playerResize)
275
+ this.bindContainerEvents()
276
+
277
+ this.listenTo(this.core, 'core:advertisement:start', this.onStartAd)
278
+ this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd)
279
+
280
+ // const has360 = this.core?.getPlugin('video_360');
281
+
282
+ // if (Browser.isiOS && has360) {
283
+ // this.container?.el.addEventListener('click', e => {
284
+ // e.preventDefault();
285
+ // e.stopPropagation();
286
+ // // feature detect
287
+ // if (typeof DeviceMotionEvent.requestPermission === 'function') {
288
+ // DeviceMotionEvent.requestPermission()
289
+ // .then(permissionState => {
290
+ // if (permissionState === 'granted') {
291
+ // console.warn('Permission granted');
292
+ // }
293
+ // })
294
+ // .catch(console.error);
295
+ // } else {
296
+ // // handle regular non iOS 13+ devices
297
+ // }
298
+ // });
299
+ // }
300
+ }
301
+
302
+ bindContainerEvents() {
303
+ if (!this.container) {
304
+ return
305
+ }
306
+ this.listenTo(this.container, Events.CONTAINER_PLAY, this.changeTogglePlay)
307
+ this.listenTo(this.container, Events.CONTAINER_PAUSE, this.changeTogglePlay)
308
+ this.listenTo(this.container, Events.CONTAINER_STOP, this.changeTogglePlay)
309
+ this.listenTo(
310
+ this.container,
311
+ Events.CONTAINER_DBLCLICK,
312
+ this.toggleFullscreen,
313
+ )
314
+ this.listenTo(
315
+ this.container,
316
+ Events.CONTAINER_TIMEUPDATE,
317
+ this.onTimeUpdate,
318
+ )
319
+ this.listenTo(
320
+ this.container,
321
+ Events.CONTAINER_PROGRESS,
322
+ this.updateProgressBar,
323
+ )
324
+ this.listenTo(
325
+ this.container,
326
+ Events.CONTAINER_SETTINGSUPDATE,
327
+ this.settingsUpdate,
328
+ )
329
+ this.listenTo(
330
+ this.container,
331
+ Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
332
+ this.settingsUpdate,
333
+ )
334
+ this.listenTo(
335
+ this.container,
336
+ Events.CONTAINER_HIGHDEFINITIONUPDATE,
337
+ this.highDefinitionUpdate,
338
+ )
339
+ this.listenTo(
340
+ this.container,
341
+ Events.CONTAINER_MEDIACONTROL_DISABLE,
342
+ this.disable,
343
+ )
344
+ this.listenTo(
345
+ this.container,
346
+ Events.CONTAINER_MEDIACONTROL_ENABLE,
347
+ this.enable,
348
+ )
349
+ this.listenTo(this.container, Events.CONTAINER_ENDED, this.ended)
350
+ this.listenTo(this.container, Events.CONTAINER_VOLUME, this.onVolumeChanged)
351
+ this.listenTo(
352
+ this.container,
353
+ Events.CONTAINER_OPTIONS_CHANGE,
354
+ this.setInitialVolume,
355
+ )
356
+ if (this.container.playback.el.nodeName.toLowerCase() === 'video') {
357
+ // wait until the metadata has loaded and then check if fullscreen on video tag is supported
358
+ this.listenToOnce(
359
+ this.container,
360
+ Events.CONTAINER_LOADEDMETADATA,
361
+ this.onLoadedMetadataOnVideoTag,
362
+ )
363
+ }
364
+ }
365
+
366
+ override disable() {
367
+ this.userDisabled = true
368
+ this.hide()
369
+ this.unbindKeyEvents()
370
+ this.$el.hide()
371
+ }
372
+
373
+ override enable() {
374
+ if (this.options.chromeless) {
375
+ return
376
+ }
377
+ this.userDisabled = false
378
+ this.bindKeyEvents()
379
+ this.show()
380
+ }
381
+
382
+ play() {
383
+ this.container && this.container.play()
384
+ }
385
+
386
+ pause() {
387
+ this.container && this.container.pause()
388
+ }
389
+
390
+ stop() {
391
+ this.container && this.container.stop()
392
+ }
393
+
394
+ private setInitialVolume() {
395
+ const initialVolume = this.persistConfig ? Config.restore('volume') : 100
396
+ const options = (this.container && this.container.options) || this.options
397
+
398
+ this.setVolume(options.mute ? 0 : initialVolume, true)
399
+ }
400
+
401
+ private onVolumeChanged() {
402
+ this.updateVolumeUI()
403
+ }
404
+
405
+ private onLoadedMetadataOnVideoTag(event: any) {
406
+ const video = this.playback && this.playback.el
407
+
408
+ // video.webkitSupportsFullscreen is deprecated but iOS appears to only use this
409
+ // see https://github.com/clappr/clappr/issues/1127
410
+ if (!Fullscreen.fullscreenEnabled() && video.webkitSupportsFullscreen) {
411
+ this.fullScreenOnVideoTagSupported = true
412
+ this.settingsUpdate()
413
+ }
414
+ }
415
+
416
+ private updateVolumeUI() {
417
+ // this will be called after a render
418
+ if (!this.rendered) {
419
+ return
420
+ }
421
+
422
+ assert.ok(this.$volumeBarContainer, 'volume bar container must be present')
423
+ // update volume bar scrubber/fill on bar mode
424
+ // this.$volumeBarContainer.find('.bar-fill-2').css({});
425
+ const containerWidth = this.$volumeBarContainer.width()
426
+
427
+ assert.ok(
428
+ this.$volumeBarBackground,
429
+ 'volume bar background must be present',
430
+ )
431
+ const barWidth = this.$volumeBarBackground.width()
432
+ const offset = (containerWidth - barWidth) / 2.0
433
+ const pos = (barWidth * this.volume) / 100.0 + offset
434
+
435
+ assert.ok(this.$volumeBarFill, 'volume bar fill must be present')
436
+ this.$volumeBarFill.css({ width: `${this.volume}%` })
437
+ this.$volumeBarFill.css({ width: `${this.volume}%` })
438
+
439
+ assert.ok(this.$volumeBarScrubber, 'volume bar scrubber must be present')
440
+ this.$volumeBarScrubber.css({ left: pos })
441
+
442
+ // update volume bar segments on segmented bar mode
443
+ this.$volumeBarContainer.find('.segmented-bar-element').removeClass('fill')
444
+ const item = Math.ceil(this.volume / 10.0)
445
+
446
+ this.$volumeBarContainer
447
+ .find('.segmented-bar-element')
448
+ .slice(0, item)
449
+ .addClass('fill')
450
+ assert.ok(this.$volumeIcon, 'volume icon must be present')
451
+ this.$volumeIcon.html('')
452
+ this.$volumeIcon.removeClass('muted')
453
+ if (!this.muted) {
454
+ this.$volumeIcon.append(volumeMaxIcon)
455
+ } else {
456
+ this.$volumeIcon.append(volumeOffIcon)
457
+ this.$volumeIcon.addClass('muted')
458
+ }
459
+ this.applyButtonStyle(this.$volumeIcon)
460
+
461
+ this.$volumeBarScrubber.css({ left: `${this.volume}%` })
462
+ this.$volumeIcon.html('')
463
+ this.$volumeIcon.removeClass('muted')
464
+
465
+ if (!this.muted) {
466
+ this.$volumeIcon.append(volumeMaxIcon)
467
+ } else {
468
+ this.$volumeIcon.append(volumeOffIcon)
469
+ this.$volumeIcon.addClass('muted')
470
+ }
471
+ this.applyButtonStyle(this.$volumeIcon)
472
+ }
473
+
474
+ private changeTogglePlay() {
475
+ // assert.ok(this.$playPauseToggle, 'play/pause toggle must be present');
476
+ this.$playPauseToggle?.html('')
477
+
478
+ // assert.ok(this.$playStopToggle, 'play/stop toggle must be present');
479
+ this.$playStopToggle?.html('')
480
+ if (this.container && this.container.isPlaying()) {
481
+ this.$playPauseToggle?.append(pauseIcon)
482
+ this.$playStopToggle?.append(pauseIcon)
483
+ this.trigger(Events.MEDIACONTROL_PLAYING)
484
+ } else {
485
+ this.$playPauseToggle?.append(playIcon)
486
+ this.$playStopToggle?.append(playIcon)
487
+ this.trigger(Events.MEDIACONTROL_NOTPLAYING)
488
+ if (Browser.isMobile) {
489
+ this.show()
490
+ }
491
+ }
492
+ this.applyButtonStyle(this.$playPauseToggle)
493
+ this.applyButtonStyle(this.$playStopToggle)
494
+ }
495
+
496
+ private mousemoveOnSeekBar(event: MouseEvent) {
497
+ if (this.settings.seekEnabled) {
498
+ // assert.ok(this.$seekBarHover && this.$seekBarContainer, 'seek bar elements must be present');
499
+ if (this.$seekBarHover && this.$seekBarContainer) {
500
+ const offsetX =
501
+ MediaControl.getPageX(event) -
502
+ this.$seekBarContainer.offset().left -
503
+ this.$seekBarHover.width() / 2
504
+
505
+ this.$seekBarHover.css({ left: offsetX })
506
+ }
507
+ }
508
+ this.trigger(Events.MEDIACONTROL_MOUSEMOVE_SEEKBAR, event)
509
+ }
510
+
511
+ private mouseleaveOnSeekBar(event: MouseEvent) {
512
+ this.trigger(Events.MEDIACONTROL_MOUSELEAVE_SEEKBAR, event)
513
+ }
514
+
515
+ private onVolumeClick(event: MouseEvent) {
516
+ this.setVolume(this.getVolumeFromUIEvent(event))
517
+ }
518
+
519
+ private mousemoveOnVolumeBar(event: MouseEvent) {
520
+ this.draggingVolumeBar && this.setVolume(this.getVolumeFromUIEvent(event))
521
+ }
522
+
523
+ private playerResize(size: { width: number; height: number }) {
524
+ if (this.container.el) {
525
+ if (isFullscreen(this.container.el)) {
526
+ this.$fullscreenToggle?.html(fullscreenOnIcon)
527
+ } else {
528
+ this.$fullscreenToggle?.html(fullscreenOffIcon)
529
+ }
530
+ }
531
+
532
+ this.applyButtonStyle(this.$fullscreenToggle)
533
+ this.$el.removeClass('w370')
534
+ this.$el.removeClass('w270')
535
+ this.verticalVolume = false
536
+ try {
537
+ const skinWidth = this.container.$el.width() || size.width
538
+
539
+ if (skinWidth <= 370 || this.options.hideVolumeBar) {
540
+ this.$el.addClass('w370')
541
+ }
542
+
543
+ if (skinWidth <= 270 && !Browser.isMobile) {
544
+ this.verticalVolume = true
545
+ this.$el.addClass('w270')
546
+ }
547
+ } catch (e) {
548
+ reportError(e)
549
+ }
550
+ }
551
+
552
+ togglePlayPause() {
553
+ this.container.isPlaying() ? this.container.pause() : this.container.play()
554
+
555
+ return false
556
+ }
557
+
558
+ togglePlayStop() {
559
+ this.container.isPlaying() ? this.container.stop() : this.container.play()
560
+ }
561
+
562
+ startSeekDrag(event: MouseEvent) {
563
+ if (!this.settings.seekEnabled) {
564
+ return
565
+ }
566
+ this.draggingSeekBar = true
567
+ this.$el.addClass('dragging')
568
+
569
+ // assert.ok(this.$seekBarLoaded && this.$seekBarPosition && this.$seekBarScrubber, 'seek bar elements must be present');
570
+ this.$seekBarLoaded?.addClass('media-control-notransition')
571
+ this.$seekBarPosition?.addClass('media-control-notransition')
572
+ this.$seekBarScrubber?.addClass('media-control-notransition')
573
+ event && event.preventDefault()
574
+ }
575
+
576
+ startVolumeDrag(event: MouseEvent) {
577
+ this.draggingVolumeBar = true
578
+ this.$el.addClass('dragging')
579
+ event && event.preventDefault()
580
+ }
581
+
582
+ stopDrag = (event: MouseEvent) => {
583
+ this.draggingSeekBar && this.seek(event)
584
+ this.$el.removeClass('dragging')
585
+ this.$seekBarLoaded?.removeClass('media-control-notransition')
586
+ this.$seekBarPosition?.removeClass('media-control-notransition')
587
+ this.$seekBarScrubber?.removeClass('media-control-notransition dragging')
588
+ this.draggingSeekBar = false
589
+ this.draggingVolumeBar = false
590
+ }
591
+
592
+ updateDrag = (event: MouseEvent | TouchEvent) => {
593
+ if (this.draggingSeekBar) {
594
+ event.preventDefault()
595
+ const pageX = MediaControl.getPageX(event)
596
+
597
+ assert.ok(this.$seekBarContainer, 'seek bar container must be present')
598
+ const offsetX = pageX - this.$seekBarContainer.offset().left
599
+ let pos = (offsetX / this.$seekBarContainer.width()) * 100
600
+
601
+ pos = Math.min(100, Math.max(pos, 0))
602
+
603
+ this.setSeekPercentage(pos)
604
+ } else if (this.draggingVolumeBar) {
605
+ event.preventDefault()
606
+ this.setVolume(this.getVolumeFromUIEvent(event))
607
+ }
608
+ }
609
+
610
+ getVolumeFromUIEvent(event: MouseEvent | TouchEvent) {
611
+ let volumeFromUI = 0
612
+
613
+ assert.ok(this.$volumeBarContainer, 'volume bar container must be present')
614
+ if (!this.verticalVolume) {
615
+ const offsetY =
616
+ MediaControl.getPageX(event) - this.$volumeBarContainer.offset().left
617
+
618
+ volumeFromUI = (offsetY / this.$volumeBarContainer.width()) * 100
619
+ } else {
620
+ const offsetX =
621
+ 80 -
622
+ Math.abs(
623
+ this.$volumeBarContainer.offset().top - MediaControl.getPageY(event),
624
+ )
625
+
626
+ volumeFromUI = (offsetX / this.$volumeBarContainer.height()) * 100
627
+ }
628
+
629
+ return volumeFromUI
630
+ }
631
+
632
+ toggleMute() {
633
+ this.setVolume(this.muted ? 100 : 0)
634
+ }
635
+
636
+ setVolume(value: number, isInitialVolume = false) {
637
+ value = Math.min(100, Math.max(value, 0))
638
+ // this will hold the intended volume
639
+ // it may not actually get set to this straight away
640
+ // if the container is not ready etc
641
+ this.intendedVolume = value
642
+ this.persistConfig && !isInitialVolume && Config.persist('volume', value)
643
+ const setWhenContainerReady = () => {
644
+ if (this.container && this.container.isReady) {
645
+ this.container.setVolume(value)
646
+ } else {
647
+ this.listenToOnce(this.container, Events.CONTAINER_READY, () => {
648
+ this.container.setVolume(value)
649
+ })
650
+ }
651
+ }
652
+
653
+ if (!this.container) {
654
+ this.listenToOnce(this, Events.MEDIACONTROL_CONTAINERCHANGED, () =>
655
+ setWhenContainerReady(),
656
+ )
657
+ } else {
658
+ setWhenContainerReady()
659
+ }
660
+ }
661
+
662
+ toggleFullscreen() {
663
+ if (!Browser.isMobile) {
664
+ this.trigger(Events.MEDIACONTROL_FULLSCREEN, this.name)
665
+ this.container.fullscreen()
666
+ this.core.toggleFullscreen()
667
+ this.resetUserKeepVisible()
668
+ }
669
+ }
670
+
671
+ onActiveContainerChanged() {
672
+ this.fullScreenOnVideoTagSupported = null
673
+ this.bindEvents()
674
+ // set the new container to match the volume of the last one
675
+ this.setInitialVolume()
676
+ this.changeTogglePlay()
677
+ this.bindContainerEvents()
678
+ this.settingsUpdate()
679
+ this.container &&
680
+ this.container.trigger(
681
+ Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
682
+ this.container.isDvrInUse(),
683
+ )
684
+ this.container && this.container.mediaControlDisabled && this.disable()
685
+ this.trigger(Events.MEDIACONTROL_CONTAINERCHANGED)
686
+
687
+ if (this.container.$el) {
688
+ this.container.$el.addClass('container-skin-1')
689
+ }
690
+
691
+ if (this.options.cropVideo) {
692
+ this.container.$el.addClass('crop-video')
693
+ }
694
+
695
+ const spinnerPlugin = this.container.getPlugin('spinner')
696
+
697
+ spinnerPlugin?.$el.find('div').addClass('gcore-skin-main-color')
698
+
699
+ const seekTimePlugin = this.container.getPlugin('seek_time')
700
+
701
+ seekTimePlugin?.$el.addClass('gcore-skin-bg-color')
702
+ seekTimePlugin?.$el.find('span').addClass('gcore-skin-text-color')
703
+ }
704
+
705
+ showVolumeBar() {
706
+ this.hideVolumeId && clearTimeout(this.hideVolumeId)
707
+ this.$volumeBarContainer?.removeClass('volume-bar-hide')
708
+ }
709
+
710
+ hideVolumeBar(timeout = 400) {
711
+ if (!this.$volumeBarContainer) {
712
+ return
713
+ }
714
+ if (this.draggingVolumeBar) {
715
+ this.hideVolumeId = setTimeout(() => this.hideVolumeBar(), timeout)
716
+ } else {
717
+ this.hideVolumeId && clearTimeout(this.hideVolumeId)
718
+ this.hideVolumeId = setTimeout(
719
+ () => this.$volumeBarContainer?.addClass('volume-bar-hide'),
720
+ timeout,
721
+ )
722
+ }
723
+ }
724
+
725
+ ended() {
726
+ this.changeTogglePlay()
727
+ }
728
+
729
+ updateProgressBar(progress: TimeProgress) {
730
+ const loadedStart = (progress.start / progress.total) * 100
731
+ const loadedEnd = (progress.current / progress.total) * 100
732
+
733
+ this.$seekBarLoaded?.css({
734
+ left: `${loadedStart}%`,
735
+ width: `${loadedEnd - loadedStart}%`,
736
+ })
737
+ }
738
+
739
+ onTimeUpdate(timeProgress: TimeProgress) {
740
+ if (this.draggingSeekBar) {
741
+ return
742
+ }
743
+ // TODO why should current time ever be negative?
744
+ const position =
745
+ timeProgress.current < 0 ? timeProgress.total : timeProgress.current
746
+
747
+ this.currentPositionValue = position
748
+ this.currentDurationValue = timeProgress.total
749
+
750
+ if (!this.draggingSeekBar) {
751
+ this.renderSeekBar()
752
+ }
753
+ }
754
+
755
+ renderSeekBar() {
756
+ // this will be triggered as soon as these become available
757
+ if (
758
+ this.currentPositionValue === null ||
759
+ this.currentDurationValue === null
760
+ ) {
761
+ return
762
+ }
763
+
764
+ // default to 100%
765
+ this.currentSeekBarPercentage = 100
766
+ if (
767
+ this.container &&
768
+ (this.container.getPlaybackType() !== Playback.LIVE ||
769
+ this.container.isDvrInUse())
770
+ ) {
771
+ this.currentSeekBarPercentage =
772
+ (this.currentPositionValue / this.currentDurationValue) * 100
773
+ }
774
+
775
+ this.setSeekPercentage(this.currentSeekBarPercentage)
776
+
777
+ this.drawDurationAndPosition()
778
+ }
779
+
780
+ drawDurationAndPosition() {
781
+ const newPosition = formatTime(this.currentPositionValue)
782
+ const newDuration = formatTime(this.currentDurationValue)
783
+
784
+ if (newPosition !== this.displayedPosition) {
785
+ this.$position?.text(newPosition)
786
+ this.displayedPosition = newPosition
787
+ }
788
+ if (newDuration !== this.displayedDuration) {
789
+ this.$duration?.text(newDuration)
790
+ this.displayedDuration = newDuration
791
+ }
792
+ }
793
+
794
+ seek(event: MouseEvent) {
795
+ if (!this.settings.seekEnabled) {
796
+ return
797
+ }
798
+
799
+ assert.ok(this.$seekBarContainer, 'seek bar container must be present')
800
+ const offsetX =
801
+ MediaControl.getPageX(event) - this.$seekBarContainer.offset().left
802
+ let pos = (offsetX / this.$seekBarContainer.width()) * 100
803
+
804
+ pos = Math.min(100, Math.max(pos, 0))
805
+ this.container && this.container.seekPercentage(pos)
806
+
807
+ this.setSeekPercentage(pos)
808
+
809
+ return false
810
+ }
811
+
812
+ setKeepVisible() {
813
+ this.keepVisible = true
814
+ }
815
+
816
+ resetKeepVisible() {
817
+ this.keepVisible = false
818
+ }
819
+
820
+ setUserKeepVisible() {
821
+ this.userKeepVisible = true
822
+ }
823
+
824
+ resetUserKeepVisible() {
825
+ this.userKeepVisible = false
826
+ }
827
+
828
+ isVisible() {
829
+ return !this.$el.hasClass('media-control-hide')
830
+ }
831
+
832
+ show(event?: MouseEvent) {
833
+ if (this.disabled || this.options.disableControlPanel) {
834
+ return
835
+ }
836
+
837
+ const timeout = 2000
838
+ const mousePointerMoved =
839
+ event &&
840
+ event.clientX !== this.lastMouseX &&
841
+ event.clientY !== this.lastMouseY
842
+
843
+ if (!event || mousePointerMoved || navigator.userAgent.match(/firefox/i)) {
844
+ if (this.hideId !== null) {
845
+ clearTimeout(this.hideId)
846
+ this.hideId = null
847
+ }
848
+ this.$el.show()
849
+ this.trigger(Events.MEDIACONTROL_SHOW, this.name)
850
+ this.container &&
851
+ this.container.trigger(Events.CONTAINER_MEDIACONTROL_SHOW, this.name)
852
+ this.$el.removeClass('media-control-hide')
853
+ this.hideId = setTimeout(() => this.hide(), timeout)
854
+ if (event) {
855
+ this.lastMouseX = event.clientX
856
+ this.lastMouseY = event.clientY
857
+ }
858
+ }
859
+ const showing = true
860
+
861
+ this.updateCursorStyle(showing)
862
+ }
863
+
864
+ hide(delay = 0) {
865
+ if (!this.isVisible()) {
866
+ return
867
+ }
868
+
869
+ const timeout = delay || 2000
870
+
871
+ if (this.hideId !== null) {
872
+ clearTimeout(this.hideId)
873
+ }
874
+
875
+ if (!this.disabled && this.options.hideMediaControl === false) {
876
+ return
877
+ }
878
+
879
+ const hasKeepVisibleRequested = this.userKeepVisible || this.keepVisible
880
+ const hasDraggingAction = this.draggingSeekBar || this.draggingVolumeBar
881
+
882
+ if (
883
+ !this.disabled &&
884
+ (delay || hasKeepVisibleRequested || hasDraggingAction)
885
+ ) {
886
+ this.hideId = setTimeout(() => this.hide(), timeout)
887
+ } else {
888
+ if (!this.options.controlsDontHide || isFullscreen(this.container.el)) {
889
+ this.trigger(Events.MEDIACONTROL_HIDE, this.name)
890
+ this.$el.addClass('media-control-hide')
891
+ this.hideVolumeBar(0)
892
+ const showing = false
893
+
894
+ this.updateCursorStyle(showing)
895
+ }
896
+ }
897
+ }
898
+
899
+ updateCursorStyle(showing: boolean) {
900
+ if (showing) {
901
+ this.core.$el.removeClass('nocursor')
902
+ } else if (this.core.isFullscreen()) {
903
+ this.core.$el.addClass('nocursor')
904
+ }
905
+ }
906
+
907
+ private settingsUpdate() {
908
+ const newSettings = this.getSettings()
909
+ $.extend(true, newSettings, {
910
+ left: [],
911
+ default: [],
912
+ right: [],
913
+ })
914
+
915
+ const LEFT_ORDER = [
916
+ 'playpause',
917
+ 'playstop',
918
+ 'live',
919
+ 'volume',
920
+ 'position',
921
+ 'duration',
922
+ ]
923
+
924
+ newSettings.left = orderByOrderPattern(
925
+ [...newSettings.left, 'clipsText', 'volume'],
926
+ LEFT_ORDER,
927
+ )
928
+
929
+ newSettings.right = [
930
+ 'fullscreen',
931
+ 'pip',
932
+ 'bottomgear',
933
+ 'subtitles',
934
+ 'multicamera',
935
+ 'playbackrate',
936
+ 'vr',
937
+ 'audiotracks',
938
+ ]
939
+
940
+ if (
941
+ (!this.fullScreenOnVideoTagSupported &&
942
+ !Fullscreen.fullscreenEnabled()) ||
943
+ this.options.fullscreenDisable
944
+ ) {
945
+ // remove fullscreen from settings if it is present
946
+ removeArrayItem(newSettings.default, 'fullscreen')
947
+ removeArrayItem(newSettings.left, 'fullscreen')
948
+ removeArrayItem(newSettings.right, 'fullscreen')
949
+ }
950
+
951
+ removeArrayItem(newSettings.default, 'hd-indicator')
952
+ removeArrayItem(newSettings.left, 'hd-indicator')
953
+
954
+ if (this.core.activePlayback.name === 'html5_video') {
955
+ newSettings.seekEnabled = this.isSeekEnabledForHtml5Playback()
956
+ }
957
+
958
+ const settingsChanged =
959
+ JSON.stringify(this.settings) !== JSON.stringify(newSettings)
960
+
961
+ if (settingsChanged) {
962
+ this.settings = newSettings
963
+ this.render()
964
+ }
965
+ }
966
+
967
+ getSettings() {
968
+ // TODO show live and remove duration/position if live
969
+ return $.extend(true, {}, this.container && this.container.settings)
970
+ }
971
+
972
+ highDefinitionUpdate(isHD: boolean) {
973
+ this.isHD = isHD
974
+ }
975
+
976
+ createCachedElements() {
977
+ const $layer = this.$el.find('.media-control-layer')
978
+
979
+ this.$duration = $layer.find('.media-control-indicator[data-duration]')
980
+ this.$fullscreenToggle = $layer.find(
981
+ 'button.media-control-button[data-fullscreen]',
982
+ )
983
+ this.$playPauseToggle = $layer.find(
984
+ 'button.media-control-button[data-playpause]',
985
+ )
986
+ this.$playStopToggle = $layer.find(
987
+ 'button.media-control-button[data-playstop]',
988
+ )
989
+ this.$position = $layer.find('.media-control-indicator[data-position]')
990
+ this.$seekBarContainer = $layer.find('.bar-container[data-seekbar]')
991
+ this.$seekBarLoaded = $layer.find('.bar-fill-1[data-seekbar]')
992
+ this.$seekBarPosition = $layer.find('.bar-fill-2[data-seekbar]')
993
+ this.$seekBarScrubber = $layer.find('.bar-scrubber[data-seekbar]')
994
+ this.$seekBarHover = $layer.find('.bar-hover[data-seekbar]')
995
+ this.$volumeBarContainer = $layer.find('.bar-container[data-volume]')
996
+ this.$volumeContainer = $layer.find('.drawer-container[data-volume]')
997
+ this.$volumeIcon = $layer.find('.drawer-icon[data-volume]')
998
+ this.$volumeBarBackground = this.$el.find('.bar-background[data-volume]')
999
+ this.$volumeBarFill = this.$el.find('.bar-fill-1[data-volume]')
1000
+ this.$volumeBarScrubber = this.$el.find('.bar-scrubber[data-volume]')
1001
+ this.$bottomGear = this.$el.find('.media-control-bottomgear')
1002
+ this.$pip = this.$el.find('.media-control-pip')
1003
+ this.$audioTracksSelector = this.$el.find(
1004
+ '.media-control-audio-tracks[data-audiotracks]',
1005
+ )
1006
+ this.$subtitlesSelector = this.$el.find(
1007
+ '.media-control-subtitles[data-subtitles]',
1008
+ )
1009
+ this.$playbackRate = this.$el.find(
1010
+ '.media-control-playbackrate[data-playbackrate]',
1011
+ )
1012
+ this.$multiCameraSelector = this.$el.find(
1013
+ '.media-control-multicamera[data-multicamera]',
1014
+ )
1015
+ this.$clipText = this.$el.find('.media-clip-text[data-clipstext]')
1016
+ this.$clipTextContainer = this.$el.find(
1017
+ '.media-clip-container[data-clipstext]',
1018
+ )
1019
+
1020
+ this.resetIndicators()
1021
+ this.initializeIcons()
1022
+ }
1023
+
1024
+ getElement(name: MediaControlElement): ZeptoResult | null {
1025
+ switch (name) {
1026
+ case 'pip':
1027
+ return this.$pip
1028
+ }
1029
+ return null
1030
+ }
1031
+
1032
+ resetIndicators() {
1033
+ assert.ok(
1034
+ this.$duration && this.$position,
1035
+ 'duration and position elements must be present',
1036
+ )
1037
+ this.displayedPosition = (this.$position.text as () => string)()
1038
+ this.displayedDuration = (this.$duration.text as () => string)()
1039
+ }
1040
+
1041
+ initializeIcons() {
1042
+ const $layer = this.$el.find('.media-control-layer')
1043
+
1044
+ $layer.find('button.media-control-button[data-play]').append(playIcon)
1045
+ $layer.find('button.media-control-button[data-pause]').append(pauseIcon)
1046
+ $layer.find('button.media-control-button[data-stop]').append(stopIcon)
1047
+ this.$playPauseToggle?.append(playIcon)
1048
+ this.$playStopToggle?.append(playIcon)
1049
+ this.$volumeIcon?.append(volumeMaxIcon)
1050
+ this.$fullscreenToggle?.append(fullscreenOffIcon)
1051
+ }
1052
+
1053
+ setSeekPercentage(value: number) {
1054
+ value = Math.max(Math.min(value, 100.0), 0)
1055
+ // not changed since last update
1056
+ if (this.displayedSeekBarPercentage === value) {
1057
+ return
1058
+ }
1059
+
1060
+ this.displayedSeekBarPercentage = value
1061
+
1062
+ // assert.ok(this.$seekBarPosition && this.$seekBarScrubber, 'seek bar elements must be present');
1063
+ this.$seekBarPosition?.removeClass('media-control-notransition')
1064
+ this.$seekBarScrubber?.removeClass('media-control-notransition')
1065
+ this.$seekBarPosition?.css({ width: `${value}%` })
1066
+ this.$seekBarScrubber?.css({ left: `${value}%` })
1067
+ }
1068
+
1069
+ seekRelative(delta: number) {
1070
+ if (!this.settings.seekEnabled) {
1071
+ return
1072
+ }
1073
+
1074
+ const currentTime = this.container.getCurrentTime()
1075
+ const duration = this.container.getDuration()
1076
+ let position = Math.min(Math.max(currentTime + delta, 0), duration)
1077
+
1078
+ position = Math.min((position * 100) / duration, 100)
1079
+ this.container.seekPercentage(position)
1080
+ }
1081
+
1082
+ bindKeyAndShow(key: string, callback: () => boolean | undefined) {
1083
+ // TODO or boolean return type
1084
+ this.kibo.down(key, () => {
1085
+ this.show()
1086
+
1087
+ return callback()
1088
+ })
1089
+ }
1090
+
1091
+ bindKeyEvents() {
1092
+ if (Browser.isMobile || this.options.disableKeyboardShortcuts) {
1093
+ return
1094
+ }
1095
+
1096
+ this.unbindKeyEvents()
1097
+ this.kibo = new Kibo(
1098
+ this.options.focusElement || this.options.parentElement,
1099
+ )
1100
+ this.bindKeyAndShow('space', () => this.togglePlayPause())
1101
+ this.bindKeyAndShow('left', () => {
1102
+ this.seekRelative(-5)
1103
+ return true
1104
+ })
1105
+ this.bindKeyAndShow('right', () => {
1106
+ this.seekRelative(5)
1107
+ return true
1108
+ })
1109
+ this.bindKeyAndShow('shift left', () => {
1110
+ this.seekRelative(-10)
1111
+ return true
1112
+ })
1113
+ this.bindKeyAndShow('shift right', () => {
1114
+ this.seekRelative(10)
1115
+ return true
1116
+ })
1117
+ this.bindKeyAndShow('shift ctrl left', () => {
1118
+ this.seekRelative(-15)
1119
+ return true
1120
+ })
1121
+ this.bindKeyAndShow('shift ctrl right', () => {
1122
+ this.seekRelative(15)
1123
+ return true
1124
+ })
1125
+ const keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
1126
+
1127
+ keys.forEach((i) => {
1128
+ this.bindKeyAndShow(i, () => {
1129
+ this.settings.seekEnabled &&
1130
+ this.container &&
1131
+ this.container.seekPercentage(Number(i) * 10)
1132
+ return false
1133
+ })
1134
+ })
1135
+ }
1136
+
1137
+ unbindKeyEvents() {
1138
+ if (this.kibo) {
1139
+ this.kibo.off('space')
1140
+ this.kibo.off('left')
1141
+ this.kibo.off('right')
1142
+ this.kibo.off('shift left')
1143
+ this.kibo.off('shift right')
1144
+ this.kibo.off('shift ctrl left')
1145
+ this.kibo.off('shift ctrl right')
1146
+ this.kibo.off(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'])
1147
+ }
1148
+ }
1149
+
1150
+ parseColors() {
1151
+ const design = this.options.design || {}
1152
+
1153
+ let variables: string[] = []
1154
+
1155
+ if (!template) {
1156
+ return
1157
+ }
1158
+
1159
+ // TODO camel case
1160
+ if (design.background_color) {
1161
+ variables = variables.concat([
1162
+ `--theme-background-color: ${design.background_color};`,
1163
+ ])
1164
+ }
1165
+
1166
+ if (design.text_color) {
1167
+ variables = variables.concat([
1168
+ `--theme-text-color: ${design.text_color};`,
1169
+ ])
1170
+ }
1171
+
1172
+ if (design.foreground_color) {
1173
+ variables = variables.concat([
1174
+ `--theme-foreground-color: ${design.foreground_color};`,
1175
+ ])
1176
+ }
1177
+
1178
+ if (design.hover_color) {
1179
+ variables = variables.concat([
1180
+ `--theme-hover-color: ${design.hover_color};`,
1181
+ ])
1182
+ }
1183
+
1184
+ this.$el.append(`<style>:root {${variables.join('\n')}}</style>`)
1185
+ }
1186
+
1187
+ applyButtonStyle(element: ZeptoResult | undefined) {
1188
+ this.buttonsColor &&
1189
+ element &&
1190
+ $(element).find('svg path').css({ fill: this.buttonsColor })
1191
+ }
1192
+
1193
+ override destroy() {
1194
+ $(document).unbind('mouseup', this.stopDrag)
1195
+ $(document).unbind('mousemove', this.updateDrag)
1196
+ this.unbindKeyEvents()
1197
+ // @ts-ignore
1198
+ this.stopListening()
1199
+ return super.destroy()
1200
+ }
1201
+
1202
+ configure() {
1203
+ this.advertisementPlaying ? this.disable() : this.enable()
1204
+ this.trigger(Events.MEDIACONTROL_OPTIONS_CHANGE)
1205
+ }
1206
+
1207
+ override render() {
1208
+ const timeout = this.options.hideMediaControlDelay || 2000
1209
+
1210
+ const html = this.template({ settings: this.settings ?? {} })
1211
+ this.$el.html(html)
1212
+ // const style = Styler.getStyleFor(mediaControlStyle, { baseUrl: this.options.baseUrl });
1213
+ // this.$el.append(style[0]);
1214
+ this.createCachedElements()
1215
+
1216
+ this.drawDurationAndPosition()
1217
+
1218
+ this.$playPauseToggle?.addClass('paused')
1219
+ this.$playStopToggle?.addClass('stopped')
1220
+
1221
+ this.changeTogglePlay()
1222
+
1223
+ if (this.container) {
1224
+ this.hideId = setTimeout(() => this.hide(), timeout)
1225
+ this.disabled && this.hide()
1226
+ }
1227
+
1228
+ // Video volume cannot be changed with Safari on mobile devices
1229
+ // Display mute/unmute icon only if Safari version >= 10
1230
+ if (Browser.isSafari && Browser.isMobile) {
1231
+ if (Browser.version < 10) {
1232
+ this.$volumeContainer?.css({ display: 'none' })
1233
+ } else {
1234
+ this.$volumeBarContainer?.css({ display: 'none' })
1235
+ }
1236
+ }
1237
+
1238
+ this.$seekBarPosition?.addClass('media-control-notransition')
1239
+ this.$seekBarScrubber?.addClass('media-control-notransition')
1240
+
1241
+ let previousSeekPercentage = 0
1242
+
1243
+ if (this.displayedSeekBarPercentage) {
1244
+ previousSeekPercentage = this.displayedSeekBarPercentage
1245
+ }
1246
+
1247
+ this.displayedSeekBarPercentage = null
1248
+ this.setSeekPercentage(previousSeekPercentage)
1249
+
1250
+ setTimeout(() => {
1251
+ !this.settings.seekEnabled &&
1252
+ this.$seekBarContainer?.addClass('seek-disabled')
1253
+ !Browser.isMobile &&
1254
+ !this.options.disableKeyboardShortcuts &&
1255
+ this.bindKeyEvents()
1256
+ this.playerResize({
1257
+ width: this.options.width,
1258
+ height: this.options.height,
1259
+ })
1260
+ this.hideVolumeBar(0)
1261
+ }, 0)
1262
+
1263
+ this.parseColors()
1264
+ this.highDefinitionUpdate(this.isHD)
1265
+
1266
+ this.core.$el.append(this.el)
1267
+
1268
+ this.rendered = true
1269
+ this.updateVolumeUI()
1270
+ this.trigger(Events.MEDIACONTROL_RENDERED)
1271
+
1272
+ return this
1273
+ }
1274
+
1275
+ get bigPlayButton() {
1276
+ return playIcon
1277
+ }
1278
+
1279
+ private handleFullScreenOnBtn() {
1280
+ this.trigger(Events.MEDIACONTROL_FULLSCREEN, this.name)
1281
+ this.container.fullscreen()
1282
+ // TODO: fix after it full screen will be fixed on iOS
1283
+ if (Browser.isiOS) {
1284
+ if (this.core.isFullscreen()) {
1285
+ Fullscreen.cancelFullscreen(this.core.el)
1286
+ } else {
1287
+ Fullscreen.requestFullscreen(this.core.el)
1288
+ }
1289
+ } else {
1290
+ this.core.toggleFullscreen()
1291
+ }
1292
+ this.resetUserKeepVisible()
1293
+ }
1294
+
1295
+ onStartAd() {
1296
+ this.advertisementPlaying = true
1297
+ this.disable()
1298
+ }
1299
+
1300
+ onFinishAd() {
1301
+ this.advertisementPlaying = false
1302
+ this.enable()
1303
+ }
1304
+
1305
+ setClipText(txt: unknown) {
1306
+ if (this.$clipText && txt) {
1307
+ this.$clipTextContainer?.show()
1308
+ this.$clipText.text(`${txt}`)
1309
+ }
1310
+ }
1311
+
1312
+ hideControllAds() {
1313
+ if (
1314
+ this.container.advertisement &&
1315
+ this.container.advertisement.type !== 'idle'
1316
+ ) {
1317
+ this.hide()
1318
+ }
1319
+ }
1320
+
1321
+ setSVGMask(svg: string) {
1322
+ if (this.svgMask) {
1323
+ this.svgMask.remove()
1324
+ }
1325
+
1326
+ if (this.$seekBarContainer?.get(0)) {
1327
+ this.$seekBarContainer.addClass('clips')
1328
+ }
1329
+
1330
+ this.svgMask = $(svg)
1331
+ this.$seekBarContainer?.append(this.svgMask)
1332
+ }
1333
+
1334
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=109212
1335
+ setMuted(value: boolean) {
1336
+ this.container.options.mute = value
1337
+ }
1338
+
1339
+ private static getPageX(event: MouseEvent | TouchEvent): number {
1340
+ return getPageX(event)
1341
+ }
1342
+
1343
+ private static getPageY(event: MouseEvent | TouchEvent): number {
1344
+ if ((event as MouseEvent).pageY) {
1345
+ return (event as MouseEvent).pageY
1346
+ }
1347
+
1348
+ if ((event as TouchEvent).changedTouches) {
1349
+ return (event as TouchEvent).changedTouches[
1350
+ (event as TouchEvent).changedTouches.length - 1
1351
+ ].pageY
1352
+ }
1353
+
1354
+ return 0
1355
+ }
1356
+
1357
+ //Решают проблему, когда нам не нужно, чтобы с помощью контролов человек мог запускать
1358
+ // или останавливать поток, контролы, которыми он управляет не должны работать
1359
+ enableControlButton() {
1360
+ this.disabledClickableList.forEach((element) => {
1361
+ element.el.css({ 'pointer-events': element.pointerEventValue })
1362
+ })
1363
+ }
1364
+
1365
+ disabledControlButton() {
1366
+ this.disabledClickableList.forEach((element) => {
1367
+ element.el.css({ 'pointer-events': 'none' })
1368
+ })
1369
+ }
1370
+
1371
+ isSeekEnabledForHtml5Playback() {
1372
+ if (this.core.getPlaybackType() === Playback.LIVE) {
1373
+ return this.options.dvrEnabled
1374
+ }
1375
+
1376
+ return isFinite(this.core.activePlayback.getDuration())
1377
+ }
1378
+ }
1379
+
1380
+ // TODO drop?
1381
+ MediaControl.extend = function (properties) {
1382
+ return extend(MediaControl, properties)
1383
+ }