@gcorevideo/player 2.19.15 → 2.20.3

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 (338) hide show
  1. package/assets/level-selector/list.ejs +1 -1
  2. package/dist/core.js +2 -2
  3. package/dist/index.css +966 -966
  4. package/dist/index.js +884 -627
  5. package/dist/player.d.ts +536 -122
  6. package/dist/plugins/index.css +1160 -1160
  7. package/dist/plugins/index.js +2006 -1725
  8. package/docs/api/player.audioselector.md +1 -251
  9. package/docs/api/player.bigmutebutton.md +1 -156
  10. package/docs/api/player.clapprnerdstats.md +12 -259
  11. package/docs/api/player.clapprstats.exportmetrics.md +4 -0
  12. package/docs/api/player.clapprstats.md +7 -223
  13. package/docs/api/player.clapprstats.setupdatemetrics.md +2 -0
  14. package/docs/api/player.clicktopause.md +5 -113
  15. package/docs/api/player.clipsplugin.gettext.md +9 -0
  16. package/docs/api/player.clipsplugin.md +10 -94
  17. package/docs/api/{player.playbackrate.setselectedrate.md → player.clipspluginsettings.md} +18 -10
  18. package/docs/api/player.clipspluginsettings.text.md +13 -0
  19. package/docs/api/player.contextmenu._constructor_.md +6 -3
  20. package/docs/api/player.contextmenu.md +13 -256
  21. package/docs/api/player.contextmenupluginsettings.label.md +11 -0
  22. package/docs/api/player.contextmenupluginsettings.md +93 -0
  23. package/docs/api/player.contextmenupluginsettings.preventshowcontextmenu.md +11 -0
  24. package/docs/api/player.contextmenupluginsettings.url.md +11 -0
  25. package/docs/api/player.dvrcontrols.md +5 -1
  26. package/docs/api/player.errorscreen.attributes.md +3 -0
  27. package/docs/api/player.errorscreen.bindevents.md +3 -0
  28. package/docs/api/player.errorscreen.container.md +3 -0
  29. package/docs/api/player.errorscreen.hide.md +3 -0
  30. package/docs/api/player.errorscreen.md +25 -0
  31. package/docs/api/player.errorscreen.name.md +3 -0
  32. package/docs/api/player.errorscreen.render.md +3 -0
  33. package/docs/api/player.errorscreen.show.md +3 -0
  34. package/docs/api/player.errorscreen.supportedversion.md +3 -0
  35. package/docs/api/player.errorscreen.template.md +3 -0
  36. package/docs/api/player.errorscreen.unbindevents.md +3 -0
  37. package/docs/api/player.favicon._constructor_.md +3 -0
  38. package/docs/api/player.favicon.bindevents.md +3 -0
  39. package/docs/api/player.favicon.configure.md +3 -0
  40. package/docs/api/player.favicon.destroy.md +3 -0
  41. package/docs/api/player.favicon.disable.md +3 -0
  42. package/docs/api/player.favicon.md +18 -1
  43. package/docs/api/player.favicon.name.md +3 -0
  44. package/docs/api/player.favicon.supportedversion.md +3 -0
  45. package/docs/api/player.gearevents.md +4 -1
  46. package/docs/api/player.googleanalytics._constructor_.md +3 -0
  47. package/docs/api/player.googleanalytics.addeventlisteners.md +3 -0
  48. package/docs/api/player.googleanalytics.embedscript.md +3 -0
  49. package/docs/api/player.googleanalytics.md +42 -1
  50. package/docs/api/player.googleanalytics.name.md +3 -0
  51. package/docs/api/player.googleanalytics.onbufferfull.md +3 -0
  52. package/docs/api/player.googleanalytics.onbuffering.md +3 -0
  53. package/docs/api/player.googleanalytics.ondvr.md +3 -0
  54. package/docs/api/player.googleanalytics.onended.md +3 -0
  55. package/docs/api/player.googleanalytics.onerror.md +3 -0
  56. package/docs/api/player.googleanalytics.onfullscreen.md +3 -0
  57. package/docs/api/player.googleanalytics.onhd.md +3 -0
  58. package/docs/api/player.googleanalytics.onpause.md +3 -0
  59. package/docs/api/player.googleanalytics.onplay.md +3 -0
  60. package/docs/api/player.googleanalytics.onready.md +3 -0
  61. package/docs/api/player.googleanalytics.onseek.md +3 -0
  62. package/docs/api/player.googleanalytics.onstop.md +3 -0
  63. package/docs/api/player.googleanalytics.onvolumechanged.md +3 -0
  64. package/docs/api/player.googleanalytics.push.md +3 -0
  65. package/docs/api/player.googleanalytics.supportedversion.md +3 -0
  66. package/docs/api/{player.clapprstats.name.md → player.initeventdata.event.md} +3 -3
  67. package/docs/api/player.initeventdata.md +60 -0
  68. package/docs/api/player.logo._constructor_.md +3 -0
  69. package/docs/api/player.logo.attributes.md +3 -0
  70. package/docs/api/player.logo.bindevents.md +3 -0
  71. package/docs/api/player.logo.md +20 -1
  72. package/docs/api/player.logo.name.md +3 -0
  73. package/docs/api/player.logo.render.md +3 -0
  74. package/docs/api/player.logo.stoplistening.md +3 -0
  75. package/docs/api/player.logo.supportedversion.md +3 -0
  76. package/docs/api/player.logo.template.md +3 -0
  77. package/docs/api/player.md +149 -18
  78. package/docs/api/player.mediacontrolelement.md +1 -1
  79. package/docs/api/player.multicamera.md +2 -0
  80. package/docs/api/player.pictureinpicture.md +9 -197
  81. package/docs/api/player.playbackrate.md +10 -314
  82. package/docs/api/player.seektime.attributes.md +3 -0
  83. package/docs/api/player.seektime.bindevents.md +3 -0
  84. package/docs/api/player.seektime.durationshown.md +3 -0
  85. package/docs/api/player.seektime.getseektime.md +3 -0
  86. package/docs/api/player.seektime.islivestreamwithdvr.md +3 -0
  87. package/docs/api/player.seektime.md +31 -0
  88. package/docs/api/player.seektime.mediacontrol.md +3 -0
  89. package/docs/api/player.seektime.mediacontrolcontainer.md +3 -0
  90. package/docs/api/player.seektime.name.md +3 -0
  91. package/docs/api/player.seektime.render.md +3 -0
  92. package/docs/api/player.seektime.shouldbevisible.md +3 -0
  93. package/docs/api/player.seektime.supportedversion.md +3 -0
  94. package/docs/api/player.seektime.template.md +3 -0
  95. package/docs/api/player.seektime.update.md +3 -0
  96. package/docs/api/player.share.md +2 -0
  97. package/docs/api/player.skiptime.md +2 -0
  98. package/docs/api/{player.clapprstats.destroy.md → player.stalleventdata.count.md} +5 -7
  99. package/docs/api/{player.bigmutebutton.template.md → player.stalleventdata.event.md} +3 -3
  100. package/docs/api/player.stalleventdata.md +117 -0
  101. package/docs/api/{player.audioselector.onshowlevelselectmenu.md → player.stalleventdata.time.md} +5 -7
  102. package/docs/api/{player.clapprstats.starttimers.md → player.stalleventdata.total_ms.md} +5 -7
  103. package/docs/api/{player.audioselector.template.md → player.starteventdata.event.md} +3 -3
  104. package/docs/api/player.starteventdata.md +60 -0
  105. package/docs/api/{player.clapprstats._defaultreport.md → player.telemetry._constructor_.md} +7 -9
  106. package/docs/api/player.telemetry.md +146 -0
  107. package/docs/api/{player.clapprnerdstats.name.md → player.telemetry.name.md} +4 -2
  108. package/docs/api/{player.clapprstats.supportedversion.md → player.telemetry.supportedversion.md} +4 -2
  109. package/docs/api/player.telemetryevent.md +100 -0
  110. package/docs/api/player.telemetryeventdata.md +18 -0
  111. package/docs/api/player.telemetrypluginsettings.md +60 -0
  112. package/docs/api/{player.audioselector.bindevents.md → player.telemetrypluginsettings.send.md} +5 -7
  113. package/docs/api/{player.audioselector.reload.md → player.telemetryrecord.md} +8 -6
  114. package/docs/api/player.thumbnails.md +21 -139
  115. package/docs/api/player.thumbnailspluginsettings.md +23 -0
  116. package/docs/api/player.volumefade.md +1 -93
  117. package/docs/api/{player.audioselector.name.md → player.watcheventdata.event.md} +3 -3
  118. package/docs/api/player.watcheventdata.md +60 -0
  119. package/lib/index.plugins.d.ts +2 -3
  120. package/lib/index.plugins.d.ts.map +1 -1
  121. package/lib/index.plugins.js +2 -3
  122. package/lib/playback/hls-playback/HlsPlayback.js +1 -1
  123. package/lib/plugins/audio-selector/AudioSelector.d.ts +28 -6
  124. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
  125. package/lib/plugins/audio-selector/AudioSelector.js +52 -22
  126. package/lib/plugins/big-mute-button/BigMuteButton.d.ts +18 -2
  127. package/lib/plugins/big-mute-button/BigMuteButton.d.ts.map +1 -1
  128. package/lib/plugins/big-mute-button/BigMuteButton.js +21 -16
  129. package/lib/plugins/bottom-gear/BottomGear.d.ts +1 -0
  130. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  131. package/lib/plugins/bottom-gear/BottomGear.js +1 -0
  132. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +38 -5
  133. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  134. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +63 -17
  135. package/lib/plugins/clappr-stats/ClapprStats.d.ts +31 -8
  136. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
  137. package/lib/plugins/clappr-stats/ClapprStats.js +24 -0
  138. package/lib/plugins/clappr-stats/types.d.ts +12 -0
  139. package/lib/plugins/clappr-stats/types.d.ts.map +1 -1
  140. package/lib/plugins/clappr-stats/types.js +3 -0
  141. package/lib/plugins/click-to-pause/ClickToPause.d.ts +13 -1
  142. package/lib/plugins/click-to-pause/ClickToPause.d.ts.map +1 -1
  143. package/lib/plugins/click-to-pause/ClickToPause.js +14 -4
  144. package/lib/plugins/clips/Clips.d.ts +34 -2
  145. package/lib/plugins/clips/Clips.d.ts.map +1 -1
  146. package/lib/plugins/clips/Clips.js +51 -22
  147. package/lib/plugins/context-menu/ContextMenu.d.ts +40 -13
  148. package/lib/plugins/context-menu/ContextMenu.d.ts.map +1 -1
  149. package/lib/plugins/context-menu/ContextMenu.js +48 -36
  150. package/lib/plugins/dvr-controls/DvrControls.d.ts +5 -4
  151. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  152. package/lib/plugins/dvr-controls/DvrControls.js +15 -29
  153. package/lib/plugins/error-screen/ErrorScreen.d.ts +4 -0
  154. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
  155. package/lib/plugins/error-screen/ErrorScreen.js +4 -0
  156. package/lib/plugins/favicon/Favicon.d.ts +4 -0
  157. package/lib/plugins/favicon/Favicon.d.ts.map +1 -1
  158. package/lib/plugins/favicon/Favicon.js +4 -0
  159. package/lib/plugins/google-analytics/GoogleAnalytics.d.ts +4 -0
  160. package/lib/plugins/google-analytics/GoogleAnalytics.d.ts.map +1 -1
  161. package/lib/plugins/google-analytics/GoogleAnalytics.js +5 -1
  162. package/lib/plugins/index.d.ts +2 -4
  163. package/lib/plugins/index.d.ts.map +1 -1
  164. package/lib/plugins/index.js +2 -4
  165. package/lib/plugins/logo/Logo.d.ts +4 -0
  166. package/lib/plugins/logo/Logo.d.ts.map +1 -1
  167. package/lib/plugins/logo/Logo.js +4 -0
  168. package/lib/plugins/media-control/MediaControl.d.ts +1 -1
  169. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  170. package/lib/plugins/media-control/MediaControl.js +3 -1
  171. package/lib/plugins/multi-camera/MultiCamera.d.ts +3 -0
  172. package/lib/plugins/multi-camera/MultiCamera.d.ts.map +1 -1
  173. package/lib/plugins/multi-camera/MultiCamera.js +3 -0
  174. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +32 -4
  175. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
  176. package/lib/plugins/picture-in-picture/PictureInPicture.js +30 -2
  177. package/lib/plugins/playback-rate/PlaybackRate.d.ts +47 -14
  178. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  179. package/lib/plugins/playback-rate/PlaybackRate.js +38 -9
  180. package/lib/plugins/seek-time/SeekTime.d.ts +4 -0
  181. package/lib/plugins/seek-time/SeekTime.d.ts.map +1 -1
  182. package/lib/plugins/seek-time/SeekTime.js +5 -1
  183. package/lib/plugins/share/Share.d.ts +3 -0
  184. package/lib/plugins/share/Share.d.ts.map +1 -1
  185. package/lib/plugins/share/Share.js +3 -0
  186. package/lib/plugins/skip-time/SkipTime.d.ts +3 -0
  187. package/lib/plugins/skip-time/SkipTime.d.ts.map +1 -1
  188. package/lib/plugins/skip-time/SkipTime.js +3 -0
  189. package/lib/plugins/statistics/Statistics.d.ts +38 -3
  190. package/lib/plugins/statistics/Statistics.d.ts.map +1 -1
  191. package/lib/plugins/statistics/Statistics.js +51 -9
  192. package/lib/plugins/telemetry/Telemetry.d.ts +153 -0
  193. package/lib/plugins/telemetry/Telemetry.d.ts.map +1 -0
  194. package/lib/plugins/telemetry/Telemetry.js +181 -0
  195. package/lib/plugins/thumbnails/Thumbnails.d.ts +48 -3
  196. package/lib/plugins/thumbnails/Thumbnails.d.ts.map +1 -1
  197. package/lib/plugins/thumbnails/Thumbnails.js +52 -18
  198. package/lib/plugins/volume-fade/VolumeFade.d.ts +8 -1
  199. package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -1
  200. package/lib/plugins/volume-fade/VolumeFade.js +9 -1
  201. package/package.json +1 -1
  202. package/src/index.plugins.ts +2 -3
  203. package/src/playback/hls-playback/HlsPlayback.ts +1 -1
  204. package/src/plugins/audio-selector/AudioSelector.ts +227 -154
  205. package/src/plugins/big-mute-button/BigMuteButton.ts +100 -79
  206. package/src/plugins/bottom-gear/BottomGear.ts +1 -0
  207. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +240 -173
  208. package/src/plugins/clappr-stats/ClapprStats.ts +32 -8
  209. package/src/plugins/clappr-stats/types.ts +13 -0
  210. package/src/plugins/click-to-pause/ClickToPause.ts +47 -36
  211. package/src/plugins/clips/Clips.ts +127 -71
  212. package/src/plugins/context-menu/ContextMenu.ts +105 -76
  213. package/src/plugins/dvr-controls/DvrControls.ts +15 -31
  214. package/src/plugins/error-screen/ErrorScreen.ts +4 -0
  215. package/src/plugins/favicon/Favicon.ts +4 -0
  216. package/src/plugins/google-analytics/GoogleAnalytics.ts +5 -1
  217. package/src/plugins/index.ts +2 -4
  218. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +47 -26
  219. package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +18 -18
  220. package/src/plugins/logo/Logo.ts +4 -0
  221. package/src/plugins/media-control/MediaControl.ts +4 -1
  222. package/src/plugins/multi-camera/MultiCamera.ts +3 -0
  223. package/src/plugins/picture-in-picture/PictureInPicture.ts +35 -7
  224. package/src/plugins/playback-rate/PlaybackRate.ts +53 -24
  225. package/src/plugins/seek-time/SeekTime.ts +5 -1
  226. package/src/plugins/share/Share.ts +3 -0
  227. package/src/plugins/skip-time/SkipTime.ts +3 -0
  228. package/src/plugins/telemetry/Telemetry.ts +317 -0
  229. package/src/plugins/thumbnails/Thumbnails.ts +268 -194
  230. package/src/plugins/volume-fade/VolumeFade.ts +10 -2
  231. package/temp/player.api.json +2457 -5257
  232. package/tsconfig.tsbuildinfo +1 -1
  233. package/docs/api/player.audioselector.attributes.md +0 -17
  234. package/docs/api/player.audioselector.events.md +0 -17
  235. package/docs/api/player.audioselector.hideselecttrackmenu.md +0 -18
  236. package/docs/api/player.audioselector.render.md +0 -18
  237. package/docs/api/player.audioselector.supportedversion.md +0 -16
  238. package/docs/api/player.audioselector.togglecontextmenu.md +0 -18
  239. package/docs/api/player.audioselector.unbindevents.md +0 -18
  240. package/docs/api/player.audioselector.version.md +0 -14
  241. package/docs/api/player.bigmutebutton.bindevents.md +0 -18
  242. package/docs/api/player.bigmutebutton.events.md +0 -17
  243. package/docs/api/player.bigmutebutton.name.md +0 -14
  244. package/docs/api/player.bigmutebutton.render.md +0 -18
  245. package/docs/api/player.bigmutebutton.supportedversion.md +0 -16
  246. package/docs/api/player.clapprnerdstats.attributes.md +0 -17
  247. package/docs/api/player.clapprnerdstats.bindevents.md +0 -18
  248. package/docs/api/player.clapprnerdstats.events.md +0 -18
  249. package/docs/api/player.clapprnerdstats.playerheight.md +0 -14
  250. package/docs/api/player.clapprnerdstats.playerwidth.md +0 -14
  251. package/docs/api/player.clapprnerdstats.render.md +0 -18
  252. package/docs/api/player.clapprnerdstats.statsboxelem.md +0 -14
  253. package/docs/api/player.clapprnerdstats.statsboxwidththreshold.md +0 -14
  254. package/docs/api/player.clapprnerdstats.supportedversion.md +0 -16
  255. package/docs/api/player.clapprnerdstats.template.md +0 -14
  256. package/docs/api/player.clapprstats._buildreport.md +0 -18
  257. package/docs/api/player.clapprstats._playbackname.md +0 -14
  258. package/docs/api/player.clapprstats._playbacktype.md +0 -14
  259. package/docs/api/player.clapprstats.bindevents.md +0 -18
  260. package/docs/api/player.clapprstats.onfirstplaying.md +0 -18
  261. package/docs/api/player.clapprstats.playafterpause.md +0 -18
  262. package/docs/api/player.clapprstats.stopreporting.md +0 -18
  263. package/docs/api/player.clicktopause.bindevents.md +0 -15
  264. package/docs/api/player.clicktopause.config.md +0 -11
  265. package/docs/api/player.clicktopause.name.md +0 -11
  266. package/docs/api/player.clicktopause.supportedversion.md +0 -13
  267. package/docs/api/player.clipsplugin.attributes.md +0 -13
  268. package/docs/api/player.clipsplugin.bindevents.md +0 -15
  269. package/docs/api/player.clipsplugin.makesvg.md +0 -49
  270. package/docs/api/player.clipsplugin.name.md +0 -11
  271. package/docs/api/player.clipsplugin.unbindevents.md +0 -15
  272. package/docs/api/player.contextmenu.attributes.md +0 -13
  273. package/docs/api/player.contextmenu.bindevents.md +0 -15
  274. package/docs/api/player.contextmenu.destroy.md +0 -15
  275. package/docs/api/player.contextmenu.events.md +0 -13
  276. package/docs/api/player.contextmenu.exposeversion.md +0 -14
  277. package/docs/api/player.contextmenu.label.md +0 -11
  278. package/docs/api/player.contextmenu.mediacontrol.md +0 -11
  279. package/docs/api/player.contextmenu.name.md +0 -11
  280. package/docs/api/player.contextmenu.render.md +0 -15
  281. package/docs/api/player.contextmenu.supportedversion.md +0 -13
  282. package/docs/api/player.contextmenu.template.md +0 -11
  283. package/docs/api/player.contextmenu.url.md +0 -11
  284. package/docs/api/player.disablecontrols.bindevents.md +0 -15
  285. package/docs/api/player.disablecontrols.container.md +0 -11
  286. package/docs/api/player.disablecontrols.md +0 -138
  287. package/docs/api/player.disablecontrols.name.md +0 -11
  288. package/docs/api/player.disablecontrols.supportedversion.md +0 -13
  289. package/docs/api/player.disablecontrols.unbindevents.md +0 -15
  290. package/docs/api/player.pictureinpicture.bindevents.md +0 -15
  291. package/docs/api/player.pictureinpicture.events.md +0 -13
  292. package/docs/api/player.pictureinpicture.exitpictureinpicture.md +0 -15
  293. package/docs/api/player.pictureinpicture.name.md +0 -11
  294. package/docs/api/player.pictureinpicture.render.md +0 -15
  295. package/docs/api/player.pictureinpicture.requestpictureinpicture.md +0 -15
  296. package/docs/api/player.pictureinpicture.supportedversion.md +0 -13
  297. package/docs/api/player.pictureinpicture.togglepictureinpicture.md +0 -15
  298. package/docs/api/player.pictureinpicture.version.md +0 -11
  299. package/docs/api/player.pictureinpicture.videoelement.md +0 -11
  300. package/docs/api/player.playbackrate.attributes.md +0 -14
  301. package/docs/api/player.playbackrate.bindevents.md +0 -15
  302. package/docs/api/player.playbackrate.events.md +0 -15
  303. package/docs/api/player.playbackrate.gettitle.md +0 -15
  304. package/docs/api/player.playbackrate.goback.md +0 -15
  305. package/docs/api/player.playbackrate.highlightcurrentrate.md +0 -15
  306. package/docs/api/player.playbackrate.name.md +0 -11
  307. package/docs/api/player.playbackrate.onfinishad.md +0 -15
  308. package/docs/api/player.playbackrate.onplay.md +0 -15
  309. package/docs/api/player.playbackrate.onrateselect.md +0 -49
  310. package/docs/api/player.playbackrate.onshowmenu.md +0 -15
  311. package/docs/api/player.playbackrate.onstartad.md +0 -15
  312. package/docs/api/player.playbackrate.onstop.md +0 -15
  313. package/docs/api/player.playbackrate.reload.md +0 -15
  314. package/docs/api/player.playbackrate.render.md +0 -15
  315. package/docs/api/player.playbackrate.supportedversion.md +0 -13
  316. package/docs/api/player.playbackrate.template.md +0 -11
  317. package/docs/api/player.playbackrate.unbindevents.md +0 -15
  318. package/docs/api/player.playbackrate.updateplaybackrate.md +0 -49
  319. package/docs/api/player.pluginsettings.md +0 -13
  320. package/docs/api/player.statistics._constructor_.md +0 -47
  321. package/docs/api/player.statistics.bindevents.md +0 -15
  322. package/docs/api/player.statistics.md +0 -141
  323. package/docs/api/player.statistics.name.md +0 -11
  324. package/docs/api/player.statistics.supportedversion.md +0 -13
  325. package/docs/api/player.thumbnails.attributes.md +0 -13
  326. package/docs/api/player.thumbnails.bindevents.md +0 -15
  327. package/docs/api/player.thumbnails.name.md +0 -11
  328. package/docs/api/player.thumbnails.settext.md +0 -49
  329. package/docs/api/player.thumbnails.supportedversion.md +0 -13
  330. package/docs/api/player.thumbnails.template.md +0 -11
  331. package/docs/api/player.volumefade.bindevents.md +0 -18
  332. package/docs/api/player.volumefade.name.md +0 -14
  333. package/docs/api/player.volumefade.unbindevents.md +0 -18
  334. package/src/plugins/disable-controls/DisableControls.ts +0 -81
  335. package/src/plugins/ga-events/GaEvents.js +0 -395
  336. package/src/plugins/ga-events/ga-tracking.js +0 -46
  337. package/src/plugins/statistics/Statistics.ts +0 -207
  338. /package/src/plugins/{statistics → telemetry}/Statistics copy.xts +0 -0
package/dist/index.js CHANGED
@@ -12459,7 +12459,7 @@ var PlaybackErrorCode;
12459
12459
  // license that can be found in the LICENSE file.
12460
12460
  const AUTO$2 = -1;
12461
12461
  const { now: now$2 } = Utils;
12462
- const T$e = 'playback.dash';
12462
+ const T$f = 'playback.dash';
12463
12463
  // @ts-expect-error
12464
12464
  class DashPlayback extends HTML5Video {
12465
12465
  _levels = null;
@@ -12729,10 +12729,10 @@ class DashPlayback extends HTML5Video {
12729
12729
  }
12730
12730
  _onPlaybackError = (event) => {
12731
12731
  // TODO
12732
- trace(`${T$e} _onPlaybackError`, { event });
12732
+ trace(`${T$f} _onPlaybackError`, { event });
12733
12733
  };
12734
12734
  _onDASHJSSError = (event) => {
12735
- trace(`${T$e} _onDASHJSSError`, { event });
12735
+ trace(`${T$f} _onDASHJSSError`, { event });
12736
12736
  this._stopTimeUpdateTimer();
12737
12737
  // Note that the other error types are deprecated
12738
12738
  const e = event.error;
@@ -12767,7 +12767,7 @@ class DashPlayback extends HTML5Video {
12767
12767
  }
12768
12768
  };
12769
12769
  triggerError(error) {
12770
- trace(`${T$e} triggerError`, { error });
12770
+ trace(`${T$f} triggerError`, { error });
12771
12771
  this.trigger(Events$1.PLAYBACK_ERROR, {
12772
12772
  ...error,
12773
12773
  origin: this.name,
@@ -12807,7 +12807,7 @@ class DashPlayback extends HTML5Video {
12807
12807
  }
12808
12808
  get dvrEnabled() {
12809
12809
  if (!this._dash) {
12810
- trace(`${T$e} dvrEnable no dash player instance`);
12810
+ trace(`${T$f} dvrEnable no dash player instance`);
12811
12811
  return false;
12812
12812
  }
12813
12813
  return (this._dash?.getDVRWindowSize() >= this._minDvrSize &&
@@ -12829,7 +12829,7 @@ class DashPlayback extends HTML5Video {
12829
12829
  this.trigger(Events$1.PLAYBACK_PROGRESS, progress, {});
12830
12830
  }
12831
12831
  play() {
12832
- trace(`${T$e} play`, { dash: !!this._dash });
12832
+ trace(`${T$f} play`, { dash: !!this._dash });
12833
12833
  if (!this._dash) {
12834
12834
  this._setup();
12835
12835
  }
@@ -41576,7 +41576,7 @@ const AUTO$1 = -1;
41576
41576
  const DEFAULT_RECOVER_ATTEMPTS = 16;
41577
41577
  Events$1.register('PLAYBACK_FRAGMENT_CHANGED');
41578
41578
  Events$1.register('PLAYBACK_FRAGMENT_PARSING_METADATA');
41579
- const T$d = 'playback.hls';
41579
+ const T$e = 'playback.hls';
41580
41580
  // @ts-expect-error
41581
41581
  class HlsPlayback extends HTML5Video {
41582
41582
  _ccIsSetup = false;
@@ -41806,7 +41806,7 @@ class HlsPlayback extends HTML5Video {
41806
41806
  maxBufferLength: 2,
41807
41807
  maxMaxBufferLength: 4,
41808
41808
  }, this.options.playback.hlsjsConfig);
41809
- trace(`${T$d} _createHLSInstance`, { config });
41809
+ trace(`${T$e} _createHLSInstance`, { config });
41810
41810
  this._hls = new Hls(config);
41811
41811
  }
41812
41812
  _attachHLSMedia() {
@@ -41895,7 +41895,7 @@ class HlsPlayback extends HTML5Video {
41895
41895
  }
41896
41896
  else {
41897
41897
  Log.error('hlsjs: failed to recover', { evt, data });
41898
- trace(`${T$d} _recover failed to recover`, {
41898
+ trace(`${T$e} _recover failed to recover`, {
41899
41899
  type: data.type,
41900
41900
  details: data.details,
41901
41901
  });
@@ -41981,7 +41981,7 @@ class HlsPlayback extends HTML5Video {
41981
41981
  this.trigger(Events$1.PLAYBACK_SETTINGSUPDATE);
41982
41982
  }
41983
41983
  _onHLSJSError(evt, data) {
41984
- trace(`${T$d} _onHLSJSError`, {
41984
+ trace(`${T$e} _onHLSJSError`, {
41985
41985
  fatal: data.fatal,
41986
41986
  type: data.type,
41987
41987
  details: data.details,
@@ -42029,7 +42029,7 @@ class HlsPlayback extends HTML5Video {
42029
42029
  evt,
42030
42030
  data,
42031
42031
  });
42032
- trace(`${T$d} _onHLSJSError trying to recover from network error`, {
42032
+ trace(`${T$e} _onHLSJSError trying to recover from network error`, {
42033
42033
  details: data.details,
42034
42034
  });
42035
42035
  error.level = PlayerError.Levels.WARN;
@@ -42042,7 +42042,7 @@ class HlsPlayback extends HTML5Video {
42042
42042
  evt,
42043
42043
  data,
42044
42044
  });
42045
- trace(`${T$d} _onHLSJSError trying to recover from media error`, {
42045
+ trace(`${T$e} _onHLSJSError trying to recover from media error`, {
42046
42046
  details: data.details,
42047
42047
  });
42048
42048
  error.level = PlayerError.Levels.WARN;
@@ -42072,7 +42072,7 @@ class HlsPlayback extends HTML5Video {
42072
42072
  return;
42073
42073
  }
42074
42074
  Log.warn('hlsjs: non-fatal error occurred', { evt, data });
42075
- trace(`${T$d} _onHLSJSError non-fatal error occurred`, {
42075
+ trace(`${T$e} _onHLSJSError non-fatal error occurred`, {
42076
42076
  type: data.type,
42077
42077
  details: data.details,
42078
42078
  });
@@ -42144,9 +42144,9 @@ class HlsPlayback extends HTML5Video {
42144
42144
  }
42145
42145
  play() {
42146
42146
  !this._hls && this._setup();
42147
- assert.ok(this._hls, 'Hls.js instance is not available');
42148
42147
  !this._manifestParsed &&
42149
42148
  !this.options.hlsPlayback.preload &&
42149
+ // @ts-expect-error
42150
42150
  this._hls.loadSource(this.options.src);
42151
42151
  super.play();
42152
42152
  this._startTimeUpdateTimer();
@@ -42400,7 +42400,7 @@ function registerPlaybacks() {
42400
42400
  Loader.registerPlayback(DashPlayback);
42401
42401
  }
42402
42402
 
42403
- const T$c = 'GPlayer';
42403
+ const T$d = 'GPlayer';
42404
42404
  const DEFAULT_OPTIONS = {
42405
42405
  autoPlay: false,
42406
42406
  debug: 'none',
@@ -42495,7 +42495,7 @@ class Player {
42495
42495
  }
42496
42496
  const coreOpts = this.buildCoreOptions(playerElement);
42497
42497
  const { core, container } = Loader.registeredPlugins;
42498
- trace(`${T$c} init`, {
42498
+ trace(`${T$d} init`, {
42499
42499
  registeredPlaybacks: Loader.registeredPlaybacks.map((p) => p.name),
42500
42500
  });
42501
42501
  coreOpts.plugins = {
@@ -42509,7 +42509,7 @@ class Player {
42509
42509
  * Destroys the player, releasing all resources and unmounting its UI from the DOM.
42510
42510
  */
42511
42511
  destroy() {
42512
- trace(`${T$c} destroy`, {
42512
+ trace(`${T$d} destroy`, {
42513
42513
  player: !!this.player,
42514
42514
  });
42515
42515
  if (this.player) {
@@ -42669,7 +42669,7 @@ class Player {
42669
42669
  this.config = $.extend(true, this.config, config);
42670
42670
  }
42671
42671
  initPlayer(coreOptions) {
42672
- trace(`${T$c} initPlayer`, {
42672
+ trace(`${T$d} initPlayer`, {
42673
42673
  autoPlay: coreOptions.autoPlay,
42674
42674
  sources: coreOptions.sources,
42675
42675
  // TODO selected options
@@ -42694,7 +42694,7 @@ class Player {
42694
42694
  }
42695
42695
  }
42696
42696
  triggerAutoPlay() {
42697
- trace(`${T$c} triggerAutoPlay`);
42697
+ trace(`${T$d} triggerAutoPlay`);
42698
42698
  setTimeout(() => {
42699
42699
  this.player?.play({
42700
42700
  autoPlay: true,
@@ -42712,7 +42712,7 @@ class Player {
42712
42712
  // TODO test
42713
42713
  events = {
42714
42714
  onReady: () => {
42715
- trace(`${T$c} onReady`, {
42715
+ trace(`${T$d} onReady`, {
42716
42716
  ready: this.ready,
42717
42717
  });
42718
42718
  if (this.ready) {
@@ -42746,7 +42746,7 @@ class Player {
42746
42746
  buildCoreOptions(rootNode) {
42747
42747
  const sources = this.buildMediaSourcesList();
42748
42748
  const source = sources[0];
42749
- trace(`${T$c} buildCoreOptions`, {
42749
+ trace(`${T$d} buildCoreOptions`, {
42750
42750
  source,
42751
42751
  sources,
42752
42752
  });
@@ -42805,7 +42805,7 @@ class Player {
42805
42805
  bindCoreListeners() {
42806
42806
  const core = this.player?.core;
42807
42807
  core?.on(Events$1.CORE_SCREEN_ORIENTATION_CHANGED, ({ orientation }) => {
42808
- trace(`${T$c} on CORE_SCREEN_ORIENTATION_CHANGED`, {
42808
+ trace(`${T$d} on CORE_SCREEN_ORIENTATION_CHANGED`, {
42809
42809
  orientation,
42810
42810
  rootNode: {
42811
42811
  width: this.rootNode?.clientWidth,
@@ -42820,14 +42820,14 @@ class Player {
42820
42820
  }
42821
42821
  }, null);
42822
42822
  core?.on(Events$1.CORE_RESIZE, ({ width, height }) => {
42823
- trace(`${T$c} on CORE_RESIZE`, {
42823
+ trace(`${T$d} on CORE_RESIZE`, {
42824
42824
  width,
42825
42825
  height,
42826
42826
  });
42827
42827
  this.safeTriggerEvent(PlayerEvent.Resize, { width, height });
42828
42828
  }, null);
42829
42829
  core?.on(Events$1.CORE_FULLSCREEN, (isFullscreen) => {
42830
- trace(`${T$c} CORE_FULLSCREEN`, {
42830
+ trace(`${T$d} CORE_FULLSCREEN`, {
42831
42831
  isFullscreen,
42832
42832
  });
42833
42833
  this.safeTriggerEvent(PlayerEvent.Fullscreen, isFullscreen);
@@ -42835,7 +42835,7 @@ class Player {
42835
42835
  }
42836
42836
  }
42837
42837
 
42838
- var version$1 = "2.19.15";
42838
+ var version$1 = "2.20.3";
42839
42839
 
42840
42840
  var packages = {
42841
42841
  "node_modules/@clappr/core": {
@@ -42867,38 +42867,57 @@ const VERSION$6 = '0.0.1';
42867
42867
  // const T = 'plugins.audio_selector';
42868
42868
  const AUTO = 0;
42869
42869
  /**
42870
+ * Adds an audio track selector to the media control UI.
42870
42871
  * @beta
42871
42872
  */
42872
42873
  class AudioSelector extends UICorePlugin {
42874
+ // TODO
42873
42875
  selectedTrackId;
42874
42876
  currentTrack = null;
42875
42877
  tracks = [];
42878
+ /**
42879
+ * @internal
42880
+ */
42876
42881
  get name() {
42877
- return 'media_control_audio_selector';
42882
+ return 'audio_selector';
42878
42883
  }
42884
+ /**
42885
+ * @internal
42886
+ */
42879
42887
  get supportedVersion() {
42880
42888
  return { min: CLAPPR_VERSION };
42881
42889
  }
42890
+ /**
42891
+ * @internal
42892
+ */
42882
42893
  static get version() {
42883
42894
  return VERSION$6;
42884
42895
  }
42885
- get template() {
42886
- return tmpl(pluginHtml$8);
42887
- }
42896
+ static template = tmpl(pluginHtml$8);
42897
+ /**
42898
+ * @internal
42899
+ */
42888
42900
  get attributes() {
42889
42901
  return {
42890
- 'class': this.name,
42891
- 'data-track-selector': ''
42902
+ class: this.name,
42903
+ 'data-track-selector': '',
42892
42904
  };
42893
42905
  }
42906
+ /**
42907
+ * @internal
42908
+ */
42894
42909
  get events() {
42895
42910
  return {
42896
42911
  'click [data-track-selector-select]': 'onTrackSelect',
42897
- 'click [data-track-selector-button]': 'onShowLevelSelectMenu'
42912
+ 'click [data-track-selector-button]': 'onShowLevelSelectMenu',
42898
42913
  };
42899
42914
  }
42915
+ /**
42916
+ * @internal
42917
+ */
42900
42918
  bindEvents() {
42901
42919
  this.listenTo(this.core, Events$1.CORE_READY, this.bindPlaybackEvents);
42920
+ // TODO CORE_ACTIVE_CONTAINER_CHANGED
42902
42921
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
42903
42922
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
42904
42923
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_HIDE, this.hideSelectTrackMenu);
@@ -42939,12 +42958,12 @@ class AudioSelector extends UICorePlugin {
42939
42958
  if (defaultTrack) {
42940
42959
  this.currentTrack = {
42941
42960
  id: defaultTrack.id,
42942
- label: defaultTrack.name
42961
+ label: defaultTrack.name,
42943
42962
  };
42944
42963
  }
42945
- this.fillTracks(data.audioTracks.map(p => ({
42964
+ this.fillTracks(data.audioTracks.map((p) => ({
42946
42965
  id: p.id,
42947
- label: p.name
42966
+ label: p.name,
42948
42967
  })), defaultTrack?.id);
42949
42968
  });
42950
42969
  currentPlayback._hls.on(Events.AUDIO_TRACK_SWITCHING, this.startTrackSwitch.bind(this));
@@ -42990,23 +43009,30 @@ class AudioSelector extends UICorePlugin {
42990
43009
  if (!currentPlayback) {
42991
43010
  return false;
42992
43011
  }
42993
- const { audioTracks } = (currentPlayback.activePlayback._hls || currentPlayback.$el.get(0));
43012
+ const { audioTracks } = currentPlayback.activePlayback._hls || currentPlayback.$el.get(0);
42994
43013
  this.tracks = audioTracks;
42995
43014
  // Only care if we have at least 2 to choose from
42996
43015
  return this.tracks && this.tracks.length > 1;
42997
43016
  }
43017
+ /**
43018
+ * @internal
43019
+ */
42998
43020
  render() {
42999
- if (this.shouldRender()) {
43000
- this.$el.html(this.template({ 'tracks': this.tracks, 'title': this.getTitle() }));
43001
- if (Object.prototype.hasOwnProperty.call(this.core.mediaControl, '$audioTracksSelector') &&
43002
- this.core.mediaControl.$audioTracksSelector.length > 0) {
43003
- this.core.mediaControl.$audioTracksSelector.append(this.el);
43004
- }
43005
- this.highlightCurrentTrack();
43021
+ if (!this.shouldRender()) {
43022
+ return this;
43023
+ }
43024
+ const mediaControl = this.core.getPlugin('media_control');
43025
+ assert(mediaControl, 'media_control plugin is required');
43026
+ this.$el.html(AudioSelector.template({ tracks: this.tracks, title: this.getTitle() }));
43027
+ const ats = mediaControl.getElement('audioTracksSelector');
43028
+ if (!(ats && ats.length > 0)) {
43029
+ return this;
43006
43030
  }
43007
- if (Object.prototype.hasOwnProperty.call(this.core.mediaControl, '$audioTracksSelector') &&
43008
- this.core.mediaControl.$audioTracksSelector.find('span.audio-arrow').length > 0) {
43009
- this.core.mediaControl.$audioTracksSelector.find('span.audio-arrow').append(audioArrow);
43031
+ ats.append(this.el);
43032
+ this.highlightCurrentTrack();
43033
+ const aa = ats.find('audioArrow');
43034
+ if (aa.length > 0) {
43035
+ aa.append(audioArrow);
43010
43036
  }
43011
43037
  return this;
43012
43038
  }
@@ -43070,7 +43096,8 @@ class AudioSelector extends UICorePlugin {
43070
43096
  return this.$('.audio_selector button .audio-text');
43071
43097
  }
43072
43098
  trackElement(id) {
43073
- return this.$('.audio_selector ul a' + (id !== undefined ? '[data-track-selector-select="' + id + '"]' : '')).parent();
43099
+ return this.$('.audio_selector ul a' +
43100
+ (id !== undefined ? '[data-track-selector-select="' + id + '"]' : '')).parent();
43074
43101
  }
43075
43102
  getTitle() {
43076
43103
  if (!this.tracks) {
@@ -43141,8 +43168,11 @@ const volumeOffIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
43141
43168
 
43142
43169
  const pluginHtml$7 = "<div class=\"big-mute-icon-wrapper\" data-big-mute>\n <div class=\"big-mute-icon gcore-skin-border-color\" data-big-mute-icon></div>\n</div>\n";
43143
43170
 
43144
- const T$b = "plugins.big_mute_button";
43171
+ const T$c = 'plugins.big_mute_button';
43172
+ // TODO rewrite as a container plugin
43145
43173
  /**
43174
+ * Displays a big mute button over the video when it's muted.
43175
+ * Once pressed, it unmutes the video.
43146
43176
  * @beta
43147
43177
  */
43148
43178
  class BigMuteButton extends UICorePlugin {
@@ -43150,42 +43180,41 @@ class BigMuteButton extends UICorePlugin {
43150
43180
  _adIsPlaying = false;
43151
43181
  $bigMuteBtnContainer = null;
43152
43182
  $bigMuteButton = null;
43183
+ /**
43184
+ * @internal
43185
+ */
43153
43186
  get name() {
43154
43187
  return 'big_mute_button';
43155
43188
  }
43189
+ /**
43190
+ * @internal
43191
+ */
43156
43192
  get supportedVersion() {
43157
43193
  return { min: CLAPPR_VERSION };
43158
43194
  }
43159
- get template() {
43160
- return tmpl(pluginHtml$7);
43161
- }
43195
+ static template = tmpl(pluginHtml$7);
43196
+ /**
43197
+ * @internal
43198
+ */
43162
43199
  get events() {
43163
43200
  return {
43164
43201
  'click .big-mute-icon': 'handleBigMuteBtnClick',
43165
43202
  'click .big-mute-icon-wrapper': 'destroyBigMuteBtn',
43166
43203
  };
43167
43204
  }
43205
+ /**
43206
+ * @internal
43207
+ */
43168
43208
  bindEvents() {
43169
43209
  super.bindEvents();
43170
43210
  this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
43171
43211
  this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
43172
43212
  this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
43173
- trace(`${T$b} bindEvents`, {
43213
+ trace(`${T$c} bindEvents`, {
43174
43214
  mediacontrol: !!this.core.mediaControl,
43175
43215
  });
43176
43216
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
43177
43217
  }
43178
- unBindEvents() {
43179
- // @ts-ignore
43180
- this.stopListening(this.core, Events$1.CORE_READY);
43181
- this.stopListening(this.core, 'core:advertisement:start', this.onStartAd);
43182
- this.stopListening(this.core, 'core:advertisement:finish', this.onFinishAd);
43183
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
43184
- const container = this.core.activeContainer;
43185
- if (container) {
43186
- this.stopListening(container.playback, Events$1.PLAYBACK_PLAY, this.render);
43187
- }
43188
- }
43189
43218
  onCoreReady() {
43190
43219
  this.listenTo(this.core.activeContainer, Events$1.CONTAINER_VOLUME, this.onContainerVolume);
43191
43220
  this.listenTo(this.core.activeContainer, Events$1.CONTAINER_READY, this.onContainerStart);
@@ -43206,12 +43235,12 @@ class BigMuteButton extends UICorePlugin {
43206
43235
  }
43207
43236
  mediaControlRendered() {
43208
43237
  const container = this.core.activeContainer;
43209
- trace(`${T$b} mediaControlRendered`, {
43238
+ trace(`${T$c} mediaControlRendered`, {
43210
43239
  container: !!container,
43211
43240
  });
43212
43241
  if (container) {
43213
43242
  this.listenTo(container.playback, Events$1.PLAYBACK_PLAY, () => {
43214
- trace(`${T$b} PLAYBACK_PLAY`);
43243
+ trace(`${T$c} PLAYBACK_PLAY`);
43215
43244
  this.render();
43216
43245
  });
43217
43246
  }
@@ -43235,19 +43264,22 @@ class BigMuteButton extends UICorePlugin {
43235
43264
  }
43236
43265
  const { autoPlay, wasMuted } = this.options;
43237
43266
  const volume = container.volume;
43238
- trace(`${T$b} shouldRender`, {
43267
+ trace(`${T$c} shouldRender`, {
43239
43268
  autoPlay,
43240
43269
  wasMuted,
43241
43270
  volume,
43242
43271
  });
43243
43272
  return autoPlay && !wasMuted && volume === 0;
43244
43273
  }
43274
+ /**
43275
+ * @internal
43276
+ */
43245
43277
  render() {
43246
43278
  if (this.shouldRender()) {
43247
- trace(`${T$b} render`, {
43279
+ trace(`${T$c} render`, {
43248
43280
  el: !!this.$el,
43249
43281
  });
43250
- this.$el.html(this.template());
43282
+ this.$el.html(BigMuteButton.template());
43251
43283
  this.$bigMuteBtnContainer = this.$el.find('.big-mute-icon-wrapper[data-big-mute]');
43252
43284
  this._adIsPlaying && this.$bigMuteBtnContainer.addClass('hide');
43253
43285
  this.$bigMuteButton = this.$bigMuteBtnContainer.find('.big-mute-icon');
@@ -43290,9 +43322,10 @@ const gearIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"n
43290
43322
  const gearHdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_28_1567)\">\n <path\n d=\"M19.14 12.94C19.18 12.64 19.2 12.33 19.2 12C19.2 11.68 19.18 11.36 19.13 11.06L21.16 9.47999C21.34 9.33999 21.39 9.06999 21.28 8.86999L19.36 5.54999C19.24 5.32999 18.99 5.25999 18.77 5.32999L16.38 6.28999C15.88 5.90999 15.35 5.58999 14.76 5.34999L14.4 2.80999C14.36 2.56999 14.16 2.39999 13.92 2.39999H10.08C9.83999 2.39999 9.64999 2.56999 9.60999 2.80999L9.24999 5.34999C8.65999 5.58999 8.11999 5.91999 7.62999 6.28999L5.23999 5.32999C5.01999 5.24999 4.76999 5.32999 4.64999 5.54999L2.73999 8.86999C2.61999 9.07999 2.65999 9.33999 2.85999 9.47999L4.88999 11.06C4.83999 11.36 4.79999 11.69 4.79999 12C4.79999 12.31 4.81999 12.64 4.86999 12.94L2.83999 14.52C2.65999 14.66 2.60999 14.93 2.71999 15.13L4.63999 18.45C4.75999 18.67 5.00999 18.74 5.22999 18.67L7.61999 17.71C8.11999 18.09 8.64999 18.41 9.23999 18.65L9.59999 21.19C9.64999 21.43 9.83999 21.6 10.08 21.6H13.92C14.16 21.6 14.36 21.43 14.39 21.19L14.75 18.65C15.34 18.41 15.88 18.09 16.37 17.71L18.76 18.67C18.98 18.75 19.23 18.67 19.35 18.45L21.27 15.13C21.39 14.91 21.34 14.66 21.15 14.52L19.14 12.94ZM12 15.6C10.02 15.6 8.39999 13.98 8.39999 12C8.39999 10.02 10.02 8.39999 12 8.39999C13.98 8.39999 15.6 10.02 15.6 12C15.6 13.98 13.98 15.6 12 15.6Z\"\n fill=\"#C9C9C9\"/>\n <rect x=\"13\" width=\"11\" height=\"7\" rx=\"1\" fill=\"#F6413B\"/>\n <path\n d=\"M14.6962 6V1.63636H15.3546V3.53267H17.53V1.63636H18.1905V6H17.53V4.0973H15.3546V6H14.6962ZM20.562 6H19.1493V1.63636H20.6067C21.0343 1.63636 21.4015 1.72372 21.7083 1.89844C22.0151 2.07173 22.2502 2.32102 22.4135 2.64631C22.5783 2.97017 22.6607 3.35866 22.6607 3.81179C22.6607 4.26634 22.5776 4.65696 22.4114 4.98366C22.2466 5.31037 22.008 5.56179 21.6955 5.73793C21.383 5.91264 21.0051 6 20.562 6ZM19.8077 5.42472H20.5257C20.8581 5.42472 21.1344 5.36222 21.3546 5.23722C21.5748 5.1108 21.7395 4.92827 21.8489 4.68963C21.9583 4.44957 22.013 4.15696 22.013 3.81179C22.013 3.46946 21.9583 3.17898 21.8489 2.94034C21.7409 2.7017 21.5797 2.5206 21.3652 2.39702C21.1507 2.27344 20.8844 2.21165 20.5662 2.21165H19.8077V5.42472Z\"\n fill=\"#C9C9C9\"/>\n </g>\n <defs>\n <clipPath id=\"clip0_28_1567\">\n <rect width=\"24\" height=\"24\" fill=\"white\"/>\n </clipPath>\n </defs>\n</svg>\n";
43291
43323
 
43292
43324
  const VERSION$5 = '2.19.12';
43293
- const T$a = 'plugins.bottom_gear';
43325
+ const T$b = 'plugins.bottom_gear';
43294
43326
  /**
43295
43327
  * Custom events emitted by the plugin
43328
+ * @beta
43296
43329
  */
43297
43330
  var GearEvents;
43298
43331
  (function (GearEvents) {
@@ -43375,11 +43408,11 @@ class BottomGear extends UICorePlugin {
43375
43408
  this.$el.find('.gear-wrapper').html(content);
43376
43409
  }
43377
43410
  onActiveContainerChanged() {
43378
- trace(`${T$a} onActiveContainerChanged`);
43411
+ trace(`${T$b} onActiveContainerChanged`);
43379
43412
  this.bindContainerEvents();
43380
43413
  }
43381
43414
  bindContainerEvents() {
43382
- trace(`${T$a} bindContainerEvents`);
43415
+ trace(`${T$b} bindContainerEvents`);
43383
43416
  this.listenTo(this.core.activeContainer, Events$1.CONTAINER_HIGHDEFINITIONUPDATE, this.highDefinitionUpdate);
43384
43417
  }
43385
43418
  highDefinitionUpdate(isHd) {
@@ -44490,6 +44523,9 @@ function requireMousetrap () {
44490
44523
  var mousetrapExports = requireMousetrap();
44491
44524
  const Mousetrap = /*@__PURE__*/getDefaultExportFromCjs$1(mousetrapExports);
44492
44525
 
44526
+ /**
44527
+ * @beta
44528
+ */
44493
44529
  var ClapprStatsEvents;
44494
44530
  (function (ClapprStatsEvents) {
44495
44531
  ClapprStatsEvents["REPORT_EVENT"] = "clappr:stats:report";
@@ -45499,7 +45535,7 @@ const qualityClasses = [
45499
45535
  'speedtest-quality-value-2',
45500
45536
  'speedtest-quality-value-3',
45501
45537
  'speedtest-quality-value-4',
45502
- 'speedtest-quality-value-5'
45538
+ 'speedtest-quality-value-5',
45503
45539
  ];
45504
45540
  const getDownloadQuality = (speedValue) => {
45505
45541
  if (speedValue < 3) {
@@ -45563,7 +45599,22 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
45563
45599
  };
45564
45600
  // const T = 'plugins.clappr_nerd_stats';
45565
45601
  /**
45602
+ * Displays useful network-related statistics.
45566
45603
  * @beta
45604
+ *
45605
+ * @remarks
45606
+ * Depends on:
45607
+ *
45608
+ * - {@link MediaControl}
45609
+ *
45610
+ * - {@link BottomGear}
45611
+ *
45612
+ * - {@link ClapprStats}
45613
+ *
45614
+ * The plugin is rendered as an item in the gear menu.
45615
+ *
45616
+ * When clicked, it shows an overlay window with the information about the network speed, latency, etc,
45617
+ * and recommended quality level.
45567
45618
  */
45568
45619
  class ClapprNerdStats extends UICorePlugin {
45569
45620
  container = null;
@@ -45576,21 +45627,31 @@ class ClapprNerdStats extends UICorePlugin {
45576
45627
  showing = false;
45577
45628
  shortcut;
45578
45629
  iconPosition;
45630
+ /**
45631
+ * @internal
45632
+ */
45579
45633
  get name() {
45580
45634
  return 'nerd_stats';
45581
45635
  }
45636
+ /**
45637
+ * @internal
45638
+ */
45582
45639
  get supportedVersion() {
45583
45640
  return { min: CLAPPR_VERSION };
45584
45641
  }
45585
- get template() {
45586
- return tmpl(pluginHtml$5);
45587
- }
45642
+ static template = tmpl(pluginHtml$5);
45643
+ /**
45644
+ * @internal
45645
+ */
45588
45646
  get attributes() {
45589
45647
  return {
45590
45648
  'data-clappr-nerd-stats': '',
45591
- 'class': 'clappr-nerd-stats'
45649
+ class: 'clappr-nerd-stats',
45592
45650
  };
45593
45651
  }
45652
+ /**
45653
+ * @internal
45654
+ */
45594
45655
  get events() {
45595
45656
  return {
45596
45657
  'click [data-show-stats-button]': 'showOrHide',
@@ -45612,8 +45673,12 @@ class ClapprNerdStats extends UICorePlugin {
45612
45673
  }
45613
45674
  constructor(core) {
45614
45675
  super(core);
45615
- this.shortcut = core.options.clapprNerdStats?.shortcut ?? ['command+shift+s', 'ctrl+shift+s'];
45616
- this.iconPosition = core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
45676
+ this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
45677
+ 'command+shift+s',
45678
+ 'ctrl+shift+s',
45679
+ ];
45680
+ this.iconPosition =
45681
+ core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
45617
45682
  this.customMetrics = {
45618
45683
  connectionSpeed: 0,
45619
45684
  ping: 0,
@@ -45621,6 +45686,9 @@ class ClapprNerdStats extends UICorePlugin {
45621
45686
  };
45622
45687
  configureSpeedTest(core.options.clapprNerdStats?.speedTestServers ?? []);
45623
45688
  }
45689
+ /**
45690
+ * @internal
45691
+ */
45624
45692
  bindEvents() {
45625
45693
  const mediaControl = this.core.getPlugin('media_control');
45626
45694
  assert(mediaControl, 'media_control plugin is required');
@@ -45660,9 +45728,11 @@ class ClapprNerdStats extends UICorePlugin {
45660
45728
  this.core.$el.find(this.statsBoxElem).show();
45661
45729
  this.showing = true;
45662
45730
  this.refreshSpeedTest();
45663
- initSpeedTest(this.customMetrics).then(() => {
45731
+ initSpeedTest(this.customMetrics)
45732
+ .then(() => {
45664
45733
  startSpeedtest();
45665
- }).catch(e => {
45734
+ })
45735
+ .catch((e) => {
45666
45736
  reportError(e);
45667
45737
  this.disable();
45668
45738
  });
@@ -45677,13 +45747,19 @@ class ClapprNerdStats extends UICorePlugin {
45677
45747
  }
45678
45748
  addGeneralMetrics() {
45679
45749
  this.metrics.general = {
45680
- displayResolution: (this.playerWidth + 'x' + this.playerHeight),
45681
- volume: this.container?.volume
45750
+ displayResolution: this.playerWidth + 'x' + this.playerHeight,
45751
+ volume: this.container?.volume,
45682
45752
  };
45683
45753
  }
45684
45754
  addCustomMetrics() {
45685
45755
  this.metrics.custom = this.customMetrics;
45686
- const videoQualityNames = ['SD (480p)', 'HD (720p)', 'Full HD (1080p)', '2K (1440p)', '4K (2160p)'];
45756
+ const videoQualityNames = [
45757
+ 'SD (480p)',
45758
+ 'HD (720p)',
45759
+ 'Full HD (1080p)',
45760
+ '2K (1440p)',
45761
+ '4K (2160p)',
45762
+ ];
45687
45763
  const { connectionSpeed, ping } = this.customMetrics;
45688
45764
  if (!connectionSpeed || !ping) {
45689
45765
  const calculatingText = 'Calculating... Please wait.';
@@ -45695,17 +45771,19 @@ class ClapprNerdStats extends UICorePlugin {
45695
45771
  const pingQuality = getPingQuality(ping);
45696
45772
  const liveQuality = Math.min(downloadQuality, pingQuality);
45697
45773
  const prefix = 'Optimal for ';
45698
- this.metrics.custom.vodQuality = prefix + videoQualityNames[downloadQuality - 1];
45699
- this.metrics.custom.liveQuality = prefix + videoQualityNames[liveQuality - 1];
45774
+ this.metrics.custom.vodQuality =
45775
+ prefix + videoQualityNames[downloadQuality - 1];
45776
+ this.metrics.custom.liveQuality =
45777
+ prefix + videoQualityNames[liveQuality - 1];
45700
45778
  }
45701
45779
  updateMetrics(metrics) {
45702
45780
  Object.assign(this.metrics, metrics);
45703
45781
  this.addGeneralMetrics();
45704
45782
  this.addCustomMetrics();
45705
45783
  const scrollTop = this.core.$el.find(this.statsBoxElem).scrollTop();
45706
- this.$el.html(this.template({
45784
+ this.$el.html(ClapprNerdStats.template({
45707
45785
  metrics: Formatter.format(this.metrics),
45708
- iconPosition: this.iconPosition
45786
+ iconPosition: this.iconPosition,
45709
45787
  }));
45710
45788
  this.setStatsBoxSize();
45711
45789
  drawSpeedTestResults();
@@ -45725,7 +45803,11 @@ class ClapprNerdStats extends UICorePlugin {
45725
45803
  this.$el.find(this.statsBoxElem).addClass('narrow');
45726
45804
  }
45727
45805
  }
45806
+ /**
45807
+ * @internal
45808
+ */
45728
45809
  render() {
45810
+ // TODO append to the container
45729
45811
  this.core.$el.append(this.$el[0]);
45730
45812
  this.hide();
45731
45813
  return this;
@@ -45777,7 +45859,10 @@ function newMetrics() {
45777
45859
  // TODO: fix
45778
45860
  const updateMetrics = () => { };
45779
45861
  /**
45862
+ * Collects useful statistics about playback performance.
45780
45863
  * @beta
45864
+ * @remarks
45865
+ * This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
45781
45866
  */
45782
45867
  class ClapprStats extends ContainerPlugin {
45783
45868
  bwMeasureCount = 0;
@@ -45799,9 +45884,15 @@ class ClapprStats extends ContainerPlugin {
45799
45884
  updateFn = updateMetrics;
45800
45885
  urisToMeasureBandwidth;
45801
45886
  uriToMeasureLatency;
45887
+ /**
45888
+ * @internal
45889
+ */
45802
45890
  get name() {
45803
45891
  return 'clappr_stats';
45804
45892
  }
45893
+ /**
45894
+ * @internal
45895
+ */
45805
45896
  get supportedVersion() {
45806
45897
  return { min: CLAPPR_VERSION };
45807
45898
  }
@@ -45829,6 +45920,10 @@ class ClapprStats extends ContainerPlugin {
45829
45920
  // this._metrics.timers[timer] += this._now() - this[`_start${timer}`];
45830
45921
  this.metrics.timers[timer] += this._now() - this.timers[timer];
45831
45922
  }
45923
+ /**
45924
+ * Registers a callback to receive the metrics.
45925
+ * @param updateMetricsFn
45926
+ */
45832
45927
  setUpdateMetrics(updateMetricsFn) {
45833
45928
  this.updateFn = updateMetricsFn;
45834
45929
  }
@@ -45847,6 +45942,9 @@ class ClapprStats extends ContainerPlugin {
45847
45942
  calls: []
45848
45943
  };
45849
45944
  }
45945
+ /**
45946
+ * @internal
45947
+ */
45850
45948
  bindEvents() {
45851
45949
  this.listenTo(this.container, Events$1.CONTAINER_BITRATE, this.onBitrate);
45852
45950
  this.listenTo(this.container, Events$1.CONTAINER_STOP, this.stopReporting);
@@ -45865,10 +45963,17 @@ class ClapprStats extends ContainerPlugin {
45865
45963
  this.listenTo(this.container.playback, Events$1.PLAYBACK_PROGRESS, this.onProgress);
45866
45964
  this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
45867
45965
  }
45966
+ /**
45967
+ * @internal
45968
+ */
45868
45969
  destroy() {
45869
45970
  this.stopReporting();
45870
45971
  super.destroy();
45871
45972
  }
45973
+ /**
45974
+ * Returns the collected metrics.
45975
+ * @returns The collected metrics
45976
+ */
45872
45977
  exportMetrics() {
45873
45978
  return structuredClone(this.metrics);
45874
45979
  }
@@ -45890,6 +45995,7 @@ class ClapprStats extends ContainerPlugin {
45890
45995
  this.intervalId = null;
45891
45996
  }
45892
45997
  this._newMetrics();
45998
+ // TODO
45893
45999
  // @ts-ignore
45894
46000
  this.stopListening();
45895
46001
  this.bindEvents();
@@ -46107,20 +46213,30 @@ class ClapprStats extends ContainerPlugin {
46107
46213
 
46108
46214
  //Copyright 2014 Globo.com Player authors. All rights reserved.
46109
46215
  // Use of this source code is governed by a BSD-style
46110
- // license that can be found in the LICENSE file.
46111
- const T$9 = 'plugins.click_to_pause_custom';
46216
+ // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE.
46217
+ const T$a = 'plugins.click_to_pause_custom';
46218
+ /**
46219
+ * Adds a behavior of toggling the playback state on click over the container
46220
+ * @beta
46221
+ */
46112
46222
  class ClickToPause extends ContainerPlugin {
46113
46223
  pointerEnabled = false;
46114
46224
  timer = null;
46225
+ /**
46226
+ * @internal
46227
+ */
46115
46228
  get name() {
46116
46229
  return 'click_to_pause_custom';
46117
46230
  }
46231
+ /**
46232
+ * @internal
46233
+ */
46118
46234
  get supportedVersion() {
46119
46235
  return { min: CLAPPR_VERSION };
46120
46236
  }
46121
- get config() {
46122
- return this.container.options.clickToPauseConfig || {};
46123
- }
46237
+ /**
46238
+ * @internal
46239
+ */
46124
46240
  bindEvents() {
46125
46241
  this.listenTo(this.container, Events$1.CONTAINER_CLICK, this.click);
46126
46242
  this.listenTo(this.container, Events$1.CONTAINER_SETTINGSUPDATE, this.settingsUpdate);
@@ -46128,7 +46244,7 @@ class ClickToPause extends ContainerPlugin {
46128
46244
  click() {
46129
46245
  const isLivePlayback = this.container.getPlaybackType() === Playback.LIVE;
46130
46246
  const isDvrEnabled = this.container.isDvrEnabled();
46131
- trace(`${T$9} click`, {
46247
+ trace(`${T$a} click`, {
46132
46248
  isLivePlayback,
46133
46249
  isDvrEnabled,
46134
46250
  });
@@ -46146,7 +46262,7 @@ class ClickToPause extends ContainerPlugin {
46146
46262
  settingsUpdate() {
46147
46263
  const isLivePlayback = this.container.getPlaybackType() === Playback.LIVE;
46148
46264
  const pointerEnabled = !isLivePlayback || this.container.isDvrEnabled();
46149
- trace(`${T$9} settingsUpdate`, {
46265
+ trace(`${T$a} settingsUpdate`, {
46150
46266
  isLivePlayback,
46151
46267
  pointerEnabled,
46152
46268
  });
@@ -46236,23 +46352,45 @@ function getPageX(event) {
46236
46352
  return 0;
46237
46353
  }
46238
46354
 
46355
+ /**
46356
+ * Adds a behavior of showing a text over the seekbar to indicate the current clip.
46357
+ * @beta
46358
+ * @remarks
46359
+ * Depends on:
46360
+ *
46361
+ * - {@link MediaControl}
46362
+ *
46363
+ * Configuration options - {@link ClipsPluginSettings}
46364
+ */
46239
46365
  class ClipsPlugin extends UICorePlugin {
46240
46366
  clips = new Map();
46241
46367
  duration = 0;
46242
46368
  durationGetting = false;
46243
46369
  _oldContainer;
46244
46370
  svgMask = null;
46371
+ /**
46372
+ * @internal
46373
+ */
46245
46374
  get name() {
46246
- return 'media_control_clips';
46375
+ return 'clips';
46247
46376
  }
46377
+ /**
46378
+ * @internal
46379
+ */
46248
46380
  get attributes() {
46249
46381
  return {
46250
- 'class': this.name
46382
+ class: this.name,
46251
46383
  };
46252
46384
  }
46385
+ /**
46386
+ * @internal
46387
+ */
46253
46388
  bindEvents() {
46389
+ const mediaControl = this.core.getPlugin('media_control');
46390
+ assert(mediaControl, 'media_control plugin is required');
46254
46391
  this.listenToOnce(this.core, Events$1.CORE_READY, this._onCoreReady);
46255
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this._onMediaControlContainerChanged);
46392
+ // TODO listen to CORE_ACTIVE_CONTAINER_CHANGED
46393
+ this.listenTo(mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this._onMediaControlContainerChanged);
46256
46394
  this.listenTo(this.core, Events$1.CORE_RESIZE, this.playerResize);
46257
46395
  }
46258
46396
  _onCoreReady() {
@@ -46262,12 +46400,6 @@ class ClipsPlugin extends UICorePlugin {
46262
46400
  }
46263
46401
  this.parseClips();
46264
46402
  }
46265
- unbindEvents() {
46266
- // @ts-ignore
46267
- this.stopListening(this.core, Events$1.CORE_READY);
46268
- // @ts-ignore
46269
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED);
46270
- }
46271
46403
  _onMediaControlContainerChanged() {
46272
46404
  this._bindContainerEvents();
46273
46405
  }
@@ -46281,9 +46413,10 @@ class ClipsPlugin extends UICorePlugin {
46281
46413
  if (this._oldContainer) {
46282
46414
  this.stopListening(this._oldContainer, Events$1.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
46283
46415
  }
46284
- this._oldContainer = this.core.mediaControl.container;
46416
+ const mediaControl = this.core.getPlugin('media_control');
46417
+ this._oldContainer = mediaControl.container;
46285
46418
  this.durationGetting = false;
46286
- this.listenTo(this.core.mediaControl.container, Events$1.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
46419
+ this.listenTo(mediaControl.container, Events$1.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
46287
46420
  }
46288
46421
  onTimeUpdate(event) {
46289
46422
  if (!this.durationGetting) {
@@ -46300,13 +46433,17 @@ class ClipsPlugin extends UICorePlugin {
46300
46433
  }
46301
46434
  parseClips() {
46302
46435
  const textArr = this.options.clips.text.split('\n');
46303
- const clipsArr = textArr.map((val) => {
46436
+ const clipsArr = textArr
46437
+ .map((val) => {
46304
46438
  const matchRes = val.match(/(\d+:\d+|:\d+) (.+)/i);
46305
- return matchRes ? {
46306
- start: strtimeToMiliseconds(matchRes[1]),
46307
- text: matchRes[2],
46308
- } : null;
46309
- }).filter((clip) => clip !== null);
46439
+ return matchRes
46440
+ ? {
46441
+ start: strtimeToMiliseconds(matchRes[1]),
46442
+ text: matchRes[2],
46443
+ }
46444
+ : null;
46445
+ })
46446
+ .filter((clip) => clip !== null);
46310
46447
  clipsArr.sort((a, b) => a.start - b.start);
46311
46448
  clipsArr.forEach((clip, index) => {
46312
46449
  this.clips.set(clip.start, {
@@ -46317,6 +46454,11 @@ class ClipsPlugin extends UICorePlugin {
46317
46454
  });
46318
46455
  });
46319
46456
  }
46457
+ /**
46458
+ * Returns the text of the current clip.
46459
+ * @param time - The current time of the player.
46460
+ * @returns The text of the current clip.
46461
+ */
46320
46462
  getText(time) {
46321
46463
  for (const [key, value] of this.clips.entries()) {
46322
46464
  if (time >= value.start && time < value.end) {
@@ -46327,14 +46469,14 @@ class ClipsPlugin extends UICorePlugin {
46327
46469
  }
46328
46470
  makeSvg(duration) {
46329
46471
  let svg = '<svg width="0" height="0">\n' + '<defs>\n' + '<clipPath id="myClip">\n';
46330
- const widthOfSeek = this.core.mediaControl.container.$el.width();
46472
+ const widthOfSeek = this.core.activeContainer.$el.width();
46331
46473
  let finishValue = 0;
46332
- this.clips.forEach(val => {
46474
+ this.clips.forEach((val) => {
46333
46475
  let end = val.end;
46334
46476
  if (!end) {
46335
46477
  end = val.end = duration;
46336
46478
  }
46337
- const widthChunk = (end - val.start) * widthOfSeek / duration;
46479
+ const widthChunk = ((end - val.start) * widthOfSeek) / duration;
46338
46480
  svg += `<rect x="${finishValue}" y="0" width="${widthChunk - 2}" height="30"/>\n`;
46339
46481
  finishValue += widthChunk;
46340
46482
  });
@@ -46347,7 +46489,8 @@ class ClipsPlugin extends UICorePlugin {
46347
46489
  if (this.svgMask) {
46348
46490
  this.svgMask.remove();
46349
46491
  }
46350
- const $seekBarContainer = this.core.mediaControl.getElement('seekBarContainer');
46492
+ const mediaControl = this.core.getPlugin('media_control');
46493
+ const $seekBarContainer = mediaControl.getElement('seekBarContainer');
46351
46494
  if ($seekBarContainer?.get(0)) {
46352
46495
  $seekBarContainer.addClass('clips');
46353
46496
  }
@@ -46355,7 +46498,8 @@ class ClipsPlugin extends UICorePlugin {
46355
46498
  $seekBarContainer?.append(this.svgMask);
46356
46499
  }
46357
46500
  setClipText(text) {
46358
- const $clipText = this.core.mediaControl.getElement('clipText');
46501
+ const mediaControl = this.core.getPlugin('media_control');
46502
+ const $clipText = mediaControl.getElement('clipText');
46359
46503
  if ($clipText && text) {
46360
46504
  $clipText.show();
46361
46505
  $clipText.text(`${text}`);
@@ -46365,28 +46509,37 @@ class ClipsPlugin extends UICorePlugin {
46365
46509
 
46366
46510
  const templateHtml$1 = "<ul class=\"context-menu-list\">\n <% if(options) { %>\n <% for (var i = 0; i < options.length; i++) { %>\n <li class=\"context-menu-list-item <%= options[i].class %>\"\n data-<%= options[i].name %>><%= options[i].label %></li>\n <% } %>\n <% } %>\n</ul>\n";
46367
46511
 
46368
- class ContextMenu extends UICorePlugin {
46512
+ /**
46513
+ * Displays a small context menu when clicked on the player container.
46514
+ * @beta
46515
+ * @remarks
46516
+ * Configuration options - {@link ContextMenuPluginSettings}
46517
+ */
46518
+ class ContextMenu extends UIContainerPlugin {
46369
46519
  _label = '';
46370
46520
  _url = '';
46371
- container = null;
46372
46521
  menuOptions = [];
46522
+ /**
46523
+ * @internal
46524
+ */
46373
46525
  get name() {
46374
46526
  return 'context_menu';
46375
46527
  }
46528
+ /**
46529
+ * @internal
46530
+ */
46376
46531
  get supportedVersion() {
46377
46532
  return { min: CLAPPR_VERSION };
46378
46533
  }
46534
+ /**
46535
+ * @internal
46536
+ */
46379
46537
  get attributes() {
46380
- return { 'class': 'context-menu' };
46381
- }
46382
- get mediaControl() {
46383
- return this.core.mediaControl;
46384
- }
46385
- get template() {
46386
- return tmpl(templateHtml$1);
46538
+ return { class: 'context-menu' };
46387
46539
  }
46540
+ static template = tmpl(templateHtml$1);
46388
46541
  get label() {
46389
- return this._label || 'Gcore player ver. ' + process.env.VERSION;
46542
+ return this._label || 'Gcore player ver. ' + version().gplayer;
46390
46543
  }
46391
46544
  get url() {
46392
46545
  return this._url || 'https://gcore.com/';
@@ -46394,16 +46547,19 @@ class ContextMenu extends UICorePlugin {
46394
46547
  get exposeVersion() {
46395
46548
  return {
46396
46549
  label: this.label,
46397
- name: 'version'
46550
+ name: 'version',
46398
46551
  };
46399
46552
  }
46553
+ /**
46554
+ * @internal
46555
+ */
46400
46556
  get events() {
46401
46557
  return {
46402
- 'click [data-version]': 'onOpenMainPage'
46558
+ 'click [data-version]': 'onOpenMainPage',
46403
46559
  };
46404
46560
  }
46405
- constructor(core) {
46406
- super(core);
46561
+ constructor(container) {
46562
+ super(container);
46407
46563
  if (this.options.contextMenu && this.options.contextMenu.label) {
46408
46564
  this._label = this.options.contextMenu.label;
46409
46565
  }
@@ -46413,28 +46569,21 @@ class ContextMenu extends UICorePlugin {
46413
46569
  this.render();
46414
46570
  this.bindEvents();
46415
46571
  }
46572
+ /**
46573
+ * @internal
46574
+ */
46416
46575
  bindEvents() {
46417
- if (this.mediaControl) {
46418
- this.listenTo(this.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.containerChanged);
46419
- if (this.container) {
46420
- this.listenTo(this.container, Events$1.CONTAINER_CONTEXTMENU, this.toggleContextMenu);
46421
- this.listenTo(this.container, Events$1.CONTAINER_CLICK, this.hide);
46422
- }
46423
- }
46424
- $('body').on('click', this.hide.bind(this));
46576
+ this.listenTo(this.container, Events$1.CONTAINER_CONTEXTMENU, this.toggleContextMenu);
46577
+ this.listenTo(this.container, Events$1.CONTAINER_CLICK, this.hide);
46578
+ $('body').on('click', this.hideOnBodyClick);
46425
46579
  }
46580
+ /**
46581
+ * @internal
46582
+ */
46426
46583
  destroy() {
46427
- $('body').off('click', this.hide.bind(this));
46428
- // @ts-ignore
46429
- this.stopListening();
46584
+ $('body').off('click', this.hideOnBodyClick);
46430
46585
  return super.destroy();
46431
46586
  }
46432
- containerChanged() {
46433
- this.container = this.core.activeContainer;
46434
- // @ts-ignore
46435
- this.stopListening();
46436
- this.bindEvents();
46437
- }
46438
46587
  toggleContextMenu(event) {
46439
46588
  event.preventDefault();
46440
46589
  const offset = this.container?.$el.offset();
@@ -46442,7 +46591,8 @@ class ContextMenu extends UICorePlugin {
46442
46591
  }
46443
46592
  show(top, left) {
46444
46593
  this.hide();
46445
- if (this.options.contextMenu && this.options.contextMenu.preventShowContextMenu) {
46594
+ if (this.options.contextMenu &&
46595
+ this.options.contextMenu.preventShowContextMenu) {
46446
46596
  return;
46447
46597
  }
46448
46598
  this.$el.css({ top, left });
@@ -46454,80 +46604,19 @@ class ContextMenu extends UICorePlugin {
46454
46604
  onOpenMainPage() {
46455
46605
  window.open(this.url, '_blank');
46456
46606
  }
46607
+ /**
46608
+ * @internal
46609
+ */
46457
46610
  render() {
46458
46611
  this.menuOptions = [this.exposeVersion];
46459
- this.$el.html(this.template({ options: this.menuOptions }));
46460
- this.core.$el.append(this.$el);
46612
+ this.$el.html(ContextMenu.template({ options: this.menuOptions }));
46613
+ this.container.$el.append(this.$el); // TODO append to the container, turn into a container plugin
46461
46614
  this.hide();
46462
- this.disable();
46463
46615
  return this;
46464
46616
  }
46465
- }
46466
-
46467
- class DisableControls extends UICorePlugin {
46468
- get name() {
46469
- return 'disable_controls';
46470
- }
46471
- get container() {
46472
- return this.core && this.core.activeContainer;
46473
- }
46474
- get supportedVersion() {
46475
- return { min: CLAPPR_VERSION };
46476
- }
46477
- bindEvents() {
46478
- if (this.container) {
46479
- this.listenTo(this.container, Events$1.CONTAINER_MEDIACONTROL_ENABLE, this.enableControls);
46480
- this.listenTo(this.container, Events$1.CONTAINER_PLAY, this.enableControls);
46481
- this.listenTo(this.container, Events$1.CONTAINER_PAUSE, this.enableControls);
46482
- this.listenTo(this.container, Events$1.CONTAINER_STOP, this.enableControls);
46483
- this.listenTo(this.container, Events$1.CONTAINER_ENDED, this.enableControls);
46484
- this.listenTo(this.container, 'container:advertisement:start', this.enableControls);
46485
- }
46486
- this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
46487
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_SHOW, this.enableControls);
46488
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.enableControls);
46489
- }
46490
- unbindEvents() {
46491
- // @ts-ignore
46492
- this.stopListening(this.core, Events$1.CORE_READY);
46493
- // @ts-ignore
46494
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_SHOW);
46495
- // @ts-ignore
46496
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED);
46497
- // @ts-ignore
46498
- this.stopListening(this.container, Events$1.CONTAINER_MEDIACONTROL_ENABLE);
46499
- // @ts-ignore
46500
- this.stopListening(this.container, Events$1.CONTAINER_PLAY);
46501
- // @ts-ignore
46502
- this.stopListening(this.container, Events$1.CONTAINER_PAUSE);
46503
- // @ts-ignore
46504
- this.stopListening(this.container, Events$1.CONTAINER_STOP);
46505
- // @ts-ignore
46506
- this.stopListening(this.container, Events$1.CONTAINER_ENDED);
46507
- // @ts-ignore
46508
- this.stopListening(this.container, 'container:advertisement:start');
46509
- }
46510
- setDisableStyles() {
46511
- const css = document.createElement('style');
46512
- const styles = '.control-need-disable { display: none!important; }';
46513
- css.appendChild(document.createTextNode(styles));
46514
- this.core.$el.get(0).appendChild(css);
46515
- }
46516
- onCoreReady() {
46517
- this.setDisableStyles();
46518
- this.bindEvents();
46519
- this.enableControls();
46520
- }
46521
- enableControls() {
46522
- this.disableAllControls();
46523
- }
46524
- disableAllControls() {
46525
- setTimeout(() => {
46526
- const spinnerPlugin = this.container.getPlugin('spinner');
46527
- spinnerPlugin?.destroy();
46528
- this.container.disableMediaControl();
46529
- }, 0);
46530
- }
46617
+ hideOnBodyClick = () => {
46618
+ this.hide();
46619
+ };
46531
46620
  }
46532
46621
 
46533
46622
  const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"button\" class=\"live-button\" aria-label=\"<%= backToLive %>\"><%= backToLive %></button>\n";
@@ -46537,8 +46626,11 @@ const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"butt
46537
46626
  * @beta
46538
46627
  *
46539
46628
  * @remarks
46540
- * The plugin is rendered in the {@link MediaControl | media control} UI.
46541
- * It renders the live stream indicator and the DVR seek bar if DVR is enabled.
46629
+ * Depends on:
46630
+ *
46631
+ * - {@link MediaControl}
46632
+ *
46633
+ * The plugin renders the live stream indicator and the DVR seek bar, if DVR is enabled, in the media control UI.
46542
46634
  */
46543
46635
  class DvrControls extends UICorePlugin {
46544
46636
  static template = tmpl(dvrHTML);
@@ -46546,7 +46638,7 @@ class DvrControls extends UICorePlugin {
46546
46638
  * @internal
46547
46639
  */
46548
46640
  get name() {
46549
- return 'media_control_dvr';
46641
+ return 'dvr_controls';
46550
46642
  }
46551
46643
  /**
46552
46644
  * @internal
@@ -46579,32 +46671,15 @@ class DvrControls extends UICorePlugin {
46579
46671
  * @internal
46580
46672
  */
46581
46673
  bindEvents() {
46582
- this.bindCoreEvents();
46583
- this.bindContainerEvents();
46584
- if (this.core.activeContainer) {
46585
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
46586
- }
46587
- }
46588
- bindCoreEvents() {
46589
- if (this.core.mediaControl.settings) {
46590
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.containerChanged);
46591
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.settingsUpdate);
46592
- this.listenTo(this.core, Events$1.CORE_OPTIONS_CHANGE, this.render);
46593
- }
46594
- else {
46595
- setTimeout(() => this.bindCoreEvents(), 100);
46596
- }
46674
+ const mediaControl = this.core.getPlugin('media_control');
46675
+ assert(mediaControl, 'media_control plugin is required');
46676
+ this.listenTo(mediaControl, Events$1.MEDIACONTROL_RENDERED, this.settingsUpdate);
46677
+ this.listenTo(this.core, Events$1.CORE_OPTIONS_CHANGE, this.render);
46678
+ this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.bindContainerEvents);
46597
46679
  }
46598
46680
  bindContainerEvents() {
46599
- if (this.core.activeContainer) {
46600
- this.listenToOnce(this.core.activeContainer, Events$1.CONTAINER_TIMEUPDATE, this.render);
46601
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
46602
- }
46603
- }
46604
- containerChanged() {
46605
- // @ts-ignore
46606
- this.stopListening();
46607
- this.bindEvents();
46681
+ this.listenToOnce(this.core.activeContainer, Events$1.CONTAINER_TIMEUPDATE, this.render);
46682
+ this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
46608
46683
  }
46609
46684
  dvrChanged(dvrEnabled) {
46610
46685
  if (this.core.getPlaybackType() !== Playback.LIVE) {
@@ -46637,7 +46712,7 @@ class DvrControls extends UICorePlugin {
46637
46712
  settingsUpdate() {
46638
46713
  // @ts-ignore
46639
46714
  this.stopListening(); // TODO sort out
46640
- this.core.mediaControl.$el.removeClass('live');
46715
+ this.core.getPlugin('media_control').$el.removeClass('live'); // TODO don't access directly
46641
46716
  if (this.shouldRender()) {
46642
46717
  this.render();
46643
46718
  this.$el.click(() => this.click());
@@ -46657,7 +46732,7 @@ class DvrControls extends UICorePlugin {
46657
46732
  backToLive: this.core.i18n.t('back_to_live')
46658
46733
  }));
46659
46734
  if (this.shouldRender()) {
46660
- const mediaControl = this.core.mediaControl;
46735
+ const mediaControl = this.core.getPlugin('media_control');
46661
46736
  assert(mediaControl, 'media_control plugin is required');
46662
46737
  // TODO don't tap into the $el directly
46663
46738
  mediaControl.$el.addClass('live');
@@ -46673,7 +46748,11 @@ const templateHtml = "<div class=\"player-error-screen__content\" data-error-scr
46673
46748
 
46674
46749
  const TIME_FOR_UPDATE = 10000;
46675
46750
  const MAX_RETRY = 10;
46676
- const T$8 = 'plugins.error_screen';
46751
+ const T$9 = 'plugins.error_screen';
46752
+ /**
46753
+ * Displays a descriptive error in the overlay on top of the player.
46754
+ * @beta
46755
+ */
46677
46756
  class ErrorScreen extends UICorePlugin {
46678
46757
  _retry = 0;
46679
46758
  err = null;
@@ -46706,17 +46785,17 @@ class ErrorScreen extends UICorePlugin {
46706
46785
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.onContainerChanged);
46707
46786
  }
46708
46787
  onCoreReady() {
46709
- trace(`${T$8} onCoreReady`);
46788
+ trace(`${T$9} onCoreReady`);
46710
46789
  if (this.core.activePlayback) {
46711
46790
  this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_PLAY, this.onPlay);
46712
46791
  }
46713
46792
  }
46714
46793
  onPlay() {
46715
- trace(`${T$8} onPlay`);
46794
+ trace(`${T$9} onPlay`);
46716
46795
  this.destroyError();
46717
46796
  }
46718
46797
  destroyError() {
46719
- trace(`${T$8} destroyError`);
46798
+ trace(`${T$9} destroyError`);
46720
46799
  this._retry = 0;
46721
46800
  this.err = null;
46722
46801
  if (this.timeout !== null) {
@@ -46772,7 +46851,7 @@ class ErrorScreen extends UICorePlugin {
46772
46851
  }
46773
46852
  }
46774
46853
  onError(err) {
46775
- trace(`${T$8} onError`, { err });
46854
+ trace(`${T$9} onError`, { err });
46776
46855
  if (err.level === PlayerError.Levels.FATAL ||
46777
46856
  err.details === 'bufferStalledError' ||
46778
46857
  err.details === 'manifestParsingError') {
@@ -46855,6 +46934,10 @@ const stopIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\
46855
46934
  const FAVICON_COLOR = '#567';
46856
46935
  const FAVICON_SELECTOR = 'link[rel="shortcut icon"]';
46857
46936
  // const oldIcon = $(FAVICON_SELECTOR);
46937
+ /**
46938
+ * The plugin adds custom favicon to the player's tab.
46939
+ * @beta
46940
+ */
46858
46941
  class Favicon extends CorePlugin {
46859
46942
  _container = null;
46860
46943
  oldIcon;
@@ -46956,7 +47039,11 @@ class Favicon extends CorePlugin {
46956
47039
 
46957
47040
  // Copyright 2014 Globo.com Player authors. All rights reserved.
46958
47041
  // Use of this source code is governed by a BSD-style
46959
- // license that can be found in the LICENSE file.
47042
+ // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE
47043
+ /**
47044
+ * An example Google Analytics integration plugin
47045
+ * @beta
47046
+ */
46960
47047
  class GoogleAnalytics extends ContainerPlugin {
46961
47048
  account = '';
46962
47049
  trackerName = '';
@@ -47267,7 +47354,7 @@ function keyName(keyCode) {
47267
47354
 
47268
47355
  const buttonHtml$2 = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option'>\n <% if (isHd) { %>\n <span class=\"gear-option_hd-icon\"><%= hdIcon %></span>\n <% } %>\n <span>Quality</span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= currentText %></span>\n</button>\n";
47269
47356
 
47270
- const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Quality\n</button>\n<ul class=\"gear-sub-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n Auto\n </a>\n </li>\n <% } %>\n <% for (const level of levels.slice().reverse()) { %>\n <li <% if (maxLevel >= 0 && level.level > maxLevel) { %>class=\"level-disabled\"<% } %>>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"<%= level.level %>\" id=\"level_selector_<%= level.level %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[level.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
47357
+ const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Quality\n</button>\n<ul class=\"gear-sub-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n Auto\n </a>\n </li>\n <% } %>\n <% for (const level of levels.slice().reverse()) { %>\n <li <% if (maxLevel >= 0 && level.level > maxLevel) { %>class=\"level-disabled\"<% } %>>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"<%= level.level %>\" id=\"level_selector_<%= level.height %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[level.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
47271
47358
 
47272
47359
  const hdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.9562 8.22232H13.9961V15.1873H14.9562C15.8914 15.1873 16.766 14.8253 17.4195 14.1676C18.0786 13.5037 18.4415 12.6281 18.4415 11.7026C18.4415 9.7837 16.8781 8.22253 14.9561 8.22253L14.9562 8.22232Z\"\n fill=\"#C9C9C9\"/>\n <path\n d=\"M22.0801 4H1.91994C0.859222 4 0 4.86406 0 5.91994V17.4878C0 18.5437 0.859222 19.4078 1.91994 19.4078H22.0801C23.1408 19.4078 24 18.5437 24 17.4878V5.91994C24 4.86406 23.1408 4 22.0801 4ZM10.3975 15.3473C10.3975 15.6124 10.1827 15.8272 9.91754 15.8272C9.65216 15.8272 9.43761 15.6122 9.43761 15.3473V12.0239H5.55956V15.3473C5.55956 15.6124 5.34481 15.8272 5.07963 15.8272C4.81425 15.8272 4.5997 15.6122 4.5997 15.3473L4.59949 7.74042C4.59949 7.47524 4.81425 7.26049 5.07943 7.26049C5.34481 7.26049 5.55936 7.47544 5.55936 7.74042V11.0636H9.43741V7.74042C9.43741 7.47524 9.65216 7.26049 9.91734 7.26049C10.1827 7.26049 10.3973 7.47544 10.3973 7.74042L10.3975 15.3473ZM18.1005 14.8438C17.2652 15.6844 16.1486 16.1472 14.9561 16.1472H13.5161C13.2507 16.1472 13.0361 15.9323 13.0361 15.6673V7.74263C13.0361 7.47745 13.2509 7.26269 13.5161 7.26269H14.9561C17.4072 7.26269 19.4013 9.25438 19.4013 11.7027C19.4013 12.8835 18.9392 13.9991 18.1005 14.844V14.8438Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
47273
47360
 
@@ -47277,7 +47364,7 @@ const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
47277
47364
 
47278
47365
  const checkIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M20.5793 4.19296C20.1216 3.86696 19.4777 3.96396 19.1424 4.40896L9.37295 17.3809L4.81634 12.107C4.45222 11.683 3.80218 11.6289 3.36709 11.9839C2.932 12.3389 2.87543 12.97 3.2416 13.393L8.64165 19.643C8.83708 19.869 9.12506 20 9.42849 20C9.4398 20 9.45114 20 9.46246 19.999C9.77926 19.989 10.0724 19.838 10.2586 19.59L20.8015 5.58996C21.1368 5.14496 21.0371 4.51896 20.5793 4.19296Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
47279
47366
 
47280
- const T$7 = 'plugins.level_selector';
47367
+ const T$8 = 'plugins.level_selector';
47281
47368
  const VERSION$4 = '2.19.4';
47282
47369
  /**
47283
47370
  * A {@link MediaControl | media control} plugin that provides a UI to control the quality level of the playback.
@@ -47379,10 +47466,10 @@ class LevelSelector extends UICorePlugin {
47379
47466
  }
47380
47467
  }
47381
47468
  onStop() {
47382
- trace(`${T$7} onStop`);
47469
+ trace(`${T$8} onStop`);
47383
47470
  const currentPlayback = this.core.activePlayback;
47384
47471
  this.listenToOnce(currentPlayback, Events$1.PLAYBACK_PLAY, () => {
47385
- trace(`${T$7} on PLAYBACK_PLAY after stop`, { selectedLevelId: this.selectedLevelId });
47472
+ trace(`${T$8} on PLAYBACK_PLAY after stop`, { selectedLevelId: this.selectedLevelId });
47386
47473
  if (currentPlayback.getPlaybackType() === 'live') {
47387
47474
  if (this.selectedLevelId !== -1) {
47388
47475
  currentPlayback.currentLevel = this.selectedLevelId;
@@ -47478,13 +47565,13 @@ class LevelSelector extends UICorePlugin {
47478
47565
  return false;
47479
47566
  }
47480
47567
  goBack() {
47481
- trace(`${T$7} goBack`);
47568
+ trace(`${T$8} goBack`);
47482
47569
  this.isOpen = false;
47483
47570
  this.core.trigger('gear:refresh');
47484
47571
  this.deferRender();
47485
47572
  }
47486
47573
  setLevel(index) {
47487
- trace(`${T$7} setIndexLevel`, { index });
47574
+ trace(`${T$8} setIndexLevel`, { index });
47488
47575
  this.selectedLevelId = index;
47489
47576
  if (!this.core.activePlayback) {
47490
47577
  return;
@@ -47502,7 +47589,7 @@ class LevelSelector extends UICorePlugin {
47502
47589
  this.deferRender();
47503
47590
  }
47504
47591
  onShowLevelSelectMenu() {
47505
- trace(`${T$7} onShowLevelSelectMenu`);
47592
+ trace(`${T$8} onShowLevelSelectMenu`);
47506
47593
  this.isOpen = true;
47507
47594
  this.renderDropdown();
47508
47595
  this.highlightCurrentLevel();
@@ -47538,11 +47625,11 @@ class LevelSelector extends UICorePlugin {
47538
47625
  return this.levelLabels[index] ?? formatLevelLabel(this.levels[index]);
47539
47626
  }
47540
47627
  updateCurrentLevel(info) {
47541
- trace(`${T$7} updateCurrentLevel`, { info });
47628
+ trace(`${T$8} updateCurrentLevel`, { info });
47542
47629
  this.highlightCurrentLevel();
47543
47630
  }
47544
47631
  highlightCurrentLevel() {
47545
- trace(`${T$7} highlightCurrentLevel`, {
47632
+ trace(`${T$8} highlightCurrentLevel`, {
47546
47633
  selectedLevelId: this.selectedLevelId,
47547
47634
  });
47548
47635
  this.allLevelElements().removeClass('current');
@@ -47606,6 +47693,10 @@ function calculateSize(original) {
47606
47693
 
47607
47694
  const logoHTML = "<div class=\"clappr-logo control-need-disable\">\n <img class=\"clappr-logo-img\"/>\n</div>\n";
47608
47695
 
47696
+ /**
47697
+ * The plugin adds custom logo to the player.
47698
+ * @beta
47699
+ */
47609
47700
  class Logo extends UIContainerPlugin {
47610
47701
  hasStartedPlaying = false;
47611
47702
  $logoContainer = null;
@@ -47883,7 +47974,7 @@ class MediaControl extends UICorePlugin {
47883
47974
  return { min: CLAPPR_VERSION };
47884
47975
  }
47885
47976
  get disabled() {
47886
- const playbackIsNOOP = this.container && this.container.getPlaybackType() === Playback.NO_OP;
47977
+ const playbackIsNOOP = this.core.activeContainer && this.core.activeContainer.getPlaybackType() === Playback.NO_OP;
47887
47978
  return this.userDisabled || playbackIsNOOP;
47888
47979
  }
47889
47980
  /**
@@ -48564,6 +48655,8 @@ class MediaControl extends UICorePlugin {
48564
48655
  */
48565
48656
  getElement(name) {
48566
48657
  switch (name) {
48658
+ case 'audioTracksSelector':
48659
+ return this.$audioTracksSelector;
48567
48660
  case 'clipText':
48568
48661
  return this.$clipText;
48569
48662
  case 'bottomGear':
@@ -48868,7 +48961,10 @@ const streamsMomentoIcon = "<svg id=\"Слой_1\" data-name=\"Слой 1\" xmln
48868
48961
  const streamsWhiteNightsIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"50\" height=\"50\" viewBox=\"0 0 50 50\">\n <defs>\n <clipPath id=\"clip-Icon\">\n <rect width=\"50\" height=\"50\"/>\n </clipPath>\n </defs>\n <g id=\"Icon\" clip-path=\"url(#clip-Icon)\">\n <g id=\"icon2\" transform=\"translate(-0.041 0)\">\n <path id=\"Контур_77\" data-name=\"Контур 77\" d=\"M6.493,13v8.266h6.275V19.74H8.31V17.714h4.006V16.3H8.31V14.53h4.365V13Zm7.5,0v8.266h1.7V15.732h.023l3.438,5.534h1.818V13h-1.7v5.545h-.023L15.8,13Z\" fill=\"#fff\"/>\n <path id=\"Контур_76\" data-name=\"Контур 76\" d=\"M29.949,29.1V26.774H31.94a1.4,1.4,0,0,1,.938.272,1.1,1.1,0,0,1,.313.874,1.155,1.155,0,0,1-.313.9,1.375,1.375,0,0,1-.938.278ZM28.132,25.36v8.266h1.817V30.4h1.818a1.353,1.353,0,0,1,.984.3,1.637,1.637,0,0,1,.394.949c.046.333.079.681.1,1.042a3.2,3.2,0,0,0,.185.938h1.819a1.218,1.218,0,0,1-.191-.423,3.611,3.611,0,0,1-.093-.527c-.019-.185-.033-.367-.041-.544s-.016-.332-.023-.463a5.052,5.052,0,0,0-.087-.625,2.109,2.109,0,0,0-.2-.573,1.586,1.586,0,0,0-.359-.451,1.414,1.414,0,0,0-.556-.284v-.023a1.926,1.926,0,0,0,1-.81,2.494,2.494,0,0,0,.307-1.262,2.308,2.308,0,0,0-.165-.88,2.128,2.128,0,0,0-.486-.724,2.3,2.3,0,0,0-.764-.492,2.67,2.67,0,0,0-1-.179ZM43.506,30.5V25.36H41.689V30.5a2.065,2.065,0,0,1-.37,1.36,1.7,1.7,0,0,1-1.343.434,2.086,2.086,0,0,1-.886-.156,1.283,1.283,0,0,1-.758-.978,3.748,3.748,0,0,1-.058-.66V25.36H36.456V30.5a3.16,3.16,0,0,0,.92,2.5,3.807,3.807,0,0,0,2.6.81,3.82,3.82,0,0,0,2.593-.816,3.132,3.132,0,0,0,.937-2.492Z\" fill=\"#fff\"/>\n <path id=\"Контур_80\" data-name=\"Контур 80\" d=\"M22.646,31.2H4.689a4.505,4.505,0,0,1-4.5-4.5V8.5A4.505,4.505,0,0,1,4.689,4h18.2a4.505,4.505,0,0,1,4.5,4.5v8.445l-.893.1a3.184,3.184,0,0,0-2.846,3.177V30.5l-.465.7ZM4.689,6a2.5,2.5,0,0,0-2.5,2.5V26.7a2.5,2.5,0,0,0,2.5,2.5H21.65V20.22a5.18,5.18,0,0,1,3.739-4.992V8.5a2.5,2.5,0,0,0-2.5-2.5Z\" fill=\"#fff\"/>\n <path id=\"Контур_81\" data-name=\"Контур 81\" d=\"M30.127,47.884a1,1,0,0,1-1-1V43.267H26.846a5.206,5.206,0,0,1-5.2-5.2V20.222a5.206,5.206,0,0,1,5.2-5.2H44.692a5.206,5.206,0,0,1,5.2,5.2V38.068a5.206,5.206,0,0,1-5.2,5.2H35.058l-4.216,4.316A1,1,0,0,1,30.127,47.884ZM26.846,17.022a3.2,3.2,0,0,0-3.2,3.2V38.067a3.2,3.2,0,0,0,3.2,3.2h3.281a1,1,0,0,1,1,1v2.162l2.8-2.86a1,1,0,0,1,.715-.3H44.692a3.2,3.2,0,0,0,3.2-3.2V20.222a3.2,3.2,0,0,0-3.2-3.2Z\" fill=\"#fff\"/>\n </g>\n </g>\n</svg>\n";
48869
48962
 
48870
48963
  const VERSION$3 = '0.0.1';
48871
- const T$6 = 'plugins.media_control_multicamera';
48964
+ const T$7 = 'plugins.media_control_multicamera';
48965
+ /**
48966
+ * The plugin adds support for loading multiple streams and switching between them using the media control UI.
48967
+ */
48872
48968
  class MultiCamera extends UICorePlugin {
48873
48969
  currentCamera = null;
48874
48970
  currentTime = 0;
@@ -49010,7 +49106,7 @@ class MultiCamera extends UICorePlugin {
49010
49106
  }
49011
49107
  onCameraSelect(event) {
49012
49108
  const value = event.currentTarget.dataset.multicameraSelectorSelect;
49013
- trace(`${T$6} onCameraSelect`, { value });
49109
+ trace(`${T$7} onCameraSelect`, { value });
49014
49110
  if (value !== undefined) {
49015
49111
  this.changeById(parseInt(value, 10));
49016
49112
  }
@@ -49137,13 +49233,13 @@ class MultiCamera extends UICorePlugin {
49137
49233
  }
49138
49234
  }
49139
49235
  changeById(id) {
49140
- trace(`${T$6} changeById`, { id });
49236
+ trace(`${T$7} changeById`, { id });
49141
49237
  queueMicrotask(() => {
49142
49238
  const playbackOptions = this.core.options.playback || {};
49143
49239
  // TODO figure out what this does
49144
49240
  playbackOptions.recycleVideo = Browser.isMobile;
49145
49241
  this.currentCamera = this.findElementById(id) ?? null;
49146
- trace(`${T$6} changeById`, { id, currentCamera: this.currentCamera, multicamera: this.multicamera });
49242
+ trace(`${T$7} changeById`, { id, currentCamera: this.currentCamera, multicamera: this.multicamera });
49147
49243
  if (!this.currentCamera) {
49148
49244
  return;
49149
49245
  }
@@ -49160,7 +49256,7 @@ class MultiCamera extends UICorePlugin {
49160
49256
  // TODO remove?
49161
49257
  // for html5 playback:
49162
49258
  this.options.dvrEnabled = this.currentCamera.dvr;
49163
- trace(`${T$6} changeById`, { currentCamera: this.currentCamera });
49259
+ trace(`${T$7} changeById`, { currentCamera: this.currentCamera });
49164
49260
  // TODO
49165
49261
  this.core.configure({
49166
49262
  playback: playbackOptions,
@@ -49218,17 +49314,39 @@ const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"no
49218
49314
  const buttonHtml$1 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <span><%= pipIcon %></span>\n</button>\n";
49219
49315
 
49220
49316
  const VERSION$2 = '0.0.1';
49221
- const T$5 = `plugins.media_control_pip`;
49317
+ const T$6 = `plugins.pip`;
49318
+ /**
49319
+ * Enables picture in picture mode.
49320
+ * @beta
49321
+ * @remarks
49322
+ * Depends on:
49323
+ *
49324
+ * - {@link MediaControl}
49325
+ *
49326
+ * It renders a button to toggle picture in picture mode in the media control UI.
49327
+ */
49222
49328
  class PictureInPicture extends UICorePlugin {
49329
+ /**
49330
+ * @internal
49331
+ */
49223
49332
  get name() {
49224
- return 'media_control_pip';
49333
+ return 'pip';
49225
49334
  }
49335
+ /**
49336
+ * @internal
49337
+ */
49226
49338
  get supportedVersion() {
49227
49339
  return { min: CLAPPR_VERSION };
49228
49340
  }
49341
+ /**
49342
+ * @internal
49343
+ */
49229
49344
  static get version() {
49230
49345
  return VERSION$2;
49231
49346
  }
49347
+ /**
49348
+ * @internal
49349
+ */
49232
49350
  get events() {
49233
49351
  return {
49234
49352
  'click button': 'togglePictureInPicture',
@@ -49237,16 +49355,22 @@ class PictureInPicture extends UICorePlugin {
49237
49355
  get videoElement() {
49238
49356
  return this.core.activePlayback.el;
49239
49357
  }
49358
+ /**
49359
+ * @internal
49360
+ */
49240
49361
  bindEvents() {
49241
49362
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
49242
49363
  }
49243
49364
  isPiPSupported() {
49244
- trace(`${T$5} isPiPSupported`, {
49365
+ trace(`${T$6} isPiPSupported`, {
49245
49366
  pictureInPictureEnabled: document.pictureInPictureEnabled,
49246
49367
  requestPictureInPicture: HTMLVideoElement.prototype.requestPictureInPicture,
49247
49368
  });
49248
49369
  return document.pictureInPictureEnabled && !!HTMLVideoElement.prototype.requestPictureInPicture;
49249
49370
  }
49371
+ /**
49372
+ * @internal
49373
+ */
49250
49374
  render() {
49251
49375
  if (!this.isPiPSupported()) {
49252
49376
  return this;
@@ -49260,7 +49384,7 @@ class PictureInPicture extends UICorePlugin {
49260
49384
  return this;
49261
49385
  }
49262
49386
  togglePictureInPicture() {
49263
- trace(`${T$5} togglePictureInPicture`);
49387
+ trace(`${T$6} togglePictureInPicture`);
49264
49388
  if (this.videoElement !== document.pictureInPictureElement) {
49265
49389
  this.requestPictureInPicture();
49266
49390
  }
@@ -49269,13 +49393,13 @@ class PictureInPicture extends UICorePlugin {
49269
49393
  }
49270
49394
  }
49271
49395
  requestPictureInPicture() {
49272
- trace(`${T$5} requestPictureInPicture`, {
49396
+ trace(`${T$6} requestPictureInPicture`, {
49273
49397
  videoElement: !!this.videoElement,
49274
49398
  });
49275
49399
  this.videoElement.requestPictureInPicture();
49276
49400
  }
49277
49401
  exitPictureInPicture() {
49278
- trace(`${T$5} exitPictureInPicture`);
49402
+ trace(`${T$6} exitPictureInPicture`);
49279
49403
  document.exitPictureInPicture();
49280
49404
  }
49281
49405
  }
@@ -49300,26 +49424,51 @@ const DEFAULT_PLAYBACK_RATES = [
49300
49424
  const DEFAULT_PLAYBACK_RATE = '1.0';
49301
49425
  // TODO
49302
49426
  const MEDIACONTROL_PLAYBACKRATE = 'playbackRate';
49427
+ /**
49428
+ * Allows changing the playback speed of the video.
49429
+ * @beta
49430
+ *
49431
+ * @remarks
49432
+ * Depends on:
49433
+ *
49434
+ * - {@link MediaControl | media_control}
49435
+ *
49436
+ * - {@link BottomGear | bottom_gear}
49437
+ *
49438
+ * It renders a button in the gear menu, which opens a dropdown with the available playback rates.
49439
+ */
49303
49440
  class PlaybackRate extends UICorePlugin {
49304
49441
  currentPlayback = null;
49305
49442
  playbackRates = DEFAULT_PLAYBACK_RATES;
49306
49443
  prevSelectedRate;
49307
49444
  selectedRate = DEFAULT_PLAYBACK_RATE;
49445
+ /**
49446
+ * @internal
49447
+ */
49308
49448
  get name() {
49309
- return 'media_control_playback_rate';
49449
+ return 'playback_rate';
49310
49450
  }
49451
+ /**
49452
+ * @internal
49453
+ */
49311
49454
  get supportedVersion() {
49312
49455
  return { min: CLAPPR_VERSION };
49313
49456
  }
49314
- get template() {
49315
- return tmpl(pluginHtml$3);
49316
- }
49457
+ static template = tmpl(pluginHtml$3);
49458
+ static buttonTemplate = tmpl(buttonHtml);
49459
+ static listTemplate = tmpl(listHtml);
49460
+ /**
49461
+ * @internal
49462
+ */
49317
49463
  get attributes() {
49318
49464
  return {
49319
49465
  'class': this.name,
49320
49466
  'data-playback-rate-select': ''
49321
49467
  };
49322
49468
  }
49469
+ /**
49470
+ * @internal
49471
+ */
49323
49472
  get events() {
49324
49473
  return {
49325
49474
  'click .gear-sub-menu_btn': 'onRateSelect',
@@ -49327,8 +49476,12 @@ class PlaybackRate extends UICorePlugin {
49327
49476
  'click .go-back': 'goBack',
49328
49477
  };
49329
49478
  }
49479
+ /**
49480
+ * @internal
49481
+ */
49330
49482
  bindEvents() {
49331
49483
  this.listenTo(this.core, 'gear:rendered', this.render);
49484
+ // TODO this.core.getPlugin('media_control'), bottom_gear
49332
49485
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
49333
49486
  this.listenTo(this.core.mediaControl, MEDIACONTROL_PLAYBACKRATE, this.updatePlaybackRate);
49334
49487
  this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
@@ -49382,6 +49535,9 @@ class PlaybackRate extends UICorePlugin {
49382
49535
  this.currentPlayback = this.core.activePlayback;
49383
49536
  return !(this.currentPlayback?.tagName !== 'video' && this.currentPlayback?.tagName !== 'audio');
49384
49537
  }
49538
+ /**
49539
+ * @internal
49540
+ */
49385
49541
  render() {
49386
49542
  const container = this.core.activeContainer;
49387
49543
  if (this.core.getPlaybackType() === Playback.LIVE && !container.isDvrEnabled()) {
@@ -49395,9 +49551,7 @@ class PlaybackRate extends UICorePlugin {
49395
49551
  this.selectedRate = cfg.defaultValue || DEFAULT_PLAYBACK_RATE;
49396
49552
  }
49397
49553
  if (this.shouldRender()) {
49398
- const t = tmpl(buttonHtml);
49399
- // const html = t({ playbackRates: this.playbackRates, title: this.getTitle() });
49400
- const button = t({
49554
+ const button = PlaybackRate.buttonTemplate({
49401
49555
  title: this.getTitle(),
49402
49556
  speedIcon,
49403
49557
  arrowRightIcon,
@@ -49445,8 +49599,7 @@ class PlaybackRate extends UICorePlugin {
49445
49599
  return false;
49446
49600
  }
49447
49601
  onShowMenu() {
49448
- const t = tmpl(listHtml);
49449
- this.$el.html(t({
49602
+ this.$el.html(PlaybackRate.listTemplate({
49450
49603
  playbackRates: this.playbackRates,
49451
49604
  arrowLeftIcon,
49452
49605
  checkIcon,
@@ -49490,7 +49643,7 @@ const posterHTML = "<div class=\"play-wrapper\" data-poster></div>\n";
49490
49643
  //Copyright 2014 Globo.com Player authors. All rights reserved.
49491
49644
  // Use of this source code is governed by a BSD-style
49492
49645
  // license that can be found in the LICENSE file.
49493
- const T$4 = 'plugins.poster_custom';
49646
+ const T$5 = 'plugins.poster_custom';
49494
49647
  /**
49495
49648
  * Displays a poster image in the background and a big play button on top when playback is stopped
49496
49649
  * @beta
@@ -49593,13 +49746,13 @@ class Poster extends UIContainerPlugin {
49593
49746
  * Disables the plugin, unmounting it from the DOM
49594
49747
  */
49595
49748
  disable() {
49596
- trace(`${T$4} disable`);
49749
+ trace(`${T$5} disable`);
49597
49750
  this.hasStartedPlaying = false;
49598
49751
  this.playRequested = false;
49599
49752
  super.disable();
49600
49753
  }
49601
49754
  onError(error) {
49602
- trace(`${T$4} onError`, {
49755
+ trace(`${T$5} onError`, {
49603
49756
  error,
49604
49757
  enabled: this.enabled,
49605
49758
  });
@@ -49612,18 +49765,18 @@ class Poster extends UIContainerPlugin {
49612
49765
  }
49613
49766
  }
49614
49767
  onPlay() {
49615
- trace(`${T$4} onPlay`);
49768
+ trace(`${T$5} onPlay`);
49616
49769
  this.hasStartedPlaying = true;
49617
49770
  this.playRequested = false;
49618
49771
  this.update();
49619
49772
  }
49620
49773
  onPlayIntent() {
49621
- trace(`${T$4} onPlayIntent`);
49774
+ trace(`${T$5} onPlayIntent`);
49622
49775
  this.playRequested = true;
49623
49776
  this.update();
49624
49777
  }
49625
49778
  onStop() {
49626
- trace(`${T$4} onStop`, {
49779
+ trace(`${T$5} onStop`, {
49627
49780
  enabled: this.enabled,
49628
49781
  });
49629
49782
  this.hasStartedPlaying = false;
@@ -49631,7 +49784,7 @@ class Poster extends UIContainerPlugin {
49631
49784
  this.update();
49632
49785
  }
49633
49786
  updatePlayButton(show) {
49634
- trace(`${T$4} updatePlayButton`, {
49787
+ trace(`${T$5} updatePlayButton`, {
49635
49788
  show,
49636
49789
  chromeless: this.options.chromeless,
49637
49790
  allowUserInteraction: this.options.allowUserInteraction,
@@ -49660,7 +49813,7 @@ class Poster extends UIContainerPlugin {
49660
49813
  this.$el.removeClass('clickable');
49661
49814
  }
49662
49815
  clicked() {
49663
- trace(`${T$4} clicked`, {
49816
+ trace(`${T$5} clicked`, {
49664
49817
  hasStartedPlaying: this.hasStartedPlaying,
49665
49818
  chromeless: this.options.chromeless,
49666
49819
  allowUserInteraction: this.options.allowUserInteraction,
@@ -49684,7 +49837,7 @@ class Poster extends UIContainerPlugin {
49684
49837
  return !this.container.playback.isAudioOnly;
49685
49838
  }
49686
49839
  update() {
49687
- trace(`${T$4} update`, {
49840
+ trace(`${T$5} update`, {
49688
49841
  shouldRender: this.shouldRender,
49689
49842
  });
49690
49843
  if (!this.shouldRender) {
@@ -49697,7 +49850,7 @@ class Poster extends UIContainerPlugin {
49697
49850
  this.updatePoster();
49698
49851
  }
49699
49852
  updatePoster() {
49700
- trace(`${T$4} updatePoster`, {
49853
+ trace(`${T$5} updatePoster`, {
49701
49854
  hasStartedPlaying: this.hasStartedPlaying,
49702
49855
  });
49703
49856
  if (!this.hasStartedPlaying) {
@@ -49712,7 +49865,7 @@ class Poster extends UIContainerPlugin {
49712
49865
  this.$el.show();
49713
49866
  }
49714
49867
  hidePoster() {
49715
- trace(`${T$4} hidePoster`, {
49868
+ trace(`${T$5} hidePoster`, {
49716
49869
  shouldHideOnPlay: this.shouldHideOnPlay(),
49717
49870
  });
49718
49871
  if (!this.options.disableMediaControl) {
@@ -49766,8 +49919,12 @@ const seekTimeHTML = "<span data-seek-time></span>\n<span data-duration></span>\
49766
49919
 
49767
49920
  // Copyright 2014 Globo.com Player authors. All rights reserved.
49768
49921
  // Use of this source code is governed by a BSD-style
49769
- // license that can be found in the LICENSE file.
49922
+ // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE
49770
49923
  const { formatTime } = Utils;
49924
+ /**
49925
+ * The plugin adds a seek time indicator to the media control UI.
49926
+ * @beta
49927
+ */
49771
49928
  class SeekTime extends UICorePlugin {
49772
49929
  get name() {
49773
49930
  return 'media_control_seek_time';
@@ -49924,6 +50081,9 @@ const fbIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"32px\"
49924
50081
 
49925
50082
  const twIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"32px\" height=\"32px\" viewBox=\"0 0 32 32\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch -->\n <title>twitter</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"twitter\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <g fill-rule=\"nonzero\" id=\"Shape\">\n <path d=\"M32,30 C32,31.104 31.104,32 30,32 L2,32 C0.896,32 0,31.104 0,30 L0,2 C0,0.896 0.896,0 2,0 L30,0 C31.104,0 32,0.896 32,2 L32,30 Z\" fill=\"#55ACEE\"></path>\n <path class=\"icon-hover\" d=\"M25.987,9.894 C25.251,10.216 24.462,10.431 23.63,10.529 C24.48,10.031 25.13,9.24 25.436,8.298 C24.644,8.759 23.766,9.095 22.831,9.276 C22.083,8.491 21.017,8 19.838,8 C17.572,8 15.738,9.807 15.738,12.038 C15.738,12.352 15.774,12.663 15.842,12.96 C12.435,12.788 9.413,11.181 7.39,8.739 C7.038,9.336 6.834,10.029 6.834,10.771 C6.834,12.17 7.56,13.406 8.658,14.131 C7.987,14.109 7.354,13.928 6.802,13.625 C6.801,13.642 6.801,13.659 6.801,13.677 C6.801,15.632 8.215,17.266 10.091,17.637 C9.748,17.727 9.386,17.779 9.01,17.779 C8.746,17.779 8.49,17.755 8.24,17.707 C8.76,19.311 10.274,20.478 12.068,20.512 C10.67,21.594 8.9,22.24 6.979,22.24 C6.649,22.24 6.321,22.222 6,22.184 C7.814,23.329 9.971,23.997 12.287,23.997 C19.828,23.997 23.953,17.843 23.953,12.506 C23.953,12.333 23.948,12.156 23.941,11.985 C24.741,11.414 25.438,10.703 25.987,9.894 Z\" fill=\"#FFFFFF\"></path>\n </g>\n </g>\n</svg>";
49926
50083
 
50084
+ /**
50085
+ * The plugin adds a share button to the media control UI.
50086
+ */
49927
50087
  class Share extends UICorePlugin {
49928
50088
  hide = false;
49929
50089
  container = null;
@@ -50041,6 +50201,9 @@ class Share extends UICorePlugin {
50041
50201
 
50042
50202
  const pluginHtml$1 = "<div class=\"skip-container\" data-skip-container>\n <div class=\"skip-item\" data-skip-left>\n </div>\n <div class=\"skip-item\" data-skip-mid>\n </div>\n <div class=\"skip-item\" data-skip-right>\n </div>\n</div>\n";
50043
50203
 
50204
+ /**
50205
+ * The plugin adds skip controls to the media control UI.
50206
+ */
50044
50207
  class SkipTime extends UICorePlugin {
50045
50208
  get name() {
50046
50209
  return 'skip_time';
@@ -50129,7 +50292,7 @@ const spinnerHTML = "<div data-bounce1></div>\n<div data-bounce2></div>\n<div da
50129
50292
  // Copyright 2014 Globo.com Player authors. All rights reserved.
50130
50293
  // Use of this source code is governed by a BSD-style
50131
50294
  // license that can be found in the LICENSE file.
50132
- const T$3 = 'plugins.spinner';
50295
+ const T$4 = 'plugins.spinner';
50133
50296
  /**
50134
50297
  * Custom events emitted by the plugin
50135
50298
  */
@@ -50194,11 +50357,11 @@ class SpinnerThreeBounce extends UIContainerPlugin {
50194
50357
  this.hasBuffering = false;
50195
50358
  }
50196
50359
  onPlay() {
50197
- trace(`${T$3} onPlay`);
50360
+ trace(`${T$4} onPlay`);
50198
50361
  this.hide();
50199
50362
  }
50200
50363
  onStop() {
50201
- trace(`${T$3} onStop`, {
50364
+ trace(`${T$4} onStop`, {
50202
50365
  showOnError: this.options.spinner?.showOnError,
50203
50366
  hasFatalError: this.hasFatalError,
50204
50367
  });
@@ -50208,7 +50371,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
50208
50371
  }
50209
50372
  onError(e) {
50210
50373
  this.hasFatalError = e.code === PlaybackErrorCode.MediaSourceUnavailable;
50211
- trace(`${T$3} onError`, {
50374
+ trace(`${T$4} onError`, {
50212
50375
  e,
50213
50376
  showOnError: this.options.spinner?.showOnError,
50214
50377
  hasFatalError: this.hasFatalError,
@@ -50242,7 +50405,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
50242
50405
  */
50243
50406
  render() {
50244
50407
  const showOnStart = this.options.spinner?.showOnStart;
50245
- trace(`${T$3} render`, {
50408
+ trace(`${T$4} render`, {
50246
50409
  buffering: this.container.buffering,
50247
50410
  showOnStart,
50248
50411
  });
@@ -50261,129 +50424,200 @@ class SpinnerThreeBounce extends UIContainerPlugin {
50261
50424
  }
50262
50425
  }
50263
50426
 
50264
- // An example implementation of client side performancestatistics
50265
- const CUSTOM_EVENTS_CONTAINER_START = 'container:start';
50266
- const WATCH_CUTOFF = 5;
50267
- const HEATMAP_INTERVAL = 10;
50268
- // TODO rewrite as core plugin
50269
- class Statistics extends ContainerPlugin {
50427
+ const T$3 = 'plugins.source_controller';
50428
+ const INITIAL_RETRY_DELAY = 1000;
50429
+ const MAX_RETRY_DELAY = 5000;
50430
+ const RETRY_DELAY_BLUR = 500;
50431
+ const VERSION$1 = '0.0.1';
50432
+ function noSync(cb) {
50433
+ queueMicrotask(cb);
50434
+ }
50435
+ /**
50436
+ * This plugin is responsible for managing the automatic failover between sources.
50437
+ * @beta
50438
+ * @remarks
50439
+ * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
50440
+ * on how sources ordering and selection works.
50441
+ *
50442
+ * This plugin does not expose any public methods apart from required by the Clappr plugin interface.
50443
+ * It is supposed to work autonomously.
50444
+ *
50445
+ * @example
50446
+ * ```ts
50447
+ * import { SourceController } from '@gcorevideo/player'
50448
+ *
50449
+ * Player.registerPlugin(SourceController)
50450
+ * ```
50451
+ */
50452
+ class SourceController extends CorePlugin {
50453
+ /*
50454
+ * The Logic itself is quite simple:
50455
+ * * Here is the short diagram:
50456
+ *
50457
+ * sources_list:
50458
+ * - a.mpd | +--------------------+
50459
+ * - b.m3u8 |--->| init |
50460
+ * - ... | |--------------------|
50461
+ * | current_source = 0 |
50462
+ * +--------------------+
50463
+ * |
50464
+ * | source = a.mpd
50465
+ * | playback = dash.js
50466
+ * v
50467
+ * +------------------+
50468
+ * +-->| load source |
50469
+ * | +---------|--------+
50470
+ * | v
50471
+ * | +------------------+
50472
+ * | | play |
50473
+ * | +---------|--------+
50474
+ * | |
50475
+ * | v
50476
+ * | +-----------------------+
50477
+ * | | on playback_error |
50478
+ * | |-----------------------|
50479
+ * | | current_source = |
50480
+ * | | (current_source + 1) |
50481
+ * | | % len sources_list |
50482
+ * | | |
50483
+ * | | delay 1..3s |
50484
+ * | +---------------|-------+
50485
+ * | |
50486
+ * | source=b.m3u8 |
50487
+ * | playback=hls.js |
50488
+ * +-------------------+
50489
+ *
50490
+ */
50491
+ sourcesList = [];
50492
+ currentSourceIndex = 0;
50493
+ sourcesDelay = {};
50494
+ active = false;
50495
+ sync = noSync;
50496
+ /**
50497
+ * @internal
50498
+ */
50270
50499
  get name() {
50271
- return 'statistics_gplayer';
50500
+ return 'source_controller';
50272
50501
  }
50502
+ /**
50503
+ * @internal
50504
+ */
50273
50505
  get supportedVersion() {
50274
50506
  return { min: CLAPPR_VERSION };
50275
50507
  }
50276
- started = false;
50277
- timeStart = 0;
50278
- heatmapSent = false;
50279
- heatmapLastTime = 0;
50280
- watchSent = false;
50281
- bufTracking = false;
50282
- lags = 0;
50283
- /**
50284
- * The time when buffering last started.
50285
- */
50286
- bufLastStarted = 0;
50508
+ constructor(core) {
50509
+ super(core);
50510
+ this.sourcesList = this.core.options.sources;
50511
+ if (this.core.options.source !== undefined) {
50512
+ // prevent Clappr from loading all sources simultaneously
50513
+ this.core.options.sources = [this.core.options.source];
50514
+ }
50515
+ else {
50516
+ this.core.options.sources = this.core.options.sources.slice(0, 1);
50517
+ }
50518
+ }
50287
50519
  /**
50288
- * The accumulated buffering duration.
50520
+ * @internal
50289
50521
  */
50290
- bufAccDuration = 0;
50291
- constructor(container) {
50292
- super(container);
50293
- assert(this.options.statistics &&
50294
- typeof this.options.statistics.send === 'function', 'Statistics plugin requires statistics options');
50295
- }
50296
50522
  bindEvents() {
50297
- // TODO remove this
50298
- this.listenToOnce(this.container, CUSTOM_EVENTS_CONTAINER_START, this.onStart);
50299
- this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
50300
- this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
50301
- this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
50302
- this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdateLive);
50303
- this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
50304
- this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.stopLevelSwitch);
50305
- }
50306
- startLevelSwitch() {
50307
- this.bufTracking = false;
50308
- }
50309
- stopLevelSwitch() {
50310
- this.bufTracking = true;
50523
+ super.bindEvents();
50524
+ this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
50311
50525
  }
50312
- onBuffering() {
50313
- if (this.bufTracking) {
50314
- this.bufLastStarted = performance.now();
50526
+ onReady() {
50527
+ trace(`${T$3} onReady`, {
50528
+ retrying: this.active,
50529
+ currentSource: this.sourcesList[this.currentSourceIndex],
50530
+ });
50531
+ const spinner = this.core.activeContainer?.getPlugin('spinner');
50532
+ if (spinner) {
50533
+ this.sync = (cb) => {
50534
+ spinner.once(SpinnerEvents.SYNC, cb);
50535
+ };
50315
50536
  }
50316
- }
50317
- onBufferFull() {
50318
- if (this.bufTracking && this.bufLastStarted) {
50319
- this.bufAccDuration += performance.now() - this.bufLastStarted;
50320
- this.lags++;
50537
+ else {
50538
+ this.sync = noSync;
50321
50539
  }
50322
- this.bufTracking = true;
50323
- }
50324
- onReady() {
50325
- this.initEvent();
50326
- if (this.options.autoPlay) {
50327
- this.onStart();
50540
+ this.bindContainerEventListeners();
50541
+ if (this.active) {
50542
+ this.core.activeContainer?.getPlugin('poster_custom')?.disable();
50543
+ spinner?.show();
50328
50544
  }
50329
50545
  }
50330
- initEvent() {
50331
- this.sendMessage('init');
50332
- }
50333
- sendMessage(state) {
50334
- this.send(state, {
50335
- // embed_url: this.options.referer,
50336
- // user_agent: Browser.userAgent
50546
+ bindContainerEventListeners() {
50547
+ this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
50548
+ trace(`${T$3} on PLAYBACK_ERROR`, {
50549
+ error: {
50550
+ code: error?.code,
50551
+ description: error?.description,
50552
+ level: error?.level,
50553
+ },
50554
+ retrying: this.active,
50555
+ currentSource: this.sourcesList[this.currentSourceIndex],
50556
+ });
50557
+ switch (error.code) {
50558
+ case PlaybackErrorCode.MediaSourceUnavailable:
50559
+ this.core.activeContainer?.getPlugin('poster_custom')?.disable();
50560
+ this.retryPlayback();
50561
+ break;
50562
+ }
50337
50563
  });
50338
- }
50339
- send(event, data = {}) {
50340
- this.options.statistics.send({
50341
- event,
50342
- type: this.container.getPlaybackType(),
50343
- ...data,
50564
+ this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
50565
+ trace(`${T$3} on PLAYBACK_PLAY`, {
50566
+ currentSource: this.sourcesList[this.currentSourceIndex],
50567
+ retrying: this.active,
50568
+ });
50569
+ if (this.active) {
50570
+ this.reset();
50571
+ // TODO make poster reset its state on enable
50572
+ this.core.activeContainer?.getPlugin('poster_custom')?.enable();
50573
+ this.core.activeContainer?.getPlugin('spinner')?.hide();
50574
+ }
50344
50575
  });
50345
50576
  }
50346
- sendHeatmap(time) {
50347
- const res = {
50348
- buffering: Math.round(this.bufAccDuration),
50349
- lags: this.lags,
50350
- };
50351
- this.bufAccDuration = 0;
50352
- this.lags = 0;
50353
- if (this.container.getPlaybackType() === Playback.VOD) {
50354
- res.timestamp = time;
50355
- }
50356
- this.send('heatmap', res);
50357
- this.heatmapSent = true;
50358
- this.heatmapLastTime = time;
50577
+ reset() {
50578
+ this.active = false;
50579
+ this.sourcesDelay = {};
50359
50580
  }
50360
- onTimeUpdateLive({ current }) {
50361
- // TODO check the `current` values for the live streams
50362
- if (!this.timeStart) {
50363
- this.timeStart = current;
50364
- }
50365
- try {
50366
- const elapsed = current - this.timeStart;
50367
- const heatmapElapsed = current - this.heatmapLastTime;
50368
- // TODO check if the heatmap is only needed for the live streams
50369
- if (!this.heatmapSent || heatmapElapsed >= HEATMAP_INTERVAL) {
50370
- this.sendHeatmap(current);
50371
- }
50372
- if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
50373
- this.watchSent = true;
50374
- this.sendMessage('watch');
50375
- }
50376
- }
50377
- catch (error) {
50378
- reportError(error);
50379
- }
50581
+ retryPlayback() {
50582
+ trace(`${T$3} retryPlayback enter`, {
50583
+ currentSourceIndex: this.currentSourceIndex,
50584
+ currentSource: this.sourcesList[this.currentSourceIndex],
50585
+ });
50586
+ this.active = true;
50587
+ this.getNextMediaSource().then((nextSource) => {
50588
+ trace(`${T$3} retryPlayback syncing...`, {
50589
+ nextSource,
50590
+ });
50591
+ const rnd = RETRY_DELAY_BLUR * Math.random();
50592
+ this.sync(() => {
50593
+ trace(`${T$3} retryPlayback loading...`);
50594
+ this.core.load(nextSource.source, nextSource.mimeType);
50595
+ trace(`${T$3} retryPlayback loaded`, {
50596
+ nextSource,
50597
+ });
50598
+ setTimeout(() => {
50599
+ // this.core.activePlayback.consent()
50600
+ this.core.activePlayback.play();
50601
+ trace(`${T$3} retryPlayback playing`);
50602
+ }, rnd);
50603
+ });
50604
+ });
50380
50605
  }
50381
- onStart() {
50382
- if (this.started) {
50383
- return;
50384
- }
50385
- this.started = true;
50386
- this.sendMessage('start');
50606
+ getNextMediaSource() {
50607
+ return new Promise((resolve) => {
50608
+ this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
50609
+ this.currentSourceIndex =
50610
+ (this.currentSourceIndex + 1) % this.sourcesList.length;
50611
+ const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
50612
+ const s = this.sourcesList[this.currentSourceIndex];
50613
+ setTimeout(() => resolve(s), delay);
50614
+ });
50615
+ }
50616
+ /**
50617
+ * @internal
50618
+ */
50619
+ static get version() {
50620
+ return VERSION$1;
50387
50621
  }
50388
50622
  }
50389
50623
 
@@ -50395,7 +50629,7 @@ const comboboxHTML = "<button data-subtitles-button class='media-control-button
50395
50629
 
50396
50630
  const stringHTML = "<div class=\"subtitle-string\">\n <p></p>\n</div>\n";
50397
50631
 
50398
- const VERSION$1 = '2.19.14';
50632
+ const VERSION = '2.19.14';
50399
50633
  const LOCAL_STORAGE_SUBTITLES_ID = 'gplayer.plugins.subtitles.selected';
50400
50634
  const T$2 = 'plugins.subtitles';
50401
50635
  const NO_TRACK = { language: 'off' };
@@ -50449,7 +50683,7 @@ class Subtitles extends UICorePlugin {
50449
50683
  * @internal
50450
50684
  */
50451
50685
  static get version() {
50452
- return VERSION$1;
50686
+ return VERSION;
50453
50687
  }
50454
50688
  static template = tmpl(comboboxHTML);
50455
50689
  static templateString = tmpl(stringHTML);
@@ -50761,6 +50995,184 @@ class Subtitles extends UICorePlugin {
50761
50995
  }
50762
50996
  }
50763
50997
 
50998
+ // An example implementation of client side performancestatistics
50999
+ const WATCH_CUTOFF = 5;
51000
+ const STALL_MEASURE_PERIOD = 10;
51001
+ const T$1 = 'plugins.telemetry';
51002
+ /**
51003
+ * Telemetry event type
51004
+ * @beta
51005
+ */
51006
+ var TelemetryEvent;
51007
+ (function (TelemetryEvent) {
51008
+ TelemetryEvent[TelemetryEvent["Init"] = 1] = "Init";
51009
+ TelemetryEvent[TelemetryEvent["Start"] = 2] = "Start";
51010
+ TelemetryEvent[TelemetryEvent["Watch"] = 3] = "Watch";
51011
+ TelemetryEvent[TelemetryEvent["Stall"] = 4] = "Stall";
51012
+ })(TelemetryEvent || (TelemetryEvent = {}));
51013
+ /**
51014
+ * Collects and reports the performance statistics.
51015
+ * @beta
51016
+ * @remarks
51017
+ * This plugin is experimental and its API is likely to change.
51018
+ *
51019
+ * Configuration options {@link TelemetryPluginSettings}
51020
+ *
51021
+ * @example
51022
+ * ```ts
51023
+ * import { Statistics } from '@gcorevideo/player'
51024
+ *
51025
+ * Player.registerPlugin(Statistics)
51026
+ *
51027
+ * const player = new Player({
51028
+ * statistics: {
51029
+ * send: (data) => {
51030
+ * fetch('/stats', {
51031
+ * method: 'POST',
51032
+ * body: JSON.stringify(data),
51033
+ * headers: { 'content-type': 'application/json' },
51034
+ * })
51035
+ * },
51036
+ * },
51037
+ * ...
51038
+ * })
51039
+ * ```
51040
+ */
51041
+ class Telemetry extends ContainerPlugin {
51042
+ /**
51043
+ * The name of the plugin.
51044
+ */
51045
+ get name() {
51046
+ return 'telemetry';
51047
+ }
51048
+ /**
51049
+ * The supported version of the plugin.
51050
+ */
51051
+ get supportedVersion() {
51052
+ return { min: CLAPPR_VERSION };
51053
+ }
51054
+ started = false;
51055
+ timeStart = 0;
51056
+ stallSent = false;
51057
+ stallLastTime = 0;
51058
+ watchSent = false;
51059
+ bufTracking = false;
51060
+ numStalls = 0;
51061
+ /**
51062
+ * The time when buffering last started.
51063
+ */
51064
+ bufLastStarted = 0;
51065
+ /**
51066
+ * The accumulated buffering duration.
51067
+ */
51068
+ stallAcc = 0;
51069
+ constructor(container) {
51070
+ super(container);
51071
+ assert(this.options.telemetry &&
51072
+ typeof this.options.telemetry.send === 'function', 'Telemetry plugin configuration is invalid: `send` option is required');
51073
+ }
51074
+ /**
51075
+ * @internal
51076
+ */
51077
+ bindEvents() {
51078
+ // TODO remove this
51079
+ // this.listenToOnce(
51080
+ // this.container,
51081
+ // CUSTOM_EVENTS_CONTAINER_START,
51082
+ // this.onStart,
51083
+ // )
51084
+ this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
51085
+ this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
51086
+ this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
51087
+ this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
51088
+ this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
51089
+ this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.endLevelSwitch);
51090
+ }
51091
+ startLevelSwitch() {
51092
+ this.bufTracking = false;
51093
+ }
51094
+ endLevelSwitch() {
51095
+ this.bufTracking = true;
51096
+ }
51097
+ onBuffering() {
51098
+ if (this.bufTracking) {
51099
+ this.bufLastStarted = performance.now();
51100
+ }
51101
+ }
51102
+ onBufferFull() {
51103
+ if (this.bufTracking && this.bufLastStarted) {
51104
+ this.stallAcc += performance.now() - this.bufLastStarted;
51105
+ this.numStalls++;
51106
+ }
51107
+ this.bufTracking = true;
51108
+ }
51109
+ onReady() {
51110
+ this.sendInit();
51111
+ trace(`${T$1} onReady`, {
51112
+ autoPlay: this.options.autoPlay,
51113
+ });
51114
+ if (this.options.autoPlay) {
51115
+ this.onStart();
51116
+ }
51117
+ else {
51118
+ this.listenToOnce(this.container.playback, Events$1.PLAYBACK_PLAY_INTENT, this.onStart);
51119
+ }
51120
+ }
51121
+ sendInit() {
51122
+ this.send({ event: TelemetryEvent.Init });
51123
+ }
51124
+ send(event) {
51125
+ this.options.telemetry.send({
51126
+ type: this.container.getPlaybackType(),
51127
+ ...event,
51128
+ });
51129
+ }
51130
+ sendStall(time) {
51131
+ // TODO don't send if no stalls?
51132
+ const res = {
51133
+ event: TelemetryEvent.Stall,
51134
+ count: this.numStalls,
51135
+ time,
51136
+ total_ms: Math.round(this.stallAcc * 1000),
51137
+ };
51138
+ this.stallAcc = 0;
51139
+ this.numStalls = 0;
51140
+ this.send(res);
51141
+ this.stallSent = true;
51142
+ this.stallLastTime = time;
51143
+ }
51144
+ onTimeUpdate({ current }) {
51145
+ if (!this.timeStart) {
51146
+ this.timeStart = current;
51147
+ }
51148
+ try {
51149
+ const elapsed = current - this.timeStart;
51150
+ const stallElapsed = current - this.stallLastTime;
51151
+ if (!this.stallSent || stallElapsed >= STALL_MEASURE_PERIOD) {
51152
+ this.sendStall(current);
51153
+ }
51154
+ if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
51155
+ this.watchSent = true;
51156
+ this.send({
51157
+ event: TelemetryEvent.Watch,
51158
+ });
51159
+ }
51160
+ }
51161
+ catch (error) {
51162
+ reportError(error);
51163
+ }
51164
+ }
51165
+ onStart() {
51166
+ if (this.started) {
51167
+ return;
51168
+ }
51169
+ this.started = true;
51170
+ this.send({
51171
+ event: TelemetryEvent.Start,
51172
+ });
51173
+ }
51174
+ }
51175
+
50764
51176
  var parseSrt$1 = {exports: {}};
50765
51177
 
50766
51178
  var parseSrt = parseSrt$1.exports;
@@ -50877,7 +51289,29 @@ const parseSRT = /*@__PURE__*/getDefaultExportFromCjs$1(parseSrtExports);
50877
51289
 
50878
51290
  const pluginHtml = "<div class=\"thumbnails-text\"></div>\n<% if (backdropHeight) { %>\n <div class=\"backdrop\" style=\"height: <%= backdropHeight %>px;\">\n <div class=\"carousel\"></div>\n </div>\n<% }; %>\n<% if (spotlightHeight) { %>\n <div class=\"spotlight\" style=\"height: <%= spotlightHeight %>px;\">\n </div>\n<% }; %>\n";
50879
51291
 
50880
- const T$1 = 'plugins.media_control_thumbnails';
51292
+ const T = 'plugins.thumbnails';
51293
+ /**
51294
+ * Displays the thumbnails of the video when available.
51295
+ * @beta
51296
+ * @example
51297
+ * ```ts
51298
+ * import { Thumbnails } from '@gcorevideo/player'
51299
+ *
51300
+ * Player.registerPlugin(Thumbnails)
51301
+ *
51302
+ * new Player({
51303
+ * thumbnails: {
51304
+ * backdropHeight: 200,
51305
+ * backdropMinOpacity: 0.9,
51306
+ * backdropMaxOpacity: 0.99,
51307
+ * spotlightHeight: 100,
51308
+ * vtt: '1\n00:00:00,000 --> 00:00:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,0,100,56\n\n2\n00:00:10,000 --> 00:00:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,0,100,56\n\n3\n00:00:20,000 --> 00:00:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,0,100,56\n\n4\n00:00:30,000 --> 00:00:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,0,100,56\n\n5\n00:00:40,000 --> 00:00:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,0,100,56\n\n6\n00:00:50,000 --> 00:01:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,0,100,56\n\n7\n00:01:00,000 --> 00:01:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,0,100,56\n\n8\n00:01:10,000 --> 00:01:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,56,100,56\n\n9\n00:01:20,000 --> 00:01:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,56,100,56\n\n10\n00:01:30,000 --> 00:01:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,56,100,56\n\n11\n00:01:40,000 --> 00:01:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,56,100,56\n\n12\n00:01:50,000 --> 00:02:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,56,100,56\n\n13\n00:02:00,000 --> 00:02:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,56,100,56\n\n14\n00:02:10,000 --> 00:02:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,56,100,56\n\n15\n00:02:20,000 --> 00:02:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,112,100,56\n\n16\n00:02:30,000 --> 00:02:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,112,100,56\n\n17\n00:02:40,000 --> 00:02:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,112,100,56\n\n18\n00:02:50,000 --> 00:03:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,112,100,56\n\n19\n00:03:00,000 --> 00:03:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,112,100,56\n\n20\n00:03:10,000 --> 00:03:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,112,100,56\n\n21\n00:03:20,000 --> 00:03:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,112,100,56\n\n22\n00:03:30,000 --> 00:03:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,168,100,56\n\n23\n00:03:40,000 --> 00:03:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,168,100,56\n\n24\n00:03:50,000 --> 00:04:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,168,100,56\n\n25\n00:04:00,000 --> 00:04:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,168,100,56\n\n26\n00:04:10,000 --> 00:04:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,168,100,56\n\n27\n00:04:20,000 --> 00:04:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,168,100,56\n\n28\n00:04:30,000 --> 00:04:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,168,100,56\n\n29\n00:04:40,000 --> 00:04:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,224,100,56\n\n30\n00:04:50,000 --> 00:05:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,224,100,56\n\n31\n00:05:00,000 --> 00:05:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,224,100,56\n\n32\n00:05:10,000 --> 00:05:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,224,100,56\n\n33\n00:05:20,000 --> 00:05:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,224,100,56\n\n34\n00:05:30,000 --> 00:05:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,224,100,56\n\n35\n00:05:40,000 --> 00:05:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,224,100,56\n\n36\n00:05:50,000 --> 00:06:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,280,100,56\n\n37\n00:06:00,000 --> 00:06:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,280,100,56\n\n38\n00:06:10,000 --> 00:06:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,280,100,56\n\n39\n00:06:20,000 --> 00:06:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,280,100,56\n\n40\n00:06:30,000 --> 00:06:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,280,100,56\n\n41\n00:06:40,000 --> 00:06:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,280,100,56\n\n42\n00:06:50,000 --> 00:07:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,280,100,56\n\n43\n00:07:00,000 --> 00:07:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,336,100,56\n\n44\n00:07:10,000 --> 00:07:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,336,100,56\n\n45\n00:07:20,000 --> 00:07:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,336,100,56\n\n46\n00:07:30,000 --> 00:07:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,336,100,56\n\n47\n00:07:40,000 --> 00:07:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,336,100,56\n\n48\n00:07:50,000 --> 00:08:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,336,100,56\n\n49\n00:08:00,000 --> 00:08:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,336,100,56\n',
51309
+ * sprite:
51310
+ * 'https://static.gvideo.co/videoplatform/sprites/2675/2452164_3dk4NsRt6vWsffEr.mp4_sprite.jpg',
51311
+ * },
51312
+ * })
51313
+ * ```
51314
+ */
50881
51315
  class Thumbnails extends UICorePlugin {
50882
51316
  _$spotlight = null;
50883
51317
  _$backdrop = null;
@@ -50892,20 +51326,27 @@ class Thumbnails extends UICorePlugin {
50892
51326
  _thumbsLoaded = false;
50893
51327
  _oldContainer = null;
50894
51328
  _thumbs = [];
51329
+ /**
51330
+ * @internal
51331
+ */
50895
51332
  get name() {
50896
- return 'media_control_thumbnails';
51333
+ return 'thumbnails';
50897
51334
  }
51335
+ /**
51336
+ * @internal
51337
+ */
50898
51338
  get supportedVersion() {
50899
51339
  return { min: CLAPPR_VERSION };
50900
51340
  }
51341
+ /**
51342
+ * @internal
51343
+ */
50901
51344
  get attributes() {
50902
51345
  return {
50903
- 'class': this.name
51346
+ class: this.name,
50904
51347
  };
50905
51348
  }
50906
- get template() {
50907
- return tmpl(pluginHtml);
50908
- }
51349
+ static template = tmpl(pluginHtml);
50909
51350
  /*
50910
51351
  * Helper to build the "thumbs" property for a sprite sheet.
50911
51352
  *
@@ -50949,6 +51390,9 @@ class Thumbnails extends UICorePlugin {
50949
51390
  return thumbs;
50950
51391
  }
50951
51392
  // TODO check if seek enabled
51393
+ /**
51394
+ * @internal
51395
+ */
50952
51396
  bindEvents() {
50953
51397
  this.listenToOnce(this.core, Events$1.CORE_READY, this._onCoreReady);
50954
51398
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_MOUSEMOVE_SEEKBAR, this._onMouseMove);
@@ -50965,7 +51409,9 @@ class Thumbnails extends UICorePlugin {
50965
51409
  }
50966
51410
  _onCoreReady() {
50967
51411
  try {
50968
- if (!this.options.thumbnails || !this.options.thumbnails.sprite || !this.options.thumbnails.vtt) {
51412
+ if (!this.options.thumbnails ||
51413
+ !this.options.thumbnails.sprite ||
51414
+ !this.options.thumbnails.vtt) {
50969
51415
  this.destroy();
50970
51416
  return;
50971
51417
  }
@@ -51016,7 +51462,7 @@ class Thumbnails extends UICorePlugin {
51016
51462
  }
51017
51463
  _getOptions() {
51018
51464
  if (!('thumbnails' in this.core.options)) {
51019
- throw '\'thumbnail property missing from options object.';
51465
+ throw "'thumbnail property missing from options object.";
51020
51466
  }
51021
51467
  return this.core.options.thumbnails;
51022
51468
  }
@@ -51117,7 +51563,7 @@ class Thumbnails extends UICorePlugin {
51117
51563
  this.$img.css({
51118
51564
  height: this.spriteSheetHeight * scaleFactor,
51119
51565
  left: -1 * thumb.x * scaleFactor,
51120
- top: -1 * thumb.y * scaleFactor
51566
+ top: -1 * thumb.y * scaleFactor,
51121
51567
  });
51122
51568
  if (this.$container.find(this.$img).length === 0) {
51123
51569
  this.$container.append(this.$img);
@@ -51148,7 +51594,7 @@ class Thumbnails extends UICorePlugin {
51148
51594
  // calculate how far along the carousel should currently be slid
51149
51595
  // depending on where the user is hovering on the progress bar
51150
51596
  _updateCarousel() {
51151
- trace(`${T$1} _updateCarousel`, {
51597
+ trace(`${T} _updateCarousel`, {
51152
51598
  backdropHeight: this._getOptions().backdropHeight,
51153
51599
  });
51154
51600
  if (!this._getOptions().backdropHeight) {
@@ -51159,7 +51605,7 @@ class Thumbnails extends UICorePlugin {
51159
51605
  const videoDuration = this.core.mediaControl.container.getDuration();
51160
51606
  const startTimeOffset = this.core.mediaControl.container.getStartTimeOffset();
51161
51607
  // the time into the video at the current hover position
51162
- const hoverTime = startTimeOffset + (videoDuration * hoverPosition);
51608
+ const hoverTime = startTimeOffset + videoDuration * hoverPosition;
51163
51609
  const backdropWidth = this._$backdrop.width();
51164
51610
  const $carousel = this._$carousel;
51165
51611
  const carouselWidth = $carousel.width();
@@ -51184,9 +51630,9 @@ class Thumbnails extends UICorePlugin {
51184
51630
  const positionInThumb = timeIntoThumb / thumbDuration;
51185
51631
  const xCoordInThumb = thumbWidth * positionInThumb;
51186
51632
  // now calculate the position along carousel that we want to be above the hover position
51187
- const xCoordInCarousel = (thumbIndex * thumbWidth) + xCoordInThumb;
51633
+ const xCoordInCarousel = thumbIndex * thumbWidth + xCoordInThumb;
51188
51634
  // and finally the position of the carousel when the hover position is taken in to consideration
51189
- const carouselXCoord = xCoordInCarousel - (hoverPosition * backdropWidth);
51635
+ const carouselXCoord = xCoordInCarousel - hoverPosition * backdropWidth;
51190
51636
  $carousel.css('left', -carouselXCoord);
51191
51637
  const maxOpacity = this._getOptions().backdropMaxOpacity || 0.6;
51192
51638
  const minOpacity = this._getOptions().backdropMinOpacity || 0.08;
@@ -51202,12 +51648,12 @@ class Thumbnails extends UICorePlugin {
51202
51648
  distance = Math.min(0, distance + thumbWidth);
51203
51649
  }
51204
51650
  // fade over the width of 2 thumbnails
51205
- const opacity = Math.max(maxOpacity - (Math.abs(distance) / (2 * thumbWidth)), minOpacity);
51651
+ const opacity = Math.max(maxOpacity - Math.abs(distance) / (2 * thumbWidth), minOpacity);
51206
51652
  this._$backdropCarouselImgs[i].css('opacity', opacity);
51207
51653
  }
51208
51654
  }
51209
51655
  _updateSpotlightThumb() {
51210
- trace(`${T$1} _updateSpotlightThumb`, {
51656
+ trace(`${T} _updateSpotlightThumb`, {
51211
51657
  spotlightHeight: this._getOptions().spotlightHeight,
51212
51658
  });
51213
51659
  if (!this._getOptions().spotlightHeight) {
@@ -51218,7 +51664,7 @@ class Thumbnails extends UICorePlugin {
51218
51664
  const videoDuration = this.core.mediaControl.container.getDuration();
51219
51665
  // the time into the video at the current hover position
51220
51666
  const startTimeOffset = this.core.mediaControl.container.getStartTimeOffset();
51221
- const hoverTime = startTimeOffset + (videoDuration * hoverPosition);
51667
+ const hoverTime = startTimeOffset + videoDuration * hoverPosition;
51222
51668
  this.setText(hoverTime);
51223
51669
  // determine which thumbnail applies to the current time
51224
51670
  const thumbIndex = this._getThumbIndexForTime(hoverTime);
@@ -51230,7 +51676,7 @@ class Thumbnails extends UICorePlugin {
51230
51676
  const elWidth = this.$el.width();
51231
51677
  const thumbWidth = $spotlight.width();
51232
51678
  const thumbHeight = $spotlight.height();
51233
- let spotlightXPos = (elWidth * hoverPosition) - (thumbWidth / 2);
51679
+ let spotlightXPos = elWidth * hoverPosition - thumbWidth / 2;
51234
51680
  // adjust so the entire thumbnail is always visible
51235
51681
  spotlightXPos = Math.max(Math.min(spotlightXPos, elWidth - thumbWidth), 0);
51236
51682
  $spotlight.css('left', spotlightXPos);
@@ -51252,7 +51698,7 @@ class Thumbnails extends UICorePlugin {
51252
51698
  return 0;
51253
51699
  }
51254
51700
  _renderPlugin() {
51255
- trace(`${T$1} _renderPlugin`, {
51701
+ trace(`${T} _renderPlugin`, {
51256
51702
  show: this._show,
51257
51703
  thumbsLoaded: this._thumbsLoaded,
51258
51704
  thumbs: this._thumbs.length,
@@ -51270,10 +51716,10 @@ class Thumbnails extends UICorePlugin {
51270
51716
  }
51271
51717
  }
51272
51718
  _createElements() {
51273
- trace(`${T$1} _createElements`);
51274
- this.$el.html(this.template({
51275
- 'backdropHeight': this._getOptions().backdropHeight,
51276
- 'spotlightHeight': this._getOptions().spotlightHeight
51719
+ trace(`${T} _createElements`);
51720
+ this.$el.html(Thumbnails.template({
51721
+ backdropHeight: this._getOptions().backdropHeight,
51722
+ spotlightHeight: this._getOptions().spotlightHeight,
51277
51723
  }));
51278
51724
  // cache dom references
51279
51725
  this._$spotlight = this.$el.find('.spotlight');
@@ -51285,208 +51731,12 @@ class Thumbnails extends UICorePlugin {
51285
51731
  }
51286
51732
  }
51287
51733
 
51288
- const T = 'plugins.source_controller';
51289
- const INITIAL_RETRY_DELAY = 1000;
51290
- const MAX_RETRY_DELAY = 5000;
51291
- const RETRY_DELAY_BLUR = 500;
51292
- const VERSION = '0.0.1';
51293
- function noSync(cb) {
51294
- queueMicrotask(cb);
51295
- }
51296
- /**
51297
- * This plugin is responsible for managing the automatic failover between sources.
51298
- * @beta
51299
- * @remarks
51300
- * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
51301
- * on how sources ordering and selection works.
51302
- *
51303
- * This plugin does not expose any public methods apart from required by the Clappr plugin interface.
51304
- * It is supposed to work autonomously.
51305
- *
51306
- * @example
51307
- * ```ts
51308
- * import { SourceController } from '@gcorevideo/player'
51309
- *
51310
- * Player.registerPlugin(SourceController)
51311
- * ```
51312
- */
51313
- class SourceController extends CorePlugin {
51314
- /*
51315
- * The Logic itself is quite simple:
51316
- * * Here is the short diagram:
51317
- *
51318
- * sources_list:
51319
- * - a.mpd | +--------------------+
51320
- * - b.m3u8 |--->| init |
51321
- * - ... | |--------------------|
51322
- * | current_source = 0 |
51323
- * +--------------------+
51324
- * |
51325
- * | source = a.mpd
51326
- * | playback = dash.js
51327
- * v
51328
- * +------------------+
51329
- * +-->| load source |
51330
- * | +---------|--------+
51331
- * | v
51332
- * | +------------------+
51333
- * | | play |
51334
- * | +---------|--------+
51335
- * | |
51336
- * | v
51337
- * | +-----------------------+
51338
- * | | on playback_error |
51339
- * | |-----------------------|
51340
- * | | current_source = |
51341
- * | | (current_source + 1) |
51342
- * | | % len sources_list |
51343
- * | | |
51344
- * | | delay 1..3s |
51345
- * | +---------------|-------+
51346
- * | |
51347
- * | source=b.m3u8 |
51348
- * | playback=hls.js |
51349
- * +-------------------+
51350
- *
51351
- */
51352
- sourcesList = [];
51353
- currentSourceIndex = 0;
51354
- sourcesDelay = {};
51355
- active = false;
51356
- sync = noSync;
51357
- /**
51358
- * @internal
51359
- */
51360
- get name() {
51361
- return 'source_controller';
51362
- }
51363
- /**
51364
- * @internal
51365
- */
51366
- get supportedVersion() {
51367
- return { min: CLAPPR_VERSION };
51368
- }
51369
- constructor(core) {
51370
- super(core);
51371
- this.sourcesList = this.core.options.sources;
51372
- if (this.core.options.source !== undefined) {
51373
- // prevent Clappr from loading all sources simultaneously
51374
- this.core.options.sources = [this.core.options.source];
51375
- }
51376
- else {
51377
- this.core.options.sources = this.core.options.sources.slice(0, 1);
51378
- }
51379
- }
51380
- /**
51381
- * @internal
51382
- */
51383
- bindEvents() {
51384
- super.bindEvents();
51385
- this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
51386
- }
51387
- onReady() {
51388
- trace(`${T} onReady`, {
51389
- retrying: this.active,
51390
- currentSource: this.sourcesList[this.currentSourceIndex],
51391
- });
51392
- const spinner = this.core.activeContainer?.getPlugin('spinner');
51393
- if (spinner) {
51394
- this.sync = (cb) => {
51395
- spinner.once(SpinnerEvents.SYNC, cb);
51396
- };
51397
- }
51398
- else {
51399
- this.sync = noSync;
51400
- }
51401
- this.bindContainerEventListeners();
51402
- if (this.active) {
51403
- this.core.activeContainer?.getPlugin('poster_custom')?.disable();
51404
- spinner?.show();
51405
- }
51406
- }
51407
- bindContainerEventListeners() {
51408
- this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
51409
- trace(`${T} on PLAYBACK_ERROR`, {
51410
- error: {
51411
- code: error?.code,
51412
- description: error?.description,
51413
- level: error?.level,
51414
- },
51415
- retrying: this.active,
51416
- currentSource: this.sourcesList[this.currentSourceIndex],
51417
- });
51418
- switch (error.code) {
51419
- case PlaybackErrorCode.MediaSourceUnavailable:
51420
- this.core.activeContainer?.getPlugin('poster_custom')?.disable();
51421
- this.retryPlayback();
51422
- break;
51423
- }
51424
- });
51425
- this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
51426
- trace(`${T} on PLAYBACK_PLAY`, {
51427
- currentSource: this.sourcesList[this.currentSourceIndex],
51428
- retrying: this.active,
51429
- });
51430
- if (this.active) {
51431
- this.reset();
51432
- // TODO make poster reset its state on enable
51433
- this.core.activeContainer?.getPlugin('poster_custom')?.enable();
51434
- this.core.activeContainer?.getPlugin('spinner')?.hide();
51435
- }
51436
- });
51437
- }
51438
- reset() {
51439
- this.active = false;
51440
- this.sourcesDelay = {};
51441
- }
51442
- retryPlayback() {
51443
- trace(`${T} retryPlayback enter`, {
51444
- currentSourceIndex: this.currentSourceIndex,
51445
- currentSource: this.sourcesList[this.currentSourceIndex],
51446
- });
51447
- this.active = true;
51448
- this.getNextMediaSource().then((nextSource) => {
51449
- trace(`${T} retryPlayback syncing...`, {
51450
- nextSource,
51451
- });
51452
- const rnd = RETRY_DELAY_BLUR * Math.random();
51453
- this.sync(() => {
51454
- trace(`${T} retryPlayback loading...`);
51455
- this.core.load(nextSource.source, nextSource.mimeType);
51456
- trace(`${T} retryPlayback loaded`, {
51457
- nextSource,
51458
- });
51459
- setTimeout(() => {
51460
- // this.core.activePlayback.consent()
51461
- this.core.activePlayback.play();
51462
- trace(`${T} retryPlayback playing`);
51463
- }, rnd);
51464
- });
51465
- });
51466
- }
51467
- getNextMediaSource() {
51468
- return new Promise((resolve) => {
51469
- this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
51470
- this.currentSourceIndex =
51471
- (this.currentSourceIndex + 1) % this.sourcesList.length;
51472
- const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
51473
- const s = this.sourcesList[this.currentSourceIndex];
51474
- setTimeout(() => resolve(s), delay);
51475
- });
51476
- }
51477
- /**
51478
- * @internal
51479
- */
51480
- static get version() {
51481
- return VERSION;
51482
- }
51483
- }
51484
-
51485
51734
  var VolumeFadeEvents;
51486
51735
  (function (VolumeFadeEvents) {
51487
51736
  VolumeFadeEvents["FADE"] = "core:volume:fade";
51488
51737
  })(VolumeFadeEvents || (VolumeFadeEvents = {}));
51489
51738
  /**
51739
+ * Applies fade effect to the player's volume change.
51490
51740
  * @beta
51491
51741
  */
51492
51742
  class VolumeFade extends UICorePlugin {
@@ -51494,15 +51744,22 @@ class VolumeFade extends UICorePlugin {
51494
51744
  container = null;
51495
51745
  delay = 0;
51496
51746
  interval = null;
51747
+ /**
51748
+ * @internal
51749
+ */
51497
51750
  get name() {
51498
51751
  return 'volume_fade';
51499
51752
  }
51753
+ /**
51754
+ * @internal
51755
+ */
51500
51756
  bindEvents() {
51757
+ // TODO on container changed
51501
51758
  this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
51502
51759
  if (this.core.mediaControl) {
51503
51760
  this.listenTo(this.core.mediaControl, 'mediacontrol:volume:user', this._onUserChangeVolume);
51504
51761
  }
51505
- this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
51762
+ // this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
51506
51763
  }
51507
51764
  unBindEvents() {
51508
51765
  this.core.$el.off('mouseleave.volume');
@@ -51574,4 +51831,4 @@ class VolumeFade extends UICorePlugin {
51574
51831
  }
51575
51832
  }
51576
51833
 
51577
- export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DisableControls, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, LogTracer, Logger, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackErrorCode, PlaybackRate, Player, PlayerEvent, Poster, SeekTime, SentryTracer, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Statistics, Subtitles, Thumbnails, VolumeFade, VolumeFadeEvents, reportError, setTracer, trace, version };
51834
+ export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, LogTracer, Logger, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackErrorCode, PlaybackRate, Player, PlayerEvent, Poster, SeekTime, SentryTracer, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents, reportError, setTracer, trace, version };