j1-template 2024.3.21 → 2024.3.23

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 (383) hide show
  1. checksums.yaml +4 -4
  2. data/assets/data/amplitude_app.html +60 -51
  3. data/assets/data/{galeries.html → gallery_app.html} +4 -4
  4. data/assets/theme/bla +0 -0
  5. data/assets/theme/j1/adapter/js/advertising.js +40 -38
  6. data/assets/theme/j1/adapter/js/algolia.js +13 -11
  7. data/assets/theme/j1/adapter/js/amplitude.js +628 -380
  8. data/assets/theme/j1/adapter/js/analytics.js +19 -17
  9. data/assets/theme/j1/adapter/js/asciidoctor.js +10 -8
  10. data/assets/theme/j1/adapter/js/attic.js +24 -22
  11. data/assets/theme/j1/adapter/js/bmd.js +10 -8
  12. data/assets/theme/j1/adapter/js/carousel.js +12 -9
  13. data/assets/theme/j1/adapter/js/chatbot.js +106 -104
  14. data/assets/theme/j1/adapter/js/clipboard.js +16 -14
  15. data/assets/theme/j1/adapter/js/comments.js +24 -22
  16. data/assets/theme/j1/adapter/js/cookieConsent.js +5 -1
  17. data/assets/theme/j1/adapter/js/customFunctions.js +12 -10
  18. data/assets/theme/j1/adapter/js/customModule.js +10 -8
  19. data/assets/theme/j1/adapter/js/docsearch.js +33 -31
  20. data/assets/theme/j1/adapter/js/dropdowns.js +16 -14
  21. data/assets/theme/j1/adapter/js/fab.js +34 -32
  22. data/assets/theme/j1/adapter/js/gallery.js +22 -20
  23. data/assets/theme/j1/adapter/js/gemini.js +66 -64
  24. data/assets/theme/j1/adapter/js/iconPicker.js +31 -29
  25. data/assets/theme/j1/adapter/js/iconPickerPage.js +11 -9
  26. data/assets/theme/j1/adapter/js/iframer.js +17 -15
  27. data/assets/theme/j1/adapter/js/j1.js +146 -143
  28. data/assets/theme/j1/adapter/js/lazyLoader.js +33 -31
  29. data/assets/theme/j1/adapter/js/lightbox.js +9 -7
  30. data/assets/theme/j1/adapter/js/logger.js +11 -9
  31. data/assets/theme/j1/adapter/js/lunr.js +37 -35
  32. data/assets/theme/j1/adapter/js/masonry.js +23 -21
  33. data/assets/theme/j1/adapter/js/masterslider.js +31 -29
  34. data/assets/theme/j1/adapter/js/mmenu.js +25 -23
  35. data/assets/theme/j1/adapter/js/navigator.js +43 -41
  36. data/assets/theme/j1/adapter/js/particles.js +12 -10
  37. data/assets/theme/j1/adapter/js/rangeSlider.js +21 -19
  38. data/assets/theme/j1/adapter/js/rouge.js +10 -8
  39. data/assets/theme/j1/adapter/js/rtable.js +14 -12
  40. data/assets/theme/j1/adapter/js/rtextResizer.js +10 -8
  41. data/assets/theme/j1/adapter/js/scroller.js +15 -13
  42. data/assets/theme/j1/adapter/js/slick.js +18 -16
  43. data/assets/theme/j1/adapter/js/slimSelect.js +30 -28
  44. data/assets/theme/j1/adapter/js/speak2me.js +25 -23
  45. data/assets/theme/j1/adapter/js/swiper.js +13 -11
  46. data/assets/theme/j1/adapter/js/themeToggler.js +11 -9
  47. data/assets/theme/j1/adapter/js/themes.js +60 -86
  48. data/assets/theme/j1/adapter/js/toccer.js +13 -11
  49. data/assets/theme/j1/adapter/js/translator.js +19 -16
  50. data/assets/theme/j1/adapter/js/videojs.js +9 -7
  51. data/assets/theme/j1/adapter/js/waves.js +18 -16
  52. data/assets/theme/j1/core/css/themes/unolight/bootstrap.css +19 -52
  53. data/assets/theme/j1/core/css/themes/unolight/bootstrap.min.css +1 -1
  54. data/assets/theme/j1/core/js/template.js +11180 -10968
  55. data/assets/theme/j1/core/js/template.min.js +13 -18
  56. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.css +10 -4
  57. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.min.css +1 -1
  58. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.css +15 -8
  59. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.min.css +2 -1
  60. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.css +35 -14
  61. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.min.css +1 -1
  62. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.js +817 -695
  63. data/assets/theme/j1/modules/backstretch/js/backstretch.js +2 -2
  64. data/assets/theme/j1/modules/backstretch/js/backstretch.min.js +1 -1
  65. data/assets/theme/j1/modules/cookieConsent/js/cookieConsent.js +11 -11
  66. data/assets/theme/j1/modules/cookieConsent/js/cookieConsent.min.js +2 -1
  67. data/assets/theme/j1/modules/dropdowns/js/dropdowns.js +2 -2
  68. data/assets/theme/j1/modules/dropdowns/js/dropdowns.min.js +1 -1
  69. data/assets/theme/j1/modules/fab/js/fab.js +2 -2
  70. data/assets/theme/j1/modules/fab/js/fab.min.js +1 -1
  71. data/assets/theme/j1/modules/lightGallery/!v2.7.2/css/lg-transitions.css +984 -0
  72. data/assets/theme/j1/modules/lightGallery/!v2.7.2/css/lg-transitions.min.css +26 -0
  73. data/assets/theme/j1/modules/lightGallery/!v2.7.2/css/lightgallery-bundle.css +1627 -0
  74. data/assets/theme/j1/modules/lightGallery/!v2.7.2/css/lightgallery-bundle.min.css +25 -0
  75. data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/uno.css +1 -1
  76. data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/uno.min.css +1 -1
  77. data/assets/theme/j1/modules/lightGallery/!v2.7.2/fonts/lg.svg +54 -0
  78. data/assets/theme/j1/modules/lightGallery/!v2.7.2/fonts/lg.ttf +0 -0
  79. data/assets/theme/j1/modules/lightGallery/!v2.7.2/fonts/lg.woff +0 -0
  80. data/assets/theme/j1/modules/lightGallery/!v2.7.2/fonts/lg.woff2 +0 -0
  81. data/assets/theme/j1/modules/lightGallery/!v2.7.2/images/loading.gif +0 -0
  82. data/assets/theme/j1/modules/lightGallery/!v2.7.2/img/loading.gif +0 -0
  83. data/assets/theme/j1/modules/lightGallery/!v2.7.2/img/video-play.png +0 -0
  84. data/assets/theme/j1/modules/lightGallery/!v2.7.2/img/vimeo-play.png +0 -0
  85. data/assets/theme/j1/modules/lightGallery/!v2.7.2/img/youtube-play.png +0 -0
  86. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/lightgallery.js +2782 -0
  87. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/lightgallery.min.js +26 -0
  88. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/parser/webvtt/LICENSE.md +44 -0
  89. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/parser/webvtt/README.md +37 -0
  90. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/parser/webvtt/parser.js +890 -0
  91. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/parser/webvtt/parser.min.js +8 -0
  92. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/j1/lg-video.1.js +585 -0
  93. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-autoplay.js +275 -0
  94. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-autoplay.min.js +26 -0
  95. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-comment.js +230 -0
  96. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-comment.min.js +26 -0
  97. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-fullscreen.js +160 -0
  98. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-fullscreen.min.js +26 -0
  99. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-hash.js +223 -0
  100. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-hash.min.js +27 -0
  101. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-medium-zoom.js +157 -0
  102. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-medium-zoom.min.js +26 -0
  103. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-pager.js +164 -0
  104. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-pager.min.js +26 -0
  105. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-rotate.js +299 -0
  106. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-rotate.min.js +26 -0
  107. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-share.js +244 -0
  108. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-share.min.js +27 -0
  109. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-thumbnail.js +509 -0
  110. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-thumbnail.min.js +26 -0
  111. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-video.js +909 -0
  112. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-video.min.js +26 -0
  113. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-vimeo-thumbnail.js +207 -0
  114. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-vimeo-thumbnail.min.js +26 -0
  115. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-zoom.js +999 -0
  116. data/assets/theme/j1/modules/lightGallery/!v2.7.2/js/plugins/lg-zoom.min.js +26 -0
  117. data/assets/theme/j1/modules/lightGallery/css/lg-transitions.css +3 -126
  118. data/assets/theme/j1/modules/lightGallery/css/lg-transitions.min.css +3 -10
  119. data/assets/theme/j1/modules/lightGallery/css/lightgallery-bundle.css +70 -237
  120. data/assets/theme/j1/modules/lightGallery/css/lightgallery-bundle.min.css +4 -10
  121. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/animation-w.png +0 -0
  122. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/customize-w.png +0 -0
  123. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/dynamic-w.png +0 -0
  124. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/facebook-icon.svg +10 -0
  125. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/googleplus-icon.svg +30 -0
  126. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/html5-w.png +0 -0
  127. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/linked-in.png +0 -0
  128. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/module-w.png +0 -0
  129. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/play-button-hover.svg +94 -0
  130. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/play-button.png +0 -0
  131. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/play-button.svg +93 -0
  132. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/responsive-w.png +0 -0
  133. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/thumb-w.png +0 -0
  134. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/touch-w.png +0 -0
  135. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/twitter-icon.svg +15 -0
  136. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/twitter.png +0 -0
  137. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/video1-w.png +0 -0
  138. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/zoom-w.png +0 -0
  139. data/assets/theme/j1/modules/lightGallery/css/theme/uno/icons/zoom.png +0 -0
  140. data/assets/theme/j1/modules/lightGallery/css/theme/uno/uno.css +276 -0
  141. data/assets/theme/j1/modules/lightGallery/css/theme/uno/uno.min.css +17 -0
  142. data/assets/theme/j1/modules/lightGallery/js/lightgallery.js +163 -120
  143. data/assets/theme/j1/modules/lightGallery/js/lightgallery.min.js +6 -6
  144. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/lg-thumbnail.0.js +495 -0
  145. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/lg-thumbnail.1.js +513 -0
  146. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/lg-video.0.js +553 -0
  147. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/lg-video.1.js +1 -1
  148. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/lg-video.2.js +914 -0
  149. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-autoplay.js +4 -4
  150. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-autoplay.min.js +5 -5
  151. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-comment.js +5 -5
  152. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-comment.min.js +6 -6
  153. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-fullscreen.js +4 -4
  154. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-fullscreen.min.js +5 -5
  155. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-hash.js +4 -4
  156. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-hash.min.js +5 -6
  157. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-medium-zoom.js +5 -5
  158. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-medium-zoom.min.js +6 -6
  159. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-pager.js +4 -4
  160. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-pager.min.js +5 -5
  161. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-relative-caption.js +179 -0
  162. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-relative-caption.min.js +32 -0
  163. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-rotate.js +4 -4
  164. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-rotate.min.js +6 -6
  165. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-share.js +4 -4
  166. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-share.min.js +6 -7
  167. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-thumbnail.js +27 -20
  168. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-thumbnail.min.js +5 -5
  169. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.js +77 -125
  170. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.min.js +6 -6
  171. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-vimeo-thumbnail.js +4 -4
  172. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-vimeo-thumbnail.min.js +5 -5
  173. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-zoom.js +11 -5
  174. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-zoom.min.js +5 -5
  175. data/assets/theme/j1/modules/lunr/js/j1.js +1 -1
  176. data/assets/theme/j1/modules/lunr/js/j1.min.js +2 -1
  177. data/assets/theme/j1/modules/rtable/js/rtable.js +2 -2
  178. data/assets/theme/j1/modules/rtable/js/rtable.min.js +2 -1
  179. data/assets/theme/j1/modules/scroller/js/scroller.js +31 -29
  180. data/assets/theme/j1/modules/scroller/js/scroller.min.js +2 -1
  181. data/assets/theme/j1/modules/themeSwitcher/js/switcher.js +38 -37
  182. data/assets/theme/j1/modules/themeSwitcher/js/switcher.min.js +2 -1
  183. data/assets/theme/j1/modules/translator/js/translator.js +17 -17
  184. data/assets/theme/j1/modules/translator/js/translator.min.js +1 -1
  185. data/assets/theme/j1/modules/videoPlayer/tiktoc/README.md +1 -0
  186. data/assets/theme/j1/modules/videojs/!v8.12.0/css/font/README.md +151 -0
  187. data/assets/theme/j1/modules/videojs/!v8.12.0/css/font/VideoJS.svg +150 -0
  188. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/city.css +147 -0
  189. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/city.min.css +5 -0
  190. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/fantasy.css +113 -0
  191. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/fantasy.min.css +5 -0
  192. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/forest.css +166 -0
  193. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/forest.min.css +5 -0
  194. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/sea.css +72 -0
  195. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/sea.min.css +5 -0
  196. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/uno.css +311 -0
  197. data/assets/theme/j1/modules/videojs/!v8.12.0/css/themes/uno.min.css +19 -0
  198. data/assets/theme/j1/modules/videojs/!v8.12.0/css/videojs.css +1686 -0
  199. data/assets/theme/j1/modules/videojs/!v8.12.0/css/videojs.min.css +13 -0
  200. data/assets/theme/j1/modules/videojs/!v8.12.0/js/video.js +65226 -0
  201. data/assets/theme/j1/modules/videojs/!v8.12.0/js/video.min.js +55 -0
  202. data/assets/theme/j1/modules/videojs/assets/README.md +1 -0
  203. data/assets/theme/j1/modules/videojs/assets/icons/speedometer-medium.svg +35 -0
  204. data/assets/theme/j1/modules/videojs/css/font/VideoJS.ttf +0 -0
  205. data/assets/theme/j1/modules/videojs/css/font/VideoJS.woff +0 -0
  206. data/assets/theme/j1/modules/videojs/css/themes/uno.css +157 -22
  207. data/assets/theme/j1/modules/videojs/css/themes/uno.min.css +1 -1
  208. data/assets/theme/j1/modules/videojs/css/videojs.css +674 -316
  209. data/assets/theme/j1/modules/videojs/css/videojs.min.css +4 -3
  210. data/assets/theme/j1/modules/videojs/js/video.js +15893 -12288
  211. data/assets/theme/j1/modules/videojs/js/video.min.js +22 -23
  212. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/!examples/index.html +31 -0
  213. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/LICENSE +19 -0
  214. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/README.md +69 -0
  215. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/css/aspect-ratio-panel.css +2 -0
  216. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/css/aspect-ratio-panel.min.css +2 -0
  217. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/js/aspect-ratio-panel.js +339 -0
  218. data/assets/theme/j1/modules/videojs/plugins/controls/aspect-ratio-panel/js/aspect-ratio-panel.min.js +2 -0
  219. data/assets/theme/j1/modules/videojs/{js/plugins/controls/autocaption → plugins/controls/autocaption/js}/autocaption.js +0 -5
  220. data/assets/theme/j1/modules/videojs/plugins/controls/persist-settings/!examples/index.html +29 -0
  221. data/assets/theme/j1/modules/videojs/plugins/controls/persist-settings/LICENSE +19 -0
  222. data/assets/theme/j1/modules/videojs/plugins/controls/persist-settings/README.md +90 -0
  223. data/assets/theme/j1/modules/videojs/plugins/controls/persist-settings/js/videojs-persist.js +120 -0
  224. data/assets/theme/j1/modules/videojs/plugins/controls/persist-settings/js/videojs-persist.min.js +2 -0
  225. data/assets/theme/j1/modules/videojs/plugins/controls/playbackrate-adjuster/!examples/index.html +37 -0
  226. data/assets/theme/j1/modules/videojs/plugins/controls/playbackrate-adjuster/LICENSE +19 -0
  227. data/assets/theme/j1/modules/videojs/plugins/controls/playbackrate-adjuster/README.md +61 -0
  228. data/assets/theme/j1/modules/videojs/plugins/controls/playbackrate-adjuster/js/playbackrate-adjuster.js +94 -0
  229. data/assets/theme/j1/modules/videojs/plugins/controls/playbackrate-adjuster/js/playbackrate-adjuster.min.js +20 -0
  230. data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/skipbuttons/README.md +25 -11
  231. data/assets/theme/j1/modules/videojs/{css/plugins/controls → plugins/controls/zoom/css}/zoom.css +7 -6
  232. data/assets/theme/j1/modules/videojs/plugins/controls/zoom/css/zoom.min.css +22 -0
  233. data/assets/theme/j1/modules/videojs/{js/plugins/players/dm → plugins/players/dm/js}/dailymotion.js +11 -9
  234. data/assets/theme/j1/modules/videojs/plugins/players/dm/js/dailymotion.min.js +19 -0
  235. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.0.js +521 -0
  236. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.1.js +605 -0
  237. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.3.js +643 -0
  238. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.4.js +583 -0
  239. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.5.js +665 -0
  240. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.6.js +642 -0
  241. data/assets/theme/j1/modules/videojs/plugins/players/vm/!unused/vimeo.7.js +673 -0
  242. data/assets/theme/j1/modules/videojs/{js/plugins/players/vm/api → plugins/players/vm/api/js}/vimeo.js +1 -1
  243. data/assets/theme/j1/modules/videojs/{js/plugins/players/vm/api → plugins/players/vm/api/js}/vimeo.min.js +1 -1
  244. data/assets/theme/j1/modules/videojs/{js/plugins/players/vm → plugins/players/vm/js}/vimeo.js +13 -12
  245. data/assets/theme/j1/modules/videojs/plugins/players/vm/js/vimeo.min.js +28 -0
  246. data/assets/theme/j1/modules/videojs/plugins/players/wt/!unused/wistia.0.js +395 -0
  247. data/assets/theme/j1/modules/videojs/plugins/players/wt/!unused/wistia.1.js +401 -0
  248. data/assets/theme/j1/modules/videojs/{js/plugins/players/wt → plugins/players/wt/js}/wistia.js +13 -11
  249. data/assets/theme/j1/modules/videojs/plugins/players/wt/js/wistia.min.js +21 -0
  250. data/assets/theme/j1/modules/videojs/{js/plugins/players/yt → plugins/players/yt/js}/youtube.js +10 -8
  251. data/assets/theme/j1/modules/videojs/plugins/players/yt/js/youtube.min.js +21 -0
  252. data/lib/j1/version.rb +1 -1
  253. data/lib/starter_web/README.md +5 -5
  254. data/lib/starter_web/_config.yml +1 -1
  255. data/lib/starter_web/_data/modules/amplitude_playlists.yml +140 -80
  256. data/lib/starter_web/_data/modules/defaults/amplitude.yml +5 -3
  257. data/lib/starter_web/_data/modules/defaults/gallery.yml +3 -3
  258. data/lib/starter_web/_data/modules/gallery.yml +83 -87
  259. data/lib/starter_web/_data/modules/navigator_menu.yml +3 -3
  260. data/lib/starter_web/_data/resources.yml +16 -12
  261. data/lib/starter_web/_data/templates/feed.xml +1 -1
  262. data/lib/starter_web/_plugins/asciidoctor/videojs-block.rb +50 -22
  263. data/lib/starter_web/_plugins/asciidoctor/youtube-block.rb +37 -16
  264. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  265. data/lib/starter_web/assets/audio/album/emancipator/Alligator.mp3 +0 -0
  266. data/lib/starter_web/assets/audio/album/emancipator/DabCity.mp3 +0 -0
  267. data/lib/starter_web/assets/audio/album/emancipator/SeaToSky.mp3 +0 -0
  268. data/lib/starter_web/assets/audio/album/emancipator/TimeForSpace.mp3 +0 -0
  269. data/lib/starter_web/assets/audio/cover/emancipator/alligator.jpg +0 -0
  270. data/lib/starter_web/assets/audio/cover/emancipator/anthem.jpg +0 -0
  271. data/lib/starter_web/assets/audio/cover/emancipator/dab-city.jpg +0 -0
  272. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn.jpg +0 -0
  273. data/lib/starter_web/assets/audio/cover/emancipator/safe-in-the-steep-cliffs.jpg +0 -0
  274. data/lib/starter_web/assets/audio/cover/emancipator/sea-to-sky.jpg +0 -0
  275. data/lib/starter_web/assets/audio/cover/emancipator/soon-it-will-be-cold-enough.jpg +0 -0
  276. data/lib/starter_web/assets/audio/cover/emancipator/tine-for-space.jpg +0 -0
  277. data/lib/starter_web/assets/video/poster/vimeo/fall_2011.jpg +0 -0
  278. data/lib/starter_web/package.json +1 -1
  279. data/lib/starter_web/pages/public/tools/tester/videojs_macro_tester.adoc +282 -0
  280. data/lib/starter_web/pages/public/tour/audio_data.adoc +11 -6
  281. data/lib/starter_web/pages/public/tour/video_data.adoc +1 -0
  282. metadata +238 -115
  283. data/assets/data/swiper_app.2.html +0 -757
  284. data/assets/data/swiper_app.4.html +0 -769
  285. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.0.css +0 -32
  286. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.1.css +0 -31
  287. data/assets/theme/j1/modules/videojs/css/plugins/controls/zoom.min.css +0 -21
  288. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/dailymotion.min.js +0 -19
  289. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/vimeo.min.js +0 -16
  290. data/assets/theme/j1/modules/videojs/js/plugins/players/wt/api/src/WistiaPlayer.ts +0 -1617
  291. data/assets/theme/j1/modules/videojs/js/plugins/players/wt/wistia.min.js +0 -21
  292. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.min.js +0 -21
  293. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/anthem.jpg +0 -0
  294. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/from-dusk-to-dawn.jpg +0 -0
  295. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/safe-in-the-steep-cliffs.jpg +0 -0
  296. data/lib/starter_web/assets/audio/cover/emancipator/from-dusk-to-dawn/soon-it-will-be-cold-enough.jpg +0 -0
  297. data/lib/starter_web/assets/video/poster/vimeo/stay_colorful.jpg +0 -0
  298. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/animation-w.png +0 -0
  299. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/customize-w.png +0 -0
  300. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/dynamic-w.png +0 -0
  301. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/facebook-icon.svg +0 -0
  302. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/googleplus-icon.svg +0 -0
  303. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/html5-w.png +0 -0
  304. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/linked-in.png +0 -0
  305. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/module-w.png +0 -0
  306. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/play-button-hover.svg +0 -0
  307. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/play-button.png +0 -0
  308. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/play-button.svg +0 -0
  309. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/responsive-w.png +0 -0
  310. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/thumb-w.png +0 -0
  311. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/touch-w.png +0 -0
  312. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/twitter-icon.svg +0 -0
  313. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/twitter.png +0 -0
  314. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/video1-w.png +0 -0
  315. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/zoom-w.png +0 -0
  316. /data/assets/theme/j1/modules/lightGallery/{css → !v2.7.2/css}/themes/uno/icons/zoom.png +0 -0
  317. /data/assets/theme/j1/modules/lightGallery/{js → !v2.7.2/js}/plugins/j1/j1-video.js +0 -0
  318. /data/assets/theme/j1/modules/lightGallery/{js → !v2.7.2/js}/plugins/j1/j1-video.min.js +0 -0
  319. /data/assets/theme/j1/modules/videoPlayer/dailymotion/js/{!readme → README.md} +0 -0
  320. /data/assets/theme/j1/modules/videoPlayer/tiktoc/{js/player.min.js → player.min.js} +0 -0
  321. /data/assets/theme/j1/modules/videoPlayer/vimeo/js/{!readme → README.md} +0 -0
  322. /data/assets/theme/j1/modules/videoPlayer/wistia/js/{!readme → README.md} +0 -0
  323. /data/assets/theme/j1/modules/videojs/{css → !v8.12.0/css}/font/video-js-cdn.css +0 -0
  324. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/autocaption/LICENSE +0 -0
  325. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/autocaption/README.md +0 -0
  326. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/autocaption → plugins/controls/autocaption/js}/autocaption.min.js +0 -0
  327. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/hotkeys/examples → plugins/controls/hotkeys/!examples}/example.html +0 -0
  328. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/hotkeys/LICENSE.md +0 -0
  329. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/hotkeys/README.md +0 -0
  330. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/hotkeys → plugins/controls/hotkeys/js}/hotkeys.js +0 -0
  331. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/hotkeys → plugins/controls/hotkeys/js}/hotkeys.min.js +0 -0
  332. /data/assets/theme/j1/modules/videojs/{css/plugins/controls → plugins/controls/skipbuttons/css}/skipbuttons.css +0 -0
  333. /data/assets/theme/j1/modules/videojs/{css/plugins/controls → plugins/controls/skipbuttons/css}/skipbuttons.min.css +0 -0
  334. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/skipbuttons → plugins/controls/skipbuttons/js}/skipbuttons.js +0 -0
  335. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/skipbuttons → plugins/controls/skipbuttons/js}/skipbuttons.min.js +0 -0
  336. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/zoom/examples → plugins/controls/zoom/!examples}/index.html +0 -0
  337. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/zoom/examples → plugins/controls/zoom/!examples}/index.js +0 -0
  338. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/zoom/examples → plugins/controls/zoom/!examples}/styles.css +0 -0
  339. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/zoom/LICENSE.md +0 -0
  340. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/controls/zoom/README.md +0 -0
  341. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/zoom → plugins/controls/zoom/js}/zoom.js +0 -0
  342. /data/assets/theme/j1/modules/videojs/{js/plugins/controls/zoom → plugins/controls/zoom/js}/zoom.min.js +0 -0
  343. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/examples → plugins/players/dm/!examples}/dailymotion-controls.html +0 -0
  344. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/examples → plugins/players/dm/!examples}/dailymotion-javascript.html +0 -0
  345. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/examples → plugins/players/dm/!examples}/dailymotion-playlist.html +0 -0
  346. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/examples → plugins/players/dm/!examples}/global-parameters.html +0 -0
  347. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/examples → plugins/players/dm/!examples}/simple.html +0 -0
  348. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/examples → plugins/players/dm/!examples}/switch.html +0 -0
  349. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/dm/LICENSE +0 -0
  350. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/doc → plugins/players/dm}/README.md +0 -0
  351. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/dm/api/LICENSE +0 -0
  352. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/api/doc → plugins/players/dm/api}/README.md +0 -0
  353. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/api → plugins/players/dm/api/js}/dailymotion.sdk.js +0 -0
  354. /data/assets/theme/j1/modules/videojs/{js/plugins/players/dm/api → plugins/players/dm/api/js}/dailymotion.sdk.min.js +0 -0
  355. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/dm/icon/scalable/dailymotion.svg +0 -0
  356. /data/assets/theme/j1/modules/videojs/{js/plugins/players/vm/examples → plugins/players/vm/!examples}/index.html +0 -0
  357. /data/assets/theme/j1/modules/videojs/{js/plugins/players/vm/examples → plugins/players/vm/!examples}/player/index.html +0 -0
  358. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/vm/LICENSE +0 -0
  359. /data/assets/theme/j1/modules/videojs/{js/plugins/players/vm/doc → plugins/players/vm}/README.md +0 -0
  360. /data/assets/theme/j1/modules/videojs/{js/plugins/players/vm/api/doc → plugins/players/vm/api}/README.md +0 -0
  361. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/vm/api/css/embed.player.css +0 -0
  362. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/vm/api/css/embed.player.uno.css +0 -0
  363. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/vm/api/css/player.css +0 -0
  364. /data/assets/theme/j1/modules/videojs/{js/plugins/players/wt/doc → plugins/players/wt}/README.md +0 -0
  365. /data/assets/theme/j1/modules/videojs/{js/plugins/players/wt/api/doc/Readme.txt → plugins/players/wt/api/README.md} +0 -0
  366. /data/assets/theme/j1/modules/videojs/{js/plugins/players/wt/api → plugins/players/wt/api/js}/wistia.min.js +0 -0
  367. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/global-parameters.html +0 -0
  368. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/simple.html +0 -0
  369. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/switch.html +0 -0
  370. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/youtube-controls.html +0 -0
  371. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/youtube-javascript.html +0 -0
  372. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/youtube-list.html +0 -0
  373. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/examples → plugins/players/yt/!examples}/youtube-playlist.html +0 -0
  374. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/v3.0.0 → plugins/players/yt/!v3.0.0}/youtube.js +0 -0
  375. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/v3.0.0 → plugins/players/yt/!v3.0.0}/youtube.min.js +0 -0
  376. /data/assets/theme/j1/modules/videojs/{js/plugins → plugins}/players/yt/LICENSE +0 -0
  377. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/doc → plugins/players/yt}/README.md +0 -0
  378. /data/assets/theme/j1/modules/videojs/{js/plugins/players/yt/api → plugins/players/yt/api/js}/youtube.min.js +0 -0
  379. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn → !info}/!sound.links.txt +0 -0
  380. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/Anthem.mp3 → Anthem.mp3} +0 -0
  381. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/DuskToDawn.mp3 → DuskToDawn.mp3} +0 -0
  382. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/FirstSnow.mp3 → FirstSnow.mp3} +0 -0
  383. /data/lib/starter_web/assets/audio/album/emancipator/{from-dusk-to-dawn/SafeInTheSteepCliffs.mp3 → SafeInTheSteepCliffs.mp3} +0 -0
@@ -6,7 +6,7 @@ regenerate: true
6
6
 
7
7
  {% comment %}
8
8
  # -----------------------------------------------------------------------------
9
- # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.31.js
9
+ # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.35.js
10
10
  # AmplitudeJS V5 Tech for J1 Template
11
11
  #
12
12
  # Product/Info:
@@ -60,7 +60,7 @@ regenerate: true
60
60
 
61
61
  /*
62
62
  # -----------------------------------------------------------------------------
63
- # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.31.js
63
+ # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.35.js
64
64
  # AmplitudeJS V5 Plugin|Tech for J1 Template
65
65
  #
66
66
  # Product/Info:
@@ -74,6 +74,8 @@ regenerate: true
74
74
  */
75
75
  "use strict";
76
76
 
77
+ const isDev = (j1.env === "development" || j1.env === "dev") ? true : false;
78
+
77
79
  // date|time monitoring
78
80
  //----------------------------------------------------------------------------
79
81
  var startTime;
@@ -84,6 +86,21 @@ regenerate: true
84
86
 
85
87
  // YT API settings
86
88
  // ---------------------------------------------------------------------------
89
+
90
+ var YT_PLAYER_ERROR = {
91
+ INVALID_PARAMETER: 2,
92
+ INVALID_PLAYER: 5,
93
+ VIDEO_NOT_ALLOWED: 101,
94
+ VIDEO_NOT_ALLOWED: 150
95
+ };
96
+
97
+ var YT_PLAYER_ERROR_NAMES = {
98
+ 2: "invalid parameter",
99
+ 5: "invalid player",
100
+ 101: "video not allowed",
101
+ 150: "video not allowed"
102
+ };
103
+
87
104
  var YT_PLAYER_STATE = {
88
105
  UNSTARTED: -1,
89
106
  ENDED: 0,
@@ -115,6 +132,7 @@ regenerate: true
115
132
  // ---------------------------------------------------------------------------
116
133
  var firstScriptTag;
117
134
  var ytPlayer;
135
+ var ytPlayerErrorTest = false;
118
136
  var ytPlayerReady = false;
119
137
  var ytApiReady = false;
120
138
  var logger = log4javascript.getLogger('j1.adapter.amplitude.tech');
@@ -161,10 +179,7 @@ regenerate: true
161
179
  var playerType;
162
180
  var playListTitle;
163
181
  var playListName;
164
- var amplitudePlayerState;
165
-
166
- var ytPlayer;
167
-
182
+ var amplitudePlayerState;
168
183
 
169
184
  var songs;
170
185
  var songMetaData;
@@ -211,7 +226,7 @@ regenerate: true
211
226
  // fade-in audio (if enabled)
212
227
  if (playerFadeAudio) {
213
228
  currentVolume = player.getVolume();
214
- logger.debug('\n' + `FADE-IN audio on StateChange at trackID|VideoID: ${trackID}|${videoID}`);
229
+ logger.debug(`FADE-IN audio on StateChange at trackID|VideoID: ${trackID}|${videoID}`);
215
230
  ytpFadeInAudio({
216
231
  playerID: playerID,
217
232
  targetVolume: currentVolume,
@@ -227,10 +242,12 @@ regenerate: true
227
242
  // TODO:
228
243
  // ---------------------------------------------------------------------------
229
244
  function processOnVideoEnd(player) {
230
- var currentVideoTime,
231
- playlist, playerID, songIndex, songs,
245
+ var currentVideoTime, activeSong,
246
+ playlist, playerID, songIndex, songs, playlistRepeat,
232
247
  trackID, activeVideoID, previousVideoID, isVideoChanged;
233
248
 
249
+ activeSong = getActiveSong();
250
+
234
251
  playlist = activeVideoElement.playlist;
235
252
  playerID = playlist + '_large';
236
253
  currentVideoTime = player.getCurrentTime();
@@ -239,6 +256,7 @@ regenerate: true
239
256
  songIndex = activeVideoElement.index;
240
257
  trackID = songIndex + 1;
241
258
  songs = activeVideoElement.songs;
259
+ playlistRepeat = (songs[songIndex].repeat === 'true') ? true : false;
242
260
 
243
261
  // check if video is changed (to detect multiple videoIDs in playlist)
244
262
  if (songIndex > 0) {
@@ -249,21 +267,34 @@ regenerate: true
249
267
 
250
268
  // fade-out audio (if enabled)
251
269
  if (isVideoChanged && playerFadeAudio) {
252
- logger.debug('\n' + `FADE-OUT audio on processOnVideoEnd at trackID|VideoID: ${trackID}|${activeVideoID}`);
270
+ logger.debug(`FADE-OUT audio on processOnVideoEnd at trackID|VideoID: ${trackID}|${activeVideoID}`);
253
271
  ytpFadeOutAudio({
254
272
  playerID: playerID,
255
273
  speed: 'default'
256
274
  });
257
275
  } // END if playerFadeAudio
258
276
 
259
- // if (!activeVideoElement.audio_single) {
260
277
  if (isVideoChanged) {
261
- // load next video
262
- logger.debug('\n' + `LOAD next VIDEO on processOnVideoEnd at trackID|playlist: ${trackID}|${playlist}`);
263
- loadNextVideo(playlist, songIndex);
278
+ if (songIndex === songs.length - 1) {
279
+ // LAST index reached, continue on FIRST index
280
+ songIndex = 0;
281
+
282
+ logger.debug(`LOAD first VIDEO on processOnVideoEnd at trackID|playlist: ${trackID}|${playlist}`);
283
+ loadVideo(playlist, songIndex);
284
+
285
+ // check if REPEAT is enabled on PLAYLIST
286
+ if (!playlistRepeat) {
287
+ // set FIRST song (video) paused if playing is continued
288
+ ytPlayer.pauseVideo();
289
+ }
290
+ } else {
291
+ // load next video
292
+ logger.debug(`LOAD next VIDEO on processOnVideoEnd at trackID|playlist: ${trackID}|${playlist}`);
293
+ loadVideo(playlist, songIndex + 1);
294
+ }
264
295
  } else {
265
- // skip loading next video if a single video is used for playlist
266
- logger.debug('\n' + `LOAD next TRACK in video on processOnVideoEnd at trackID|playlist: ${trackID}|${playlist}`);
296
+ // skip loading next video if a SINGLE video is used for playlist
297
+ logger.debug(`LOAD next TRACK in video on processOnVideoEnd at trackID|playlist: ${trackID}|${playlist}`);
267
298
  }
268
299
 
269
300
  } // END processOnVideoEnd
@@ -275,45 +306,57 @@ regenerate: true
275
306
  // ---------------------------------------------------------------------------
276
307
  function doNothingOnStateChange(state) {
277
308
  if (state > 0) {
278
- logger.warn('\n' + `DO NOTHING on StateChange for state: ${YT_PLAYER_STATE_NAMES[state]}`);
309
+ isDev && logger.warn(`DO NOTHING on StateChange for state: ${YT_PLAYER_STATE_NAMES[state]}`);
279
310
  } else {
280
- logger.warn('\n' + `DO NOTHING on StateChange for state: ${YT_PLAYER_STATE_NAMES[6]}`);
311
+ isDev && logger.warn(`DO NOTHING on StateChange for state: ${YT_PLAYER_STATE_NAMES[6]}`);
281
312
  }
282
313
  } // END doNothingOnStateChange
283
314
 
284
315
  // ---------------------------------------------------------------------------
285
316
  // processOnStateChangePlaying()
286
317
  //
287
- // wrraper for processing on stae PLAYING
318
+ // wrapper for processing players on state PLAYING
288
319
  // ---------------------------------------------------------------------------
289
320
  function processOnStateChangePlaying(event, playlist, songIndex) {
290
- var activeSong, playlist, playerID, videoID,
291
- ytPlayer, songs, songIndex,
292
- currentPlayer, previousPlayer, trackID;
293
-
294
- ytPlayer = event.target;
321
+ var activeSong, activePlaylist,
322
+ playerID, videoID, firstVideo,
323
+ ytPlayer, songs, songIndex, previousSongIndex,
324
+ currentPlayer, previousPlayer,
325
+ trackID, isSongIndexChanged;
295
326
 
296
- // update active song settings (manually)
297
- checkActiveVideoElementYTP();
327
+ ytPlayer = event.target;
328
+ firstVideo = (songIndex > 0) ? false : true;
298
329
 
299
- // get active song settings (manually)
300
- activeSong = getActiveSong();
301
-
302
- playlist = activeSong.playlist;
330
+ activeSong = getActiveSong();
331
+ activePlaylist = playlist;
303
332
  playerID = activeSong.playerID;
304
333
  videoID = activeSong.videoID;
305
334
  songs = activeSong.songs;
306
335
  songIndex = activeSong.index;
307
336
  currentPlayer = activeSong.player;
308
337
  previousPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player
338
+ trackID = songIndex + 1;
339
+
340
+ logger.debug(`PLAY audio on YT Player at playlist|trackID: ${activePlaylist}|${trackID}`);
309
341
 
310
342
  // save YT player GLOBAL data for later use (e.g. events)
311
343
  j1.adapter.amplitude.data.activePlayer = 'ytp';
312
344
  j1.adapter.amplitude.data.ytpGlobals['activeIndex'] = songIndex;
313
345
  j1.adapter.amplitude.data.ytpGlobals['videoID'] = videoID;
314
346
 
347
+
315
348
  // save YT player data for later use (e.g. events)
316
- j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
349
+ // -------------------------------------------------------------------------
350
+ j1.modules.amplitudejs.data.activePlayer = 'ytp';
351
+ j1.modules.amplitudejs.data.activeIndex = songIndex;
352
+ j1.modules.amplitudejs.data.activePlaylist = playlist;
353
+ j1.modules.amplitudejs.data.ytp.activePlayer = ytPlayer;
354
+ j1.modules.amplitudejs.data.ytp.activeIndex = songIndex;
355
+ j1.modules.amplitudejs.data.ytp.activePlaylist = playlist;
356
+ j1.modules.amplitudejs.data.ytp.players[playerID].activeIndex = songIndex;
357
+ j1.modules.amplitudejs.data.ytp.players[playerID].player = ytPlayer;
358
+ j1.modules.amplitudejs.data.ytp.players[playerID].videoID = videoID;
359
+
317
360
 
318
361
  // update time container for the ACTIVE video
319
362
  // -----------------------------------------------------------------
@@ -327,18 +370,18 @@ regenerate: true
327
370
  updateProgressBarsYTP();
328
371
  }, 500);
329
372
 
330
- trackID = songIndex + 1;
331
- logger.debug('\n' + `PLAY video on StateChange at trackID|VideoID: ${trackID}|${videoID}`);
373
+ // update meta data
374
+ ytpUpdatMetaContainers(activeSong);
332
375
 
333
376
  // check|process video for configured START position (if set)
334
377
  // -------------------------------------------------------------------------
335
378
  var songStartSec = activeSong.startSec;
336
379
  if (songStartSec) {
337
- var tsStartSec = seconds2timestamp(songStartSec);
380
+ var tsStartSec = j1.adapter.amplitude.seconds2timestamp(songStartSec);
338
381
  var songCurrentTime = ytPlayer.getCurrentTime();
339
382
 
340
383
  if (songCurrentTime < songStartSec) {
341
- logger.debug('\n' + `START video on StateChange at trackID|timestamp: ${trackID}|${tsStartSec}`);
384
+ logger.debug(`START video on StateChange at trackID|timestamp: ${trackID}|${tsStartSec}`);
342
385
  processOnVideoStart(ytPlayer, songStartSec);
343
386
  }
344
387
  } // END if songStartEnabled
@@ -347,13 +390,13 @@ regenerate: true
347
390
  // -------------------------------------------------------------------------
348
391
  var songEndSec = activeSong.endSec;
349
392
  if (songEndSec) {
350
- var tsEndSec = seconds2timestamp(songEndSec);
393
+ var tsEndSec = j1.adapter.amplitude.seconds2timestamp(songEndSec);
351
394
 
352
395
  var checkOnVideoEnd = setInterval(function() {
353
396
  var songCurrentTime = ytPlayer.getCurrentTime();
354
397
 
355
398
  if (songCurrentTime >= songEndSec) {
356
- logger.debug('\n' + `STOP video on StateChange at trackID|timestamp: ${trackID}|${tsEndSec}`);
399
+ logger.debug(`STOP video on StateChange at trackID|timestamp: ${trackID}|${tsEndSec}`);
357
400
  processOnVideoEnd(ytPlayer);
358
401
 
359
402
  clearInterval(checkOnVideoEnd);
@@ -361,83 +404,99 @@ regenerate: true
361
404
  }, 500); // END checkOnVideoEnd
362
405
  } // END if songEndEnabled
363
406
 
364
- // stop active AT players running in parallel
365
- // -------------------------------------------------------------------------
366
- var atpPlayerState = Amplitude.getPlayerState();
367
- if (atpPlayerState === 'playing') {
368
- Amplitude.stop();
407
+ // stop active AT|YT players running in parallel except the current
408
+ ytpStopParallelActivePlayers(playerID);
369
409
 
370
- // clear button MINI PlayerPlayPause (AT player)
371
- var buttonPlayerPlayPauseMini = document.getElementsByClassName("mini-player-play-pause");
372
- for (var i=0; i<buttonPlayerPlayPauseMini.length; i++) {
373
- var htmlElement = buttonPlayerPlayPauseMini[i];
374
-
375
- if (htmlElement.dataset.amplitudeSource === 'audio') {
410
+ // clear button MINI PlayerPlayPause (AT player)
411
+ var buttonPlayerPlayPauseMini = document.getElementsByClassName("mini-player-play-pause");
412
+ for (var i=0; i<buttonPlayerPlayPauseMini.length; i++) {
413
+ var htmlElement = buttonPlayerPlayPauseMini[i];
414
+
415
+ // toggle classes on state playing
416
+ if (htmlElement.dataset.amplitudeSource === 'audio') {
417
+ if (htmlElement.classList.contains('amplitude-playing')) {
376
418
  htmlElement.classList.remove('amplitude-playing');
377
419
  htmlElement.classList.add('amplitude-paused');
378
420
  }
379
-
380
- } // END for MINI buttonPlayerPlayPause
381
-
382
- // clear button COMPACT PlayerPlayPause (AT player)
383
- var buttonPlayerPlayPauseCompact = document.getElementsByClassName("compact-player-play-pause");
384
- for (var i=0; i<buttonPlayerPlayPauseCompact.length; i++) {
385
- var htmlElement = buttonPlayerPlayPauseCompact[i];
386
-
387
- if (htmlElement.dataset.amplitudeSource === 'audio') {
421
+ }
422
+
423
+ } // END for MINI buttonPlayerPlayPause
424
+
425
+ // clear button COMPACT PlayerPlayPause (AT player)
426
+ var buttonPlayerPlayPauseCompact = document.getElementsByClassName("compact-player-play-pause");
427
+ for (var i=0; i<buttonPlayerPlayPauseCompact.length; i++) {
428
+ var htmlElement = buttonPlayerPlayPauseCompact[i];
429
+
430
+ // toggle classes on state playing
431
+ if (htmlElement.dataset.amplitudeSource === 'audio') {
432
+ if (htmlElement.classList.contains('amplitude-playing')) {
388
433
  htmlElement.classList.remove('amplitude-playing');
389
434
  htmlElement.classList.add('amplitude-paused');
390
435
  }
391
-
392
- } // END for COMACT buttonPlayerPlayPause
436
+ }
437
+
438
+ } // END for COMACT buttonPlayerPlayPause
393
439
 
394
- // clear button LARGE PlayerPlayPause (AT player)
395
- var buttonPlayerPlayPauseLarge = document.getElementsByClassName("large-player-play-pause");
396
- for (var i=0; i<buttonPlayerPlayPauseLarge.length; i++) {
397
- var htmlElement = buttonPlayerPlayPauseLarge[i];
398
-
399
- if (htmlElement.dataset.amplitudeSource === 'audio') {
440
+ // clear button LARGE PlayerPlayPause (AT player)
441
+ var buttonPlayerPlayPauseLarge = document.getElementsByClassName("large-player-play-pause");
442
+ for (var i=0; i<buttonPlayerPlayPauseLarge.length; i++) {
443
+ var htmlElement = buttonPlayerPlayPauseLarge[i];
444
+
445
+ // toggle classes on state playing
446
+ if (htmlElement.dataset.amplitudeSource === 'audio') {
447
+ if (htmlElement.classList.contains('amplitude-playing')) {
400
448
  htmlElement.classList.remove('amplitude-playing');
401
449
  htmlElement.classList.add('amplitude-paused');
402
450
  }
451
+ }
403
452
 
404
- } // END for LARGE buttonPlayerPlayPause
405
-
406
- } // END if atpPlayerState 'playing'
407
-
408
- // TODO: check if YT player stop is needed
409
- // -------------------------------------------------------------------------
410
- // stop active YT players running in parallel except the current
411
- // if (previousPlayer.options.videoId !== videoID) {
412
- // logger.debug('\n' + `STOP all video on StateChange running in parallel at trackID|playerID: ${trackID}|${playerID}`);
413
- // var playerState = (previousPlayer.getPlayerState() > 0) ? previousPlayer.getPlayerState() : 6;
414
- // var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
415
- //
416
- // if (ytPlayerState === 'playing' || ytPlayerState === 'paused') {
417
- // previousPlayer.stopVideo();
418
- // }
419
- // }
420
- //
421
- // stopAllActivePlayers(playerID);
453
+ } // END for LARGE buttonPlayerPlayPause
422
454
 
423
455
  } // END processOnStateChangePlaying
424
456
 
425
-
426
457
  // ---------------------------------------------------------------------------
427
458
  // processOnStateChangeEnded()
428
459
  //
429
460
  // ---------------------------------------------------------------------------
430
461
  function processOnStateChangeEnded(event, playlist, songIndex) {
431
- var videoID = event.target.options.videoId;
432
- var trackID = songIndex + 1;
462
+ var videoID = event.target.options.videoId;
463
+ var trackID = songIndex + 1;
464
+ var playerID = playlist + '_large';
465
+ var songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
466
+ var songMetaData = songs[songIndex];
467
+ var playlistRepeat = (songMetaData.repeat === 'true') ? true : false;
468
+
469
+ if (songIndex === songs.length - 1) {
470
+ // LAST index reached, continue on FIRST index
471
+ songIndex = 0;
472
+
473
+ // save player current time data for later use
474
+ // ytPlayerCurrentTime = ytPlayer.getCurrentTime();
433
475
 
434
- // save player current time data for later use
435
- ytPlayerCurrentTime = ytPlayer.getCurrentTime();
476
+ // save YT player data for later use (e.g. events)
477
+ // ---------------------------------------------------------------------
478
+ j1.modules.amplitudejs.data.ytp.previousIndex = songIndex;
479
+
480
+ logger.debug(`LOAD first VIDEO on processOnStateChangeEnded at trackID|playlist: ${trackID}|${playlist}`);
481
+ loadVideo(playlist, songIndex);
482
+
483
+ // check if REPEAT is enabled on PLAYLIST
484
+ if (!playlistRepeat) {
485
+ // set FIRST song (video) paused if playing is continued
486
+ ytPlayer.pauseVideo();
487
+ }
488
+ } else {
489
+ // save player current time data for later use
490
+ // ytPlayerCurrentTime = ytPlayer.getCurrentTime();
436
491
 
437
- logger.debug('\n' + `NEXT video on StateChange at trackID|VideoID: ${trackID}|${videoID}`);
492
+ // save YT player data for later use (e.g. events)
493
+ // ---------------------------------------------------------------------
494
+ j1.modules.amplitudejs.data.ytp.previousIndex = songIndex;
438
495
 
439
- // load NEXT song (video) in playlist
440
- loadNextVideo(playlist, songIndex);
496
+ // load next video
497
+ logger.debug(`LOAD next VIDEO on processOnStateChangeEnded at trackID|playlist: ${trackID}|${playlist}`);
498
+ loadVideo(playlist, songIndex + 1);
499
+ }
441
500
 
442
501
  } // END processOnStateChangeEnded
443
502
 
@@ -521,50 +580,6 @@ regenerate: true
521
580
  current[lastKey] = value;
522
581
  }
523
582
 
524
- // ---------------------------------------------------------------------------
525
- // timestamp2seconds
526
- // ---------------------------------------------------------------------------
527
- function timestamp2seconds(timestamp) {
528
- // split timestamp
529
- const parts = timestamp.split(':');
530
-
531
- // check timestamp format
532
- if (parts.length !== 3) {
533
- // return "invalid timestamp";
534
- return false;
535
- }
536
-
537
- // convert parts to integers
538
- const hours = parseInt(parts[0], 10);
539
- const minutes = parseInt(parts[1], 10);
540
- const seconds = parseInt(parts[2], 10);
541
-
542
- // check valid timestamp values
543
- if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) ||
544
- hours < 0 || hours > 23 ||
545
- minutes < 0 || minutes > 59 ||
546
- seconds < 0 || seconds > 59) {
547
- return "invalid timestamp";
548
- }
549
-
550
- const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
551
- return totalSeconds;
552
- } // END timestamp2seconds
553
-
554
- // ---------------------------------------------------------------------------
555
- // seconds2timestamp
556
- // ---------------------------------------------------------------------------
557
- function seconds2timestamp(seconds) {
558
- const hours = Math.floor(seconds / 3600);
559
- const minutes = Math.floor((seconds % 3600) / 60);
560
- const remainSeconds = seconds % 60;
561
- const tsHours = hours.toString().padStart(2, '0');
562
- const tsMinutes = minutes.toString().padStart(2, '0');
563
- const tsSeconds = remainSeconds.toString().padStart(2, '0');
564
-
565
- return `${tsHours}:${tsMinutes}:${tsSeconds}`;
566
- } // END seconds2timestamp
567
-
568
583
  // ---------------------------------------------------------------------------
569
584
  // ytpFadeInAudio
570
585
  // ---------------------------------------------------------------------------
@@ -584,7 +599,7 @@ regenerate: true
584
599
  // transition will be
585
600
  const iterationSteps = {
586
601
  'default': 150,
587
- 'slow': 250,
602
+ 'slow': 250,
588
603
  'slower': 350,
589
604
  'slowest': 500
590
605
  };
@@ -595,18 +610,10 @@ regenerate: true
595
610
  currentStep = 1;
596
611
 
597
612
  if (volumeSlider === undefined || volumeSlider === null) {
598
- logger.warn('\n' + 'no volume slider found at playerID: ' + settings.playerID);
613
+ isDev && logger.warn('no volume slider found at playerID: ' + settings.playerID);
599
614
  return;
600
615
  }
601
616
 
602
- // (ytPlayer.isMuted()) && ytPlayer.unMute();
603
-
604
- // skip fade-in when volume is already at target value
605
- // if (ytPlayer.getVolume() >= targetVolume) {
606
- // logger.warn('\n' + 'skipped fade-in for current video on volume: ', targetVolume);
607
- // return;
608
- // }
609
-
610
617
  // Start the players volume muted
611
618
  ytPlayer.setVolume(0);
612
619
 
@@ -639,7 +646,7 @@ regenerate: true
639
646
  // number of iteration steps to DECREASE the volume
640
647
  const iterationSteps = {
641
648
  'default': 150,
642
- 'slow': 250,
649
+ 'slow': 250,
643
650
  'slower': 350,
644
651
  'slowest': 500
645
652
  };
@@ -651,7 +658,7 @@ regenerate: true
651
658
  currentStep = 0;
652
659
 
653
660
  if (volumeSlider === undefined || volumeSlider === null) {
654
- logger.warn('\n' + 'no volume slider found at playerID: ' + settings.playerID);
661
+ isDev && logger.warn('no volume slider found at playerID: ' + settings.playerID);
655
662
  return;
656
663
  }
657
664
 
@@ -675,7 +682,7 @@ regenerate: true
675
682
  function initYtAPI() {
676
683
  startTimeModule = Date.now();
677
684
 
678
- logger.info('\n' + 'Initialize plugin|tech (ytp) : started');
685
+ logger.info('Initialize plugin|tech (ytp) : started');
679
686
 
680
687
  // Load YT IFrame Player API asynchronously
681
688
  // -------------------------------------------------------------------------
@@ -687,46 +694,47 @@ regenerate: true
687
694
  }
688
695
 
689
696
  // ---------------------------------------------------------------------------
690
- // loadNextVideo(list, index)
697
+ // loadVideo(list, index)
691
698
  //
692
699
  // load next video in playlist
693
700
  // ---------------------------------------------------------------------------
694
- function loadNextVideo(currentPlaylist, currentIndex) {
695
- var activeSongSettings, trackID, songName, playlist, playerID, playerIFrame,
696
- songs, songIndex, songMetaData, songURL, ytpVideoID;
697
-
698
- // update active song settings (manually)
699
- checkActiveVideoElementYTP();
700
-
701
- // get active song settings (manually)
702
- activeSongSettings = getActiveSong();
703
-
704
- playlist = currentPlaylist;
705
- playerID = playlist + '_large';
706
- songs = activeSongSettings.songs;
707
- ytPlayer = activeSongSettings.player;
708
- songIndex = currentIndex;
709
- trackID = songIndex + 1;
710
-
711
- songIndex++;
701
+ function loadVideo(currentPlaylist, currentIndex) {
702
+ var activeSong, trackID, songName,
703
+ playlist, playerID, playerIFrame,
704
+ songs, songIndex, songMetaData, songURL,
705
+ ytpVideoID, firstVideo, playlistRepeat;
712
706
 
713
- ytpSongIndex = songIndex;
707
+ activeSong = getActiveSong();
708
+ playlist = currentPlaylist;
709
+ playerID = playlist + '_large';
710
+ songs = activeSong.songs;
711
+ playlistRepeat = (songs[currentIndex].repeat === 'true') ? true : false;
712
+ ytPlayer = activeSong.player;
713
+ songIndex = currentIndex;
714
+ trackID = songIndex + 1;
714
715
 
715
-
716
- // play sonng (video) in playlist
716
+ // switch|play to songIndex in playlist
717
717
  if (songIndex <= songs.length - 1) {
718
718
  songMetaData = songs[songIndex];
719
719
  songURL = songMetaData.url;
720
- ytVideoID = songURL.split('=')[1];
720
+ ytpVideoID = songURL.split('=')[1];
721
721
 
722
722
  // save YT player data for later use (e.g. events)
723
723
  j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
724
- j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytVideoID;
724
+ j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
725
725
 
726
726
 
727
- logger.debug('\n' + `SWITCH video on loadNextVideo at trackID|VideoID: ${trackID}|${ytVideoID}`);
728
- ytPlayer.loadVideoById(ytVideoID);
727
+ // save YT player data for later use (e.g. events)
728
+ // -----------------------------------------------------------------------
729
+ j1.modules.amplitudejs.data.ytp.previousSongIndex = songIndex;
730
+ j1.modules.amplitudejs.data.ytp.players[playerID].activeIndex = songIndex;
731
+ j1.modules.amplitudejs.data.ytp.players[playerID].previousIndex = songIndex - 1;
732
+ j1.modules.amplitudejs.data.ytp.players[playerID].videoID = ytpVideoID;
729
733
 
734
+
735
+ logger.debug(`SWITCH video on loadNextVideo at trackID|VideoID: ${trackID}|${ytpVideoID}`);
736
+ ytPlayer.loadVideoById(ytpVideoID);
737
+
730
738
  // delay after switch video
731
739
  if (muteAfterVideoSwitchInterval) {
732
740
  ytPlayer.mute();
@@ -735,14 +743,16 @@ regenerate: true
735
743
  }, muteAfterVideoSwitchInterval);
736
744
  }
737
745
 
738
- // update global song index
746
+ // save YT player data for later use (e.g. events)
747
+ // -----------------------------------------------------------------------
739
748
  ytpSongIndex = songIndex;
749
+ j1.modules.amplitudejs.data.ytp.songIndex = songIndex;
740
750
 
741
751
  // load the song cover image
742
752
  loadCoverImage(songMetaData);
743
753
 
744
754
  // update meta data
745
- updatMetaContainers(songMetaData);
755
+ // ytpUpdatMetaContainers(songMetaData);
746
756
 
747
757
  // set song (video) active at index in playlist
748
758
  setSongActive(playlist, songIndex);
@@ -754,62 +764,10 @@ regenerate: true
754
764
  if (playerAutoScrollSongElement) {
755
765
  scrollToActiveElement(playlist);
756
766
  }
757
- } else {
758
- // continue on FIRST track (video) in playlist
759
- //
760
- songIndex = 0;
761
- var songMetaData = songs[songIndex];
762
- var songURL = songMetaData.url;
763
- var ytVideoID = songURL.split('=')[1];
764
-
765
- // update global song index
766
- ytpSongIndex = songIndex;
767
-
768
- // load next video (paused)
769
- // -----------------------------------------------------------------------
770
-
771
- // save YT player data for later use (e.g. events)
772
- j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
773
- j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
774
767
 
775
- logger.debug('\n' + `SWITCH video on loadNextVideo at trackID|VideoID: ${trackID}|${ytVideoID}`);
776
- ytPlayer.loadVideoById(ytVideoID);
768
+ } // END if songIndex
777
769
 
778
- // delay after switch video
779
- if (muteAfterVideoSwitchInterval) {
780
- ytPlayer.mute();
781
- setTimeout(() => {
782
- ytPlayer.unMute();
783
- }, muteAfterVideoSwitchInterval);
784
- }
785
-
786
- // load the song cover image
787
- loadCoverImage(songMetaData);
788
-
789
- // update meta data
790
- updatMetaContainers(songMetaData);
791
-
792
- // set AJS play_pause button paused
793
- var playPauseButtonClass = `large-player-play-pause-${playerID}`
794
- setPlayPauseButtonPaused(playPauseButtonClass);
795
-
796
- // set song (video) active at index in playlist
797
- setSongActive(playlist, songIndex);
798
-
799
- // reset progress bar settings
800
- resetProgressBarYTP();
801
-
802
- // scroll song active at index in player
803
- if (playerAutoScrollSongElement) {
804
- scrollToActiveElement(playlist);
805
- }
806
-
807
- // TODO: check if SHUFFLE is enabled on PLAYLIST (PLAYER ???)
808
- // set FIRST song (video) paused
809
- ytPlayer.pauseVideo();
810
- }
811
-
812
- } // END loadVideo
770
+ } // END loadNextVideo
813
771
 
814
772
  // ---------------------------------------------------------------------------
815
773
  // initUiEventsForAJS
@@ -840,7 +798,7 @@ regenerate: true
840
798
  {% endif %}{% endfor %}
841
799
 
842
800
  clearInterval(dependencies_ytp_ready);
843
- logger.info('\n' + 'Initialize APIPlayers : ready');
801
+ logger.info('Initialize APIPlayers : ready');
844
802
  } // END if ready
845
803
 
846
804
  }, 10); // END dependencies_ytp_ready
@@ -881,21 +839,21 @@ regenerate: true
881
839
 
882
840
  // load individual player settings (to manage multiple players in page)
883
841
  //
884
- var ytpVideoID = activeSongMetadata.url.split('=')[1];
885
842
  var ytpAutoPlay = ('{{player.yt_player.autoplay}}'.length > 0) ? '{{player.yt_player.autoplay}}' : '{{amplitude_defaults.player.yt_player.autoplay}}';
886
843
  var ytpLoop = ('{{player.yt_player.loop}}'.length > 0) ? '{{player.yt_player.loop}}' : '{{amplitude_defaults.player.yt_player.loop}}';
887
844
  var ytpHeight = ('{{player.yt_player.height}}'.length > 0) ? '{{player.yt_player.height}}' : '{{amplitude_defaults.player.yt_player.height}}';
888
845
  var ytpWidth = ('{{player.yt_player.width}}'.length > 0) ? '{{player.yt_player.width}}' : '{{amplitude_defaults.player.yt_player.width}}';
889
846
 
890
- logger.info('\n' + 'AJS YouTube iFrame API: ready');
891
- logger.info('\n' + 'configure player on ID: #{{player.id}}');
847
+ logger.info('AJS YouTube iFrame API: ready');
848
+ logger.info('configure player on ID: #{{player.id}}');
892
849
 
893
- // create a hidden YT Player iFrame container
850
+ // create a (hidden) ytp iframe container
894
851
  //
895
852
  ytpContainer = document.getElementById('{{player.id}}_video');
896
853
  ytpContainer.innerHTML = '<div id="iframe_{{player.id}}"></div>';
897
854
  ytpContainer.style.cssText = 'display:none';
898
855
 
856
+ var ytpVideoID = (ytPlayerErrorTest) ? 'invalidVideoID' : activeSongMetadata.url.split('=')[1];
899
857
  ytPlayer = new YT.Player('iframe_{{player.id}}', {
900
858
  height: ytpHeight,
901
859
  width: ytpWidth,
@@ -905,8 +863,9 @@ regenerate: true
905
863
  loop: ytpLoop
906
864
  },
907
865
  events: {
908
- 'onReady': {{player.id}}OnPlayerReady,
909
- 'onStateChange': {{player.id}}OnPlayerStateChange
866
+ 'onReady': {{player.id}}OnPlayerReady,
867
+ 'onStateChange': {{player.id}}OnPlayerStateChange,
868
+ 'onError': {{player.id}}OnPlayerErrors
910
869
  }
911
870
  });
912
871
 
@@ -931,25 +890,41 @@ regenerate: true
931
890
 
932
891
  // save YT player GLOBAL data for later use (e.g. events)
933
892
  j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] = ytApiReady;
934
-
893
+
894
+
895
+ // save amplitudejs data for later use (e.g. events)
896
+ // -------------------------------------------------------------------
897
+ j1.modules.amplitudejs.data.ytp.apiReady = ytApiReady;
898
+
899
+
935
900
  // reset current player
936
901
  playerExistsInPage = false;
937
902
 
938
903
  } // END if playerExistsInPage()
939
904
 
940
- function checkPlayingStatus(player) {
941
- if (player.getPlayerState() === YT_PLAYER_STATE.PLAYING) {
942
- // code run after video is playing
943
- // console.debug("checkPlayingStatus: AJS YouTube Player state: PLAYING");
944
- // do nothing
945
- return;
946
- } else {
947
- // re-check player state required
948
- // console.debug("checkPlayingStatus: AJS YouTube Player state:", player.getPlayerState());
949
- }
950
- } // END checkPlayingStatus
905
+ // AJS YouTube Player errors fired by the YT API
906
+ // ---------------------------------------------------------------------
907
+ function {{player.id}}OnPlayerErrors(event) {
908
+ var eventData, ytPlayer, videoID;
909
+
910
+ eventData = event.data;
911
+ ytPlayer = event.target;
912
+ videoID = ytPlayer.options.videoId;
913
+
914
+ logger.error(`YT API Error '${YT_PLAYER_ERROR_NAMES[eventData]}' for VideoID: '${videoID}'`);
915
+
916
+ // save YT player GLOBAL data for later use (e.g. events)
917
+ j1.adapter.amplitude.data.ytpGlobals['ytApiError'] = eventData;
918
+
919
+
920
+ // save amplitudejs data for later use (e.g. events)
921
+ // ------------------------------------------------------------------
922
+ j1.modules.amplitudejs.data.ytp.apiError = eventData;
951
923
 
952
- // run AJS YouTube Player initialization
924
+
925
+ }
926
+
927
+ // AJS YouTube Player initialization fired by the YT API
953
928
  // ---------------------------------------------------------------------
954
929
  function {{player.id}}OnPlayerReady(event) {
955
930
  var hours, minutes, seconds,
@@ -960,7 +935,7 @@ regenerate: true
960
935
  ytPlayerReady = true;
961
936
  playerVolumePreset = parseInt({{player.volume_slider.preset_value}});
962
937
 
963
- logger.debug('\n' + `FOUND video ready at ID: {{player.id}}`);
938
+ logger.debug(`FOUND video ready at ID: {{player.id}}`);
964
939
 
965
940
  // set video playback quality to a minimum
966
941
  ytPlayer.setPlaybackQuality('small');
@@ -985,13 +960,19 @@ regenerate: true
985
960
  }
986
961
  }
987
962
 
988
- logger.info('\n' + 'AJS YouTube Player on ID {{player.id}}: ready');
963
+ logger.info('yt player on ID {{player.id}}: ready');
989
964
 
990
965
  // save YT player GLOBAL data for later use (e.g. events)
991
966
  j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] = ytPlayerReady;
967
+ j1.adapter.amplitude.data.ytpGlobals['ytApiError'] = 0;
968
+
969
+
970
+ // save amplitudejs data for later use (e.g. events)
971
+ // -------------------------------------------------------------------
972
+ j1.modules.amplitudejs.data.ytp.apiError = 0;
973
+ j1.modules.amplitudejs.data.ytp.players.{{player.id}} = {};
974
+ j1.modules.amplitudejs.data.ytp.players.{{player.id}}.playerReady = ytPlayerReady;
992
975
 
993
- // save YT player data for later use (e.g. events)
994
- // j1.adapter.amplitude.data.ytPlayers.{{player.id}}.playerReady = ytPlayerReady;
995
976
 
996
977
  // get duration hours (if configured)
997
978
  if ({{player.display_hours}} ) {
@@ -1023,12 +1004,12 @@ regenerate: true
1023
1004
  // -------------------------------------------------------------------
1024
1005
  endTimeModule = Date.now();
1025
1006
 
1026
- logger.info('\n' + 'Initialize plugin|tech (ytp) : finished');
1007
+ logger.info('Initialize plugin|tech (ytp) : finished');
1027
1008
 
1028
1009
  if (playerCounter > 0) {
1029
- logger.info('\n' + 'Found players of type video (YTP) in page: ' + playerCounter);
1010
+ logger.info('Found players of type video (YTP) in page: ' + playerCounter);
1030
1011
  } else {
1031
- logger.warn('\n' + 'Found NO players of type video (YTP) in page');
1012
+ isDev && logger.warn('Found NO players of type video (YTP) in page');
1032
1013
  }
1033
1014
 
1034
1015
  // update activeVideoElement data structure for the ACTIVE video
@@ -1038,7 +1019,7 @@ regenerate: true
1038
1019
  }, checkActiveVideoInterval);
1039
1020
  // END checkActiveVideoElementYTP
1040
1021
 
1041
- logger.info('\n' + 'plugin|tech initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
1022
+ logger.info('plugin|tech initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
1042
1023
 
1043
1024
  } // END onPlayerReady()
1044
1025
 
@@ -1053,6 +1034,8 @@ regenerate: true
1053
1034
  // are being set; e.g. start|stop positions for a video (when)
1054
1035
  // configured.
1055
1036
  // ---------------------------------------------------------------------
1037
+ // AJS YouTube Player state changes fired by the YT API
1038
+ // ---------------------------------------------------------------------
1056
1039
  function {{player.id}}OnPlayerStateChange(event) {
1057
1040
  var currentTime, playlist, ytPlayer, ytVideoID,
1058
1041
  songs, songIndex, trackID, playerID, songMetaData;
@@ -1076,6 +1059,19 @@ regenerate: true
1076
1059
  j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player = ytPlayer;
1077
1060
  j1.adapter.amplitude.data.ytPlayers.{{player.id}}.activeIndex = songIndex;
1078
1061
 
1062
+
1063
+ // save amplitudejs data for later use (e.g. events)
1064
+ // -------------------------------------------------------------------
1065
+ j1.modules.amplitudejs.data.activePlayer = 'ytp';
1066
+ j1.modules.amplitudejs.data.activeIndex = songIndex;
1067
+ j1.modules.amplitudejs.data.activePlaylist = playlist;
1068
+ j1.modules.amplitudejs.data.ytp.activePlayer = ytPlayer;
1069
+ j1.modules.amplitudejs.data.ytp.activeIndex = songIndex;
1070
+ j1.modules.amplitudejs.data.ytp.activePlaylist = playlist;
1071
+ j1.modules.amplitudejs.data.ytp.players.{{player.id}}.player = ytPlayer;
1072
+ j1.modules.amplitudejs.data.ytp.players.{{player.id}}.activeIndex = songIndex;
1073
+
1074
+
1079
1075
  // reset time container|progressbar for the ACTIVE song (video)
1080
1076
  // -------------------------------------------------------------------
1081
1077
  resetCurrentTimeContainerYTP(ytPlayer, playlist);
@@ -1104,7 +1100,7 @@ regenerate: true
1104
1100
  processOnStateChangeEnded(event, playlist, songIndex);
1105
1101
  break;
1106
1102
  default:
1107
- logger.error('\n' + `UNKNOWN event on StateChange fired: ${event.data}`);
1103
+ logger.error(`UNKNOWN event on StateChange fired: ${event.data}`);
1108
1104
  } // END switch event.data
1109
1105
 
1110
1106
  } // END {{player.id}}OnPlayerStateChange
@@ -1114,7 +1110,6 @@ regenerate: true
1114
1110
 
1115
1111
  } // END onYouTubeIframeAPIReady
1116
1112
 
1117
-
1118
1113
  // ---------------------------------------------------------------------------
1119
1114
  // main
1120
1115
  // ===========================================================================
@@ -1126,6 +1121,13 @@ regenerate: true
1126
1121
  // ---------------------------------------------------------------------------
1127
1122
  initYtAPI();
1128
1123
 
1124
+ // save YT player data for later use (e.g. events)
1125
+ // ---------------------------------------------------------------------
1126
+ var url = '//youtube.com/iframe_api'
1127
+ if (document.querySelectorAll(`script[src="${url}"]`).length > 0) {
1128
+ j1.modules.amplitudejs.data.ytp.plugin = 'loaded';
1129
+ }
1130
+
1129
1131
  // ---------------------------------------------------------------------------
1130
1132
  // initUiEventsForAJS
1131
1133
  //
@@ -1133,28 +1135,27 @@ regenerate: true
1133
1135
  // ---------------------------------------------------------------------------
1134
1136
  initUiEventsForAJS();
1135
1137
 
1136
-
1137
1138
  // ---------------------------------------------------------------------------
1138
1139
  // Base AJS Player functions
1139
1140
  // ===========================================================================
1140
1141
 
1141
1142
  // ---------------------------------------------------------------------------
1142
- // updatMetaContainers(metaData)
1143
+ // ytpUpdatMetaContainers(metaData)
1143
1144
  //
1144
1145
  // update song name in meta-containers
1145
1146
  // ---------------------------------------------------------------------------
1146
- function updatMetaContainers(metaData) {
1147
- var playerID, playlist, songName, artistName, albumName,
1148
- largePlayerSongAudioRating;
1147
+ function ytpUpdatMetaContainers(metaData) {
1148
+ var playerID, playlist, trackID, rating;
1149
1149
 
1150
- playlist = metaData.playlist;
1151
- playerID = playlist + '_large';
1150
+ playlist = metaData.playlist;
1151
+ playerID = playlist + '_large';
1152
+ rating = metaData.rating;
1153
+ trackID = metaData.index + 1;
1152
1154
 
1153
- var trackID = metaData.index + 1;
1154
- logger.debug('\n' + `UPDATE metadata on updatMetaContainers for trackID|playlist at: ${trackID}|${playlist}`);
1155
+ logger.debug(`UPDATE metadata on ytpUpdatMetaContainers for trackID|playlist at: ${trackID}|${playlist}`);
1155
1156
 
1156
1157
  // update song name in meta-containers
1157
- songName = document.getElementsByClassName("song-name");
1158
+ var songName = document.getElementsByClassName("song-name");
1158
1159
  if (songName.length) {
1159
1160
  for (var i=0; i<songName.length; i++) {
1160
1161
  var currentPlaylist = songName[i].dataset.amplitudePlaylist;
@@ -1165,10 +1166,10 @@ regenerate: true
1165
1166
  }
1166
1167
 
1167
1168
  // update artist name in meta-containers
1168
- artistName = document.getElementsByClassName("artist");
1169
+ var artistName = document.getElementsByClassName("artist");
1169
1170
  if (artistName.length) {
1170
1171
  for (var i=0; i<artistName.length; i++) {
1171
- var currentPlaylist = songName[i].dataset.amplitudePlaylist;
1172
+ var currentPlaylist = artistName[i].dataset.amplitudePlaylist;
1172
1173
  if (currentPlaylist === playlist) {
1173
1174
  artistName[i].innerHTML = metaData.artist;
1174
1175
  }
@@ -1176,7 +1177,7 @@ regenerate: true
1176
1177
  }
1177
1178
 
1178
1179
  // update album name in meta-containers
1179
- albumName = document.getElementsByClassName("album");
1180
+ var albumName = document.getElementsByClassName("album");
1180
1181
  if (albumName.length) {
1181
1182
  for (var i=0; i<albumName.length; i++) {
1182
1183
  var currentPlaylist = songName[i].dataset.amplitudePlaylist;
@@ -1187,27 +1188,32 @@ regenerate: true
1187
1188
  }
1188
1189
 
1189
1190
  // update song rating in screen controls
1190
- largePlayerSongAudioRating = document.getElementsByClassName("audio-rating-screen-controls");
1191
- if (largePlayerSongAudioRating.length) {
1192
- for (var i=0; i<largePlayerSongAudioRating.length; i++) {
1193
- var currentPlaylist = largePlayerSongAudioRating[i].dataset.amplitudePlaylist;
1191
+ var songAudioRating = document.getElementsByClassName("audio-rating-screen-controls");
1192
+ if (songAudioRating.length) {
1193
+ for (var i=0; i<songAudioRating.length; i++) {
1194
+ var currentPlaylist = songAudioRating[i].dataset.amplitudePlaylist;
1194
1195
  if (currentPlaylist === playlist) {
1195
1196
  if (metaData.rating) {
1196
- var trackID = metaData.index + 1;
1197
-
1198
- // save YT player data for later use (e.g. events)
1199
- j1.adapter.amplitude.data.ytPlayers[playerID].videoID = metaData.videoID;
1197
+ songAudioRating[i].innerHTML = `<img src="/assets/image/pattern/rating/scalable/${metaData.rating}-star.svg" alt="song rating">`;
1198
+ }
1199
+ }
1200
+ }
1201
+ } // END if songAudioRating
1200
1202
 
1201
- logger.debug('\n' + `UPDATE song rating on updatMetaContainers for trackID|playlist at: ${trackID}|${playlist} with a value of: ${metaData.rating}`);
1202
- largePlayerSongAudioRating[i].innerHTML = '<img src="/assets/image/pattern/rating/scalable/' + metaData.rating + '-star.svg"' + 'alt="song rating">';
1203
- } else {
1204
- largePlayerSongAudioRating[i].innerHTML = '';
1203
+ // update song info in screen controls
1204
+ var songAudioInfo = document.getElementsByClassName("audio-info-link-screen-controls");
1205
+ if (songAudioInfo.length) {
1206
+ for (var i=0; i<songAudioInfo.length; i++) {
1207
+ var currentPlaylist = songAudioInfo[i].dataset.amplitudePlaylist;
1208
+ if (currentPlaylist === playlist) {
1209
+ if (metaData.audio_info) {
1210
+ songAudioInfo[i].setAttribute("href", metaData.audio_info);
1205
1211
  }
1206
1212
  }
1207
1213
  }
1208
- } // END if largePlayerSongAudioRating
1214
+ } // END if songAudioInfo
1209
1215
 
1210
- } // END updatMetaContainers
1216
+ } // END ytpUpdatMetaContainers
1211
1217
 
1212
1218
  // ---------------------------------------------------------------------------
1213
1219
  // loadCoverImage(metaData)
@@ -1221,46 +1227,68 @@ regenerate: true
1221
1227
  selector = ".cover-image-" + metaData.playlist;
1222
1228
  coverImage = document.querySelector(selector);
1223
1229
  coverImage.src = metaData.cover_art_url;
1230
+
1224
1231
  } // END loadCoverImage
1225
1232
 
1226
1233
  // ---------------------------------------------------------------------------
1227
- // stopAllActivePlayers(exceptPlayer)
1234
+ // ytpStopParallelActivePlayers(exceptPlayer)
1228
1235
  //
1229
1236
  // if multiple players used on a page, stop ALL active AT|YT players
1230
- // running in parallel execpet the exceptPlayer
1237
+ // running in parallel skipping the exceptPlayer
1231
1238
  // ---------------------------------------------------------------------------
1232
- function stopAllActivePlayers(exceptPlayer) {
1239
+ function ytpStopParallelActivePlayers(exceptPlayer) {
1233
1240
 
1234
- // stop active AT players
1241
+ // stop active AT players running in parallel
1235
1242
  // -------------------------------------------------------------------------
1236
- var atpPlayerState = Amplitude.getPlayerState();
1237
- if (atpPlayerState === 'playing') {
1243
+ var atPlayerState = Amplitude.getPlayerState();
1244
+ if (atPlayerState === 'playing' || atPlayerState === 'paused') {
1238
1245
  Amplitude.stop();
1239
1246
  } // END stop active AT players
1240
1247
 
1241
- // stop active YT players
1248
+ // stop active YT players running in parallel
1242
1249
  // -------------------------------------------------------------------------
1243
1250
  const ytPlayers = Object.keys(j1.adapter.amplitude.data.ytPlayers);
1244
1251
  for (let i=0; i<ytPlayers.length; i++) {
1245
- const ytPlayerID = ytPlayers[i];
1246
- const playerProperties = j1.adapter.amplitude.data.ytPlayers[ytPlayerID];
1252
+ const ytPlayerID = ytPlayers[i];
1253
+ const playerProperties = j1.adapter.amplitude.data.ytPlayers[ytPlayerID];
1247
1254
 
1248
1255
  if (ytPlayerID !== exceptPlayer) {
1249
1256
  var player = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID]['player'];
1250
1257
  var playerState = (player.getPlayerState() > 0) ? player.getPlayerState() : 6;
1251
1258
  var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1252
1259
 
1253
- // if (ytPlayerState === 'playing' || ytPlayerState === 'paused' || ytPlayerState === 'buffering' || ytPlayerState === 'cued' || ytPlayerState === 'unstarted') {
1254
- if (ytPlayerState === 'playing' || ytPlayerState === 'paused' || ytPlayerState === 'buffering' || ytPlayerState === 'cued' || ytPlayerState === 'unstarted') {
1255
- logger.debug('\n' + `STOP player at stopAllActivePlayers for id: ${ytPlayerID}`);
1256
- // player.mute();
1260
+ // toggle PlayPause buttons playing => puased
1261
+ // ---------------------------------------------------------------------
1262
+ var isValidPlayerState = /playing|paused/.test(ytPlayerState);
1263
+ if (isValidPlayerState) {
1264
+ logger.debug(`STOP player at ytpStopParallelActivePlayers for id: ${ytPlayerID}`);
1257
1265
  player.stopVideo();
1258
- j1.adapter.amplitude.data.ytpGlobals.activeIndex = 0;
1259
- }
1260
- }
1261
- } // END stop active YT players
1266
+ var ytpButtonPlayerPlayPause = document.getElementsByClassName("large-player-play-pause-" + ytPlayerID);
1267
+ for (var j=0; j<ytpButtonPlayerPlayPause.length; j++) {
1268
+
1269
+ var htmlElement = ytpButtonPlayerPlayPause[j];
1270
+ if (htmlElement.dataset.amplitudeSource === 'youtube') {
1271
+ if (htmlElement.classList.contains('amplitude-playing')) {
1272
+ htmlElement.classList.remove('amplitude-playing');
1273
+ htmlElement.classList.add('amplitude-paused');
1274
+ }
1275
+ // if (htmlElement.classList.contains('amplitude-paused')) {
1276
+ // htmlElement.classList.remove('amplitude-paused');
1277
+ // htmlElement.classList.add('amplitude-playing');
1278
+ // }
1279
+ }
1280
+
1281
+ } // END for ytpButtonPlayerPlayPause
1282
+
1283
+ } // END if ytPlayerState
1284
+ } // END if ytPlayerID
1262
1285
 
1263
- } // END stopAllActivePlayers
1286
+ // save AT player data for later use (e.g. events)
1287
+ // ---------------------------------------------------------------------
1288
+ j1.adapter.amplitude.data.ytpGlobals.activeIndex = 0;
1289
+
1290
+ } // END stop active YT players
1291
+ } // END ytpStopParallelActivePlayers
1264
1292
 
1265
1293
  // ---------------------------------------------------------------------------
1266
1294
  // getSongPlayed
@@ -1313,7 +1341,7 @@ regenerate: true
1313
1341
  }
1314
1342
  }
1315
1343
 
1316
- } // END setSongPlayed
1344
+ } // END setSongActive
1317
1345
 
1318
1346
  // ---------------------------------------------------------------------------
1319
1347
  // getProgressBarSelectedPositionPercentage
@@ -1368,20 +1396,18 @@ regenerate: true
1368
1396
  activeVideoElement.album = activeSong.album;
1369
1397
  activeVideoElement.artist = activeSong.artist;
1370
1398
  activeVideoElement.audio_info = activeSong.audio_info;
1371
- activeVideoElement.audio_single = activeSong.audio_single;
1372
1399
  activeVideoElement.currentTime = parseFloat(activeVideoElement.player.getCurrentTime());
1373
1400
  activeVideoElement.cover_art_url = activeSong.cover_art_url;
1374
1401
  activeVideoElement.duration = activeSong.duration;
1375
- activeVideoElement.endSec = timestamp2seconds(activeSong.end);
1402
+ activeVideoElement.endSec = j1.adapter.amplitude.timestamp2seconds(activeSong.end);
1376
1403
  activeVideoElement.endTS = activeSong.end;
1377
1404
  activeVideoElement.name = activeSong.name;
1378
- activeVideoElement.rating = activeSong.album;
1379
- activeVideoElement.startSec = timestamp2seconds(activeSong.start);
1405
+ activeVideoElement.rating = activeSong.rating;
1406
+ activeVideoElement.startSec = j1.adapter.amplitude.timestamp2seconds(activeSong.start);
1380
1407
  activeVideoElement.startTS = activeSong.start;
1381
1408
  activeVideoElement.url = activeSong.url;
1382
1409
 
1383
1410
  var videoArray = activeSong.url.split('=');
1384
-
1385
1411
  activeVideoElement.videoID = videoArray[1];
1386
1412
 
1387
1413
  }
@@ -1440,7 +1466,7 @@ regenerate: true
1440
1466
  activeClass = 'large-player-progress-' + playlist;
1441
1467
 
1442
1468
  if (activePlayer === undefined) {
1443
- logger.error('\n' + 'YT player not defined');
1469
+ logger.error('YT player not defined');
1444
1470
  return;
1445
1471
  }
1446
1472
 
@@ -1467,33 +1493,13 @@ regenerate: true
1467
1493
  function updateDurationTimeContainerYTP(player, playlist) {
1468
1494
  var hours, minutes, seconds;
1469
1495
  var durationHours, durationMinutes, durationSeconds;
1470
- var activeSongSettings, ytPlayer, activePlaylist;
1471
-
1472
- // update active song settings (manually)
1473
- checkActiveVideoElementYTP();
1474
-
1475
- // get active song settings (manually)
1476
- activeSongSettings = getActiveSong();
1477
- if (!activeSongSettings) {
1478
- return false;
1479
- }
1480
-
1481
- ytPlayer = activeSongSettings.player;
1482
- activePlaylist = activeSongSettings.playlist;
1483
-
1484
- // if (activeSongSettings) {
1485
- // ytPlayer = activeSongSettings.player;
1486
- // activePlaylist = activeSongSettings.playlist;
1487
- // } else {
1488
- // ytPlayer = player;
1489
- // activePlaylist = playlist;
1490
- // }
1496
+ var activePlaylist;
1491
1497
 
1492
1498
  // get current hours|minutes|seconds
1493
1499
  // -------------------------------------------------------------------------
1494
- hours = ytpGetDurationHours(ytPlayer);
1495
- minutes = ytpGetDurationMinutes(ytPlayer);
1496
- seconds = ytpGetDurationSeconds(ytPlayer);
1500
+ hours = ytpGetDurationHours(player);
1501
+ minutes = ytpGetDurationMinutes(player);
1502
+ seconds = ytpGetDurationSeconds(player);
1497
1503
 
1498
1504
  // update current duration|hours
1499
1505
  // -------------------------------------------------------------------------
@@ -1501,7 +1507,7 @@ regenerate: true
1501
1507
  if (durationHours.length && !isNaN(hours)) {
1502
1508
  for (var i=0; i<durationHours.length; i++) {
1503
1509
  var currentPlaylist = durationHours[i].dataset.amplitudePlaylist;
1504
- if (currentPlaylist === activePlaylist) {
1510
+ if (currentPlaylist === playlist) {
1505
1511
  durationHours[i].innerHTML = hours;
1506
1512
  }
1507
1513
  }
@@ -1513,7 +1519,7 @@ regenerate: true
1513
1519
  if (durationMinutes.length && !isNaN(minutes)) {
1514
1520
  for (var i=0; i<durationMinutes.length; i++) {
1515
1521
  var currentPlaylist = durationMinutes[i].dataset.amplitudePlaylist;
1516
- if (currentPlaylist === activePlaylist) {
1522
+ if (currentPlaylist === playlist) {
1517
1523
  durationMinutes[i].innerHTML = minutes;
1518
1524
  }
1519
1525
  }
@@ -1525,7 +1531,7 @@ regenerate: true
1525
1531
  if (durationSeconds.length && !isNaN(seconds)) {
1526
1532
  for (var i=0; i<durationSeconds.length; i++) {
1527
1533
  var currentPlaylist = durationSeconds[i].dataset.amplitudePlaylist;
1528
- if (currentPlaylist === activePlaylist) {
1534
+ if (currentPlaylist === playlist) {
1529
1535
  durationSeconds[i].innerHTML = seconds;
1530
1536
  }
1531
1537
  }
@@ -1693,7 +1699,6 @@ regenerate: true
1693
1699
 
1694
1700
  } // END ytpSeekTo
1695
1701
 
1696
-
1697
1702
  // ---------------------------------------------------------------------------
1698
1703
  // ytpGetBuffered
1699
1704
  //
@@ -1719,7 +1724,6 @@ regenerate: true
1719
1724
  return activeIndex;
1720
1725
  } // END ytpGetActiveIndex
1721
1726
 
1722
-
1723
1727
  // ---------------------------------------------------------------------------
1724
1728
  // ytpSetActiveIndex
1725
1729
  //
@@ -1779,10 +1783,13 @@ regenerate: true
1779
1783
  // Returns the duration of the video
1780
1784
  // ---------------------------------------------------------------------------
1781
1785
  function ytpGetDuration(player) {
1782
- var playerState, duration;
1786
+ var duration;
1783
1787
 
1784
- playerState = player.getPlayerState();
1785
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.BUFFERING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1788
+ var playerState = player.getPlayerState();
1789
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1790
+
1791
+ var isValidPlayerState = /playing|paused|buffering|cued/.test(ytPlayerState);
1792
+ if (isValidPlayerState) {
1786
1793
  duration = player.getDuration();
1787
1794
 
1788
1795
  return duration;
@@ -1797,18 +1804,20 @@ regenerate: true
1797
1804
  // Returns the current time of the video played
1798
1805
  // ---------------------------------------------------------------------------
1799
1806
  function ytpGetCurrentTime(player) {
1800
- var currentTime, playerState;
1807
+ var currentTime;
1808
+
1809
+ var playerState = player.getPlayerState();
1810
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1801
1811
 
1802
- if (player !== undefined && player.getPlayerState !== undefined) {
1803
- playerState = player.getPlayerState();
1804
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1812
+ var isValidPlayerState = /playing|paused|cued|unstarted/.test(ytPlayerState);
1813
+ if (isValidPlayerState) {
1805
1814
  currentTime = player.getCurrentTime();
1806
1815
 
1807
1816
  return currentTime;
1808
- } else {
1817
+ } else {
1809
1818
  return 0;
1810
- }
1811
1819
  }
1820
+
1812
1821
  } // END ytpGetCurrentTime
1813
1822
 
1814
1823
  // ---------------------------------------------------------------------------
@@ -1817,21 +1826,23 @@ regenerate: true
1817
1826
  // Returns the duration hours of the video
1818
1827
  // ---------------------------------------------------------------------------
1819
1828
  function ytpGetDurationHours(player) {
1820
- var playerState, duration, hours, d, h;
1829
+ var duration, hours, d, h;
1830
+
1831
+ var playerState = player.getPlayerState();
1832
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1821
1833
 
1822
- if (player !== undefined && player.getPlayerState !== undefined) {
1823
- playerState = player.getPlayerState();
1824
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
1834
+ var isValidPlayerState = /playing|paused|cued/.test(ytPlayerState);
1835
+ if (isValidPlayerState) {
1825
1836
  duration = ytpGetDuration(player);
1826
1837
  d = Number(duration);
1827
1838
  h = Math.floor(d / 3600);
1828
1839
  hours = h.toString().padStart(2, '0');
1829
1840
 
1830
1841
  return hours;
1831
- } else {
1842
+ } else {
1832
1843
  return '00';
1833
- }
1834
1844
  }
1845
+
1835
1846
  } // END ytpGetDurationHours
1836
1847
 
1837
1848
  // ---------------------------------------------------------------------------
@@ -1840,23 +1851,24 @@ regenerate: true
1840
1851
  // Returns the duration minutes of the video
1841
1852
  // ---------------------------------------------------------------------------
1842
1853
  function ytpGetDurationMinutes(player) {
1843
- var playerState, duration, minutes, d, m;
1854
+ var duration, minutes, d, m;
1844
1855
 
1845
- if (player !== undefined && player.getPlayerState !== undefined) {
1846
- playerState = player.getPlayerState();
1847
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1856
+ var playerState = player.getPlayerState();
1857
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1858
+
1859
+ var isValidPlayerState = /playing|paused|cued/.test(ytPlayerState);
1860
+ if (isValidPlayerState) {
1848
1861
  duration = ytpGetDuration(player);
1849
1862
  d = Number(duration);
1850
1863
  m = Math.floor(d % 3600 / 60);
1851
1864
  minutes = m.toString().padStart(2, '0');
1852
1865
 
1853
1866
  return minutes;
1854
- } else {
1867
+ } else {
1855
1868
  return '00';
1856
- }
1857
1869
  }
1858
- } // END ytpGetDurationMinutes
1859
1870
 
1871
+ } // END ytpGetDurationMinutes
1860
1872
 
1861
1873
  // ---------------------------------------------------------------------------
1862
1874
  // ytpGetDurationSeconds
@@ -1864,21 +1876,23 @@ regenerate: true
1864
1876
  // Returns the duration seconds of the video
1865
1877
  // ---------------------------------------------------------------------------
1866
1878
  function ytpGetDurationSeconds(player) {
1867
- var playerState, duration, seconds, d, s;
1879
+ var duration, seconds, d, s;
1880
+
1881
+ var playerState = player.getPlayerState();
1882
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1868
1883
 
1869
- if (player !== undefined && player.getPlayerState !== undefined) {
1870
- playerState = player.getPlayerState();
1871
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
1884
+ var isValidPlayerState = /playing|paused|cued/.test(ytPlayerState);
1885
+ if (isValidPlayerState) {
1872
1886
  duration = ytpGetDuration(player);
1873
1887
  d = Number(duration);
1874
1888
  s = Math.floor(d % 60);
1875
1889
  seconds = s.toString().padStart(2, '0');
1876
1890
 
1877
1891
  return seconds;
1878
- } else {
1892
+ } else {
1879
1893
  return '00';
1880
- }
1881
1894
  }
1895
+
1882
1896
  } // END ytpGetDurationSeconds
1883
1897
 
1884
1898
  // ---------------------------------------------------------------------------
@@ -1887,21 +1901,23 @@ regenerate: true
1887
1901
  // Returns the current hours the user is into the video
1888
1902
  // ---------------------------------------------------------------------------
1889
1903
  function ytpGetCurrentHours(player) {
1890
- var playerState, currentTime, hours, d, h;
1904
+ var currentTime, hours, d, h;
1905
+
1906
+ var playerState = player.getPlayerState();
1907
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1891
1908
 
1892
- if (player !== undefined && player.getPlayerState !== undefined) {
1893
- playerState = player.getPlayerState();
1894
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1909
+ var isValidPlayerState = /playing|paused/.test(ytPlayerState);
1910
+ if (isValidPlayerState) {
1895
1911
  currentTime = ytpGetCurrentTime(player);
1896
1912
  d = Number(currentTime);
1897
1913
  h = Math.floor(d / 3600);
1898
1914
  hours = h.toString().padStart(2, '0');
1899
1915
 
1900
1916
  return hours;
1901
- } else {
1917
+ } else {
1902
1918
  return '00';
1903
- }
1904
1919
  }
1920
+
1905
1921
  } // END ytpGetCurrentHours
1906
1922
 
1907
1923
  // ---------------------------------------------------------------------------
@@ -1910,21 +1926,23 @@ regenerate: true
1910
1926
  // Returns the current minutes the user is into the video
1911
1927
  // ---------------------------------------------------------------------------
1912
1928
  function ytpGetCurrentMinutes (player) {
1913
- var playerState, currentTime, minutes, d, m;
1929
+ var currentTime, minutes, d, m;
1930
+
1931
+ var playerState = player.getPlayerState();
1932
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1914
1933
 
1915
- if (player !== undefined && player.getPlayerState !== undefined) {
1916
- playerState = player.getPlayerState();
1917
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1934
+ var isValidPlayerState = /playing|paused/.test(ytPlayerState);
1935
+ if (isValidPlayerState) {
1918
1936
  currentTime = ytpGetCurrentTime(player);
1919
1937
  d = Number(currentTime);
1920
1938
  m = Math.floor(d % 3600 / 60);
1921
1939
  minutes = m.toString().padStart(2, '0');
1922
1940
 
1923
1941
  return minutes;
1924
- } else {
1942
+ } else {
1925
1943
  return '00';
1926
- }
1927
1944
  }
1945
+
1928
1946
  } // END ytpGetCurrentMinutes
1929
1947
 
1930
1948
  // ---------------------------------------------------------------------------
@@ -1933,21 +1951,23 @@ regenerate: true
1933
1951
  // Returns the current seconds the user is into the video
1934
1952
  // ---------------------------------------------------------------------------
1935
1953
  function ytpGetCurrentSeconds(player) {
1936
- var playerState, currentTime, seconds, d, s;
1954
+ var currentTime, seconds, d, s;
1937
1955
 
1938
- if (player !== undefined && player.getPlayerState !== undefined) {
1939
- playerState = player.getPlayerState();
1940
- if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
1956
+ var playerState = player.getPlayerState();
1957
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
1958
+
1959
+ var isValidPlayerState = /playing|paused/.test(ytPlayerState);
1960
+ if (isValidPlayerState) {
1941
1961
  currentTime = ytpGetCurrentTime(player);
1942
1962
  d = Number(currentTime);
1943
1963
  s = Math.floor(d % 60);
1944
1964
  seconds = s.toString().padStart(2, '0');
1945
1965
 
1946
1966
  return seconds;
1947
- } else {
1967
+ } else {
1948
1968
  return '00';
1949
- }
1950
1969
  }
1970
+
1951
1971
  } // END ytpGetCurrentSeconds
1952
1972
 
1953
1973
  // ---------------------------------------------------------------------------
@@ -1980,10 +2000,6 @@ regenerate: true
1980
2000
  // setPlayPauseButtonPaused
1981
2001
  // ---------------------------------------------------------------------------
1982
2002
  function setPlayPauseButtonPaused(element) {
1983
- var button, htmlElement;
1984
-
1985
- // button = document.getElementsByClassName(elementClass);
1986
- // htmlElement = button[0];
1987
2003
 
1988
2004
  element.classList.remove('amplitude-playing');
1989
2005
  element.classList.add('amplitude-paused');
@@ -1993,14 +2009,10 @@ regenerate: true
1993
2009
  // ---------------------------------------------------------------------------
1994
2010
  // setPlayPauseButtonPlaying
1995
2011
  // ---------------------------------------------------------------------------
1996
- function setPlayPauseButtonPlaying(elementClass) {
1997
- var button, htmlElement;
1998
-
1999
- button = document.getElementsByClassName(elementClass);
2000
- htmlElement = button[0];
2012
+ function setPlayPauseButtonPlaying(element) {
2001
2013
 
2002
- htmlElement.classList.remove('amplitude-paused');
2003
- htmlElement.classList.add('amplitude-playing');
2014
+ element.classList.remove('amplitude-paused');
2015
+ element.classList.add('amplitude-playing');
2004
2016
 
2005
2017
  } // END setPlayPauseButtonPlaying
2006
2018
 
@@ -2070,8 +2082,7 @@ regenerate: true
2070
2082
  });
2071
2083
  }
2072
2084
 
2073
- // Overload AJS play_pause button for YT
2074
- // TODO: Fix for multiple players in page
2085
+ // Overload ytp play_pause button for YT
2075
2086
  // ---------------------------------------------------------------------
2076
2087
  var largePlayerPlayPauseButton = document.getElementsByClassName(playerButton);
2077
2088
  for (var i=0; i<largePlayerPlayPauseButton.length; i++) {
@@ -2080,111 +2091,117 @@ regenerate: true
2080
2091
 
2081
2092
  if (classString.includes(ytPlayerID)) {
2082
2093
  largePlayerPlayPauseButton[i].addEventListener('click', function(event) {
2083
- var activeSongSettings, songs, songMetaData, ytPlayer,
2084
- playlist, playerID, songIndex;
2085
-
2086
- playlist = this.getAttribute("data-amplitude-playlist");
2087
- playerID = playlist + '_large';
2094
+ var activeSong, songs, songMetaData, playerData,
2095
+ ytPlayer, playerState, ytPlayerState, playlist,
2096
+ playerID, songIndex;
2088
2097
 
2089
- // update active song settings (manually)
2090
- checkActiveVideoElementYTP();
2098
+ playlist = this.getAttribute("data-amplitude-playlist");
2099
+ playerID = playlist + '_large';
2100
+ activeSong = getActiveSong();
2091
2101
 
2092
- // get active song settings (manually)
2093
- activeSongSettings = getActiveSong();
2094
-
2095
- // TODO: Extend getSongIndex() for singleAudio
2096
- // var songIndex = (singleAudio) ? ytpSongIndex : getSongIndex(songs, ytVideoID);
2097
- if (!activeSongSettings) {
2102
+ if (!activeSong) {
2098
2103
  songIndex = 0;
2099
2104
  ytpSongIndex = 0;
2100
2105
  } else {
2101
-
2102
- // ytPlayerCurrentTime = activeSongSettings.currentTime;
2103
-
2104
- if (activeSongSettings.playlist !== playlist) {
2106
+ if (activeSong.playlist !== playlist) {
2105
2107
  songIndex = 0;
2106
2108
  ytpSongIndex = 0;
2107
-
2108
- // reset previous player settings
2109
- if (activeSongSettings.player !== undefined) {
2110
- activeSongSettings.player.stopVideo();
2111
- var playPauseButtonClass = `large-player-play-pause-${activeSongSettings.playerID}`;
2112
- togglePlayPauseButton(playPauseButtonClass);
2113
- }
2114
2109
  } else {
2115
2110
  songIndex = ytpSongIndex;
2116
2111
  }
2117
- }
2118
-
2119
- // set song (video) active at index in playlist
2120
- setSongActive(playlist, songIndex);
2112
+ } // END if activeSong
2121
2113
 
2122
- // reset progress bar settings
2123
- resetProgressBarYTP();
2114
+ if (j1.adapter.amplitude.data.ytpGlobals.ytApiError > 0) {
2115
+ // do nothing on API errors
2116
+ var trackID = songIndex + 1;
2117
+ logger.error(`DISABLED player for playlist|trackID: ${playlist}|${trackID} on API error '${YT_PLAYER_ERROR_NAMES[j1.adapter.amplitude.data.ytpGlobals.ytApiError]}'`);
2124
2118
 
2125
- // scroll song active at index in player
2126
- if (playerAutoScrollSongElement) {
2127
- scrollToActiveElement(playlist);
2119
+ return;
2128
2120
  }
2129
2121
 
2130
- // update activeAudio data (manually)
2131
- checkActiveVideoElementYTP();
2132
-
2133
- // get active song settings (manually)
2134
- activeSongSettings = getActiveSong();
2135
-
2136
- songs = activeSongSettings.songs;
2137
- songMetaData = songs[songIndex];
2138
- ytPlayer = activeSongSettings.player;
2139
-
2140
- // update meta data
2141
- updatMetaContainers(songMetaData);
2122
+ playerData = j1.adapter.amplitude.data.ytPlayers[playerID];
2123
+ ytPlayer = playerData.player;
2124
+ songIndex = playerData.activeIndex;
2125
+ songs = playerData.songs;
2142
2126
 
2143
2127
  // save player GLOBAL data for later use (e.g. events)
2144
2128
  j1.adapter.amplitude.data.activePlayer = 'ytp';
2145
2129
  j1.adapter.amplitude.data.ytpGlobals['activeIndex'] = songIndex;
2146
2130
  j1.adapter.amplitude.data.ytpGlobals['activePlaylist'] = playlist;
2147
2131
 
2148
- // YT play|pause video
2132
+ // toggle YT play|pause video
2149
2133
  // ---------------------------------------------------------------
2150
- var playerState = ytPlayer.getPlayerState();
2151
- if (playerState < 0) {
2152
- var ytPlayerState = YT_PLAYER_STATE_NAMES[6];
2153
- } else {
2154
- var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
2155
- }
2134
+ playerState = ytPlayer.getPlayerState();
2135
+ ytPlayerState = (playerState < 0) ? YT_PLAYER_STATE_NAMES[6] : YT_PLAYER_STATE_NAMES[playerState];
2136
+
2137
+ // NOTE:
2138
+ // ---------------------------------------------------------------
2139
+ // unclear why player state 'cued' occurs
2140
+ // ---------------------------------------------------------------
2141
+ // load (cued) video
2142
+ if (ytPlayerState === 'cued' || ytPlayerState === 'unstarted' ) {
2143
+ ytPlayer.playVideo();
2144
+
2145
+ // wait for API error state
2146
+ setTimeout(() => {
2147
+ if (j1.adapter.amplitude.data.ytpGlobals.ytApiError > 0) {
2148
+ var trackID = songIndex + 1;
2149
+ logger.error(`DISABLED player for playlist|trackID: ${playlist}|${trackID} on API error '${YT_PLAYER_ERROR_NAMES[j1.adapter.amplitude.data.ytpGlobals.ytApiError]}'`);
2150
+
2151
+ // do nothing on API errors
2152
+ return;
2153
+ }
2154
+
2155
+ // reset progress bar settings
2156
+ resetProgressBarYTP();
2156
2157
 
2157
- // var playPauseButtonsMini = document.getElementsByClassName('mini-player-play-pause');
2158
- // setPlayPauseButtonPaused(playPauseButtonsMini);
2158
+ var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2159
+ togglePlayPauseButton(playPauseButtonClass);
2159
2160
 
2160
- if (ytPlayerState === 'playing') {
2161
+ // set song at songIndex active in playlist
2162
+ setSongActive(playlist, songIndex);
2163
+
2164
+ // scroll song active at index in player
2165
+ if (playerAutoScrollSongElement) {
2166
+ scrollToActiveElement(playlist);
2167
+ }
2168
+
2169
+ // reset|update time settings
2170
+ resetCurrentTimeContainerYTP(ytPlayer, playlist);
2171
+ updateDurationTimeContainerYTP(ytPlayer, playlist);
2172
+
2173
+ }, 100);
2174
+
2175
+ return;
2176
+ } // END if ytPlayerState === 'cued'
2177
+
2178
+ // NOTE:
2179
+ // ---------------------------------------------------------------
2180
+ // unclear why player state 'cued'
2181
+ // is folloed by 'unstarted'|'buffering' on playing
2182
+ // ---------------------------------------------------------------
2183
+ // TOGGLE state 'playing' => 'paused'
2184
+ var isValidPlayerState = /playing|unstarted|buffering/.test(ytPlayerState);
2185
+ if (isValidPlayerState) {
2161
2186
  ytPlayer.pauseVideo();
2162
2187
 
2163
2188
  ytPlayerCurrentTime = ytPlayer.getCurrentTime();
2164
-
2165
- // var trackID = songIndex + 1;
2166
- // logger.debug('\n' + `PAUSE video for PlayPauseButton on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2167
2189
 
2168
- // var playPauseButtonsMini = document.getElementsByClassName('mini-player-play-pause');
2169
- // setPlayPauseButtonPaused(playPauseButtonsMini);
2170
-
2171
- // var playPauseButtonClassCompact = `compact-player-play-pause -${ytPlayerID}`;
2172
- // togglePlayPauseButton(playPauseButtonClassCompact);
2173
- // //
2174
- // var playPauseButtonClassLarge = `large-player-play-pause-${ytPlayerID}`;
2175
- // togglePlayPauseButton(playPauseButtonClassLarge);
2190
+ var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2191
+ togglePlayPauseButton(playPauseButtonClass);
2176
2192
 
2177
2193
  // reset|update time settings
2178
2194
  resetCurrentTimeContainerYTP(ytPlayer, playlist);
2179
2195
  updateDurationTimeContainerYTP(ytPlayer, playlist);
2180
2196
  }
2181
2197
 
2198
+ // TOGGLE state 'paused' => 'playing'
2182
2199
  if (ytPlayerState === 'paused') {
2183
2200
  ytPlayer.playVideo();
2184
2201
  ytpSeekTo(ytPlayer, ytPlayerCurrentTime, true);
2185
2202
 
2186
2203
  var trackID = songIndex + 1;
2187
- logger.debug('\n' + `PLAY video for PlayPauseButton on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2204
+ logger.debug(`PLAY video for PlayPauseButton on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2188
2205
 
2189
2206
  var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2190
2207
  togglePlayPauseButton(playPauseButtonClass);
@@ -2192,47 +2209,16 @@ regenerate: true
2192
2209
  // reset|update time settings
2193
2210
  resetCurrentTimeContainerYTP(ytPlayer, playlist);
2194
2211
  updateDurationTimeContainerYTP(ytPlayer, playlist);
2195
- }
2196
-
2197
- if (ytPlayerState === 'cued') {
2198
- ytPlayer.playVideo();
2199
- var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2200
- togglePlayPauseButton(playPauseButtonClass);
2201
-
2202
- // set song at songIndex active in playlist
2203
- setSongActive(playlist, songIndex);
2204
-
2205
- // scroll song active at index in player
2206
- if (playerAutoScrollSongElement) {
2207
- scrollToActiveElement(playlist);
2208
- }
2209
-
2210
- // reset|update time settings
2211
- resetCurrentTimeContainerYTP(ytPlayer, playlist);
2212
- updateDurationTimeContainerYTP(ytPlayer, playlist);
2213
- }
2214
-
2215
- // TODO: unclear why state 'unstarted' is generated
2216
- // on LAST item
2217
- // workaround sofar
2218
- if (ytPlayerState === 'unstarted') {
2219
- ytPlayer.playVideo();
2220
- // ytPlayer.mute();
2221
-
2222
- var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2223
- togglePlayPauseButton(playPauseButtonClass);
2224
- resetCurrentTimeContainerYTP(ytPlayer, playlist);
2225
- updateDurationTimeContainerYTP(ytPlayer, playlist);
2226
- }
2212
+ } // if ytPlayerState === 'paused'
2227
2213
 
2228
2214
  // deactivate AJS events (if any)
2229
2215
  event.stopImmediatePropagation();
2230
- }); // END EventListener largePlayerPlayPauseButton 'click'
2231
- }
2216
+
2217
+ }); // END EventListener largePlayerPlayPauseButton 'click
2218
+ } // END if classString
2232
2219
  } // END for largePlayerPlayPauseButton
2233
2220
 
2234
2221
  // Overload AJS largePlayerSkipBackward button for YT
2235
- // TODO: Fix for multiple players in page
2236
2222
  // ---------------------------------------------------------------------
2237
2223
  var largePlayerSkipForwardButtons = document.getElementsByClassName("large-player-skip-forward");
2238
2224
  for (var i=0; i<largePlayerSkipForwardButtons.length; i++) {
@@ -2252,19 +2238,17 @@ regenerate: true
2252
2238
  currentVideoTime = ytPlayer.getCurrentTime();
2253
2239
 
2254
2240
  if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) {
2255
- logger.debug('\n' + `SKIP forward on Button skipForward for ${skipOffset} seconds`);
2241
+ logger.debug(`SKIP forward on Button skipForward for ${skipOffset} seconds`);
2256
2242
  ytpSeekTo(ytPlayer, currentVideoTime + skipOffset, true);
2257
-
2258
2243
  }
2259
2244
 
2260
2245
  // deactivate AJS events (if any)
2261
2246
  event.stopImmediatePropagation();
2262
- }); // END Listener 'click'
2263
- } // END if skip-forward button
2264
- } // END for
2247
+ }); // END eventListener
2248
+ } // END if classString.includes(ytPlayerID
2249
+ } // END for largePlayerSkipForwardButtons
2265
2250
 
2266
2251
  // Overload AJS largePlayerSkipBackward button for YT
2267
- // TODO: Fix for multiple players in page
2268
2252
  // ---------------------------------------------------------------------
2269
2253
  var largePlayerSkipBackwardButtons = document.getElementsByClassName("large-player-skip-backward");
2270
2254
  for (var i=0; i<largePlayerSkipBackwardButtons.length; i++) {
@@ -2284,7 +2268,7 @@ regenerate: true
2284
2268
  currentVideoTime = ytPlayer.getCurrentTime();
2285
2269
 
2286
2270
  if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) {
2287
- logger.debug('\n' + `SKIP backward on Button skipBackward for ${skipOffset} seconds`);
2271
+ logger.debug(`SKIP backward on Button skipBackward for ${skipOffset} seconds`);
2288
2272
  ytpSeekTo(ytPlayer, currentVideoTime - skipOffset, true);
2289
2273
  }
2290
2274
 
@@ -2295,8 +2279,6 @@ regenerate: true
2295
2279
  } // END for
2296
2280
 
2297
2281
  // Overload AJS largePlayerNext button for YT
2298
- // click on (player) next button
2299
- // TODO: Fix for multiple players in page
2300
2282
  // ---------------------------------------------------------------------
2301
2283
  var largePlayerNextButton = document.getElementsByClassName("large-player-next");
2302
2284
  for (var i=0; i<largePlayerNextButton.length; i++) {
@@ -2315,12 +2297,17 @@ regenerate: true
2315
2297
  songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2316
2298
  ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2317
2299
 
2318
- if (ytPlayer === undefined) {
2319
- logger.error('\n' + 'YT player not defined');
2300
+ if (j1.adapter.amplitude.data.ytpGlobals.ytApiError > 0) {
2301
+ // do nothing on API errors
2302
+ var trackID = songIndex + 1;
2303
+ logger.error(`DISABLED player for playlist|trackID: ${playlist}|${trackID} on API error '${YT_PLAYER_ERROR_NAMES[j1.adapter.amplitude.data.ytpGlobals.ytApiError]}'`);
2304
+
2305
+ return;
2320
2306
  }
2321
2307
 
2322
- // stop active AT|YT players except the current
2323
- // stopAllActivePlayers(playerID);
2308
+ if (ytPlayer === undefined) {
2309
+ logger.error('YT player not defined');
2310
+ }
2324
2311
 
2325
2312
  // select video
2326
2313
  if (songIndex < songs.length-1) {
@@ -2350,8 +2337,16 @@ regenerate: true
2350
2337
  j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2351
2338
  j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2352
2339
 
2340
+ // save amplitudejs data for later use (e.g. events)
2341
+ // ---------------------------------------------------------------
2342
+ j1.modules.amplitudejs.data.ytp.activeIndex = songIndex;
2343
+ j1.modules.amplitudejs.data.ytp.activePlaylist = playlist;
2344
+ j1.modules.amplitudejs.data.ytp.players[playerID].player = ytPlayer;
2345
+ j1.modules.amplitudejs.data.ytp.players[playerID].activeIndex = songIndex;
2346
+
2347
+
2353
2348
  trackID = songIndex + 1;
2354
- logger.debug('\n' + `SWITCH video for PlayerNextButton at trackID|VideoID: ${trackID}|${ytpVideoID}`);
2349
+ logger.debug(`SWITCH video for PlayerNextButton at trackID|VideoID: ${trackID}|${ytpVideoID}`);
2355
2350
  ytPlayer.loadVideoById(ytpVideoID);
2356
2351
 
2357
2352
  // delay after switch video
@@ -2375,7 +2370,6 @@ regenerate: true
2375
2370
 
2376
2371
  // set AJS play_pause button paused
2377
2372
  var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2378
- // setPlayPauseButtonPlaying(playPauseButtonClass);
2379
2373
  togglePlayPauseButton(playPauseButtonClass);
2380
2374
  } else {
2381
2375
  // toggle AJS play_pause button
@@ -2392,7 +2386,7 @@ regenerate: true
2392
2386
  loadCoverImage(songMetaData);
2393
2387
 
2394
2388
  // update meta data
2395
- updatMetaContainers(songMetaData);
2389
+ // ytpUpdatMetaContainers(songMetaData);
2396
2390
 
2397
2391
  // set song at songIndex active in playlist
2398
2392
  setSongActive(playlist, songIndex);
@@ -2406,13 +2400,11 @@ regenerate: true
2406
2400
  event.stopImmediatePropagation();
2407
2401
 
2408
2402
  }); // END EventListener 'click' next button
2409
- } // END if
2403
+ } // END if classString.includes(ytPlayerID)
2410
2404
 
2411
2405
  } // END for largePlayerNextButton
2412
2406
 
2413
2407
  // Overload AJS largePlayerPrevious button for YT
2414
- // click on (player) previous button
2415
- // TODO: Fix for multiple players in page
2416
2408
  // -----------------------------------------------------------------------
2417
2409
  var largePlayePreviousButton = document.getElementsByClassName("large-player-previous");
2418
2410
  for (var i=0; i<largePlayePreviousButton.length; i++) {
@@ -2431,12 +2423,17 @@ regenerate: true
2431
2423
  songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2432
2424
  ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2433
2425
 
2434
- if (ytPlayer === undefined) {
2435
- logger.error('\n' + 'YT player not defined');
2426
+ if (j1.adapter.amplitude.data.ytpGlobals.ytApiError > 0) {
2427
+ // do nothing on API errors
2428
+ var trackID = songIndex + 1;
2429
+ logger.error(`DISABLED player for playlist|trackID: ${playlist}|${trackID} on API error '${YT_PLAYER_ERROR_NAMES[j1.adapter.amplitude.data.ytpGlobals.ytApiError]}'`);
2430
+
2431
+ return;
2436
2432
  }
2437
2433
 
2438
- // stop active AT|YT players except the current
2439
- // stopAllActivePlayers(playerID);
2434
+ if (ytPlayer === undefined) {
2435
+ logger.error('YT player not defined');
2436
+ }
2440
2437
 
2441
2438
  // select video
2442
2439
  if (songIndex > 0 && songIndex <= songs.length - 1) {
@@ -2459,7 +2456,20 @@ regenerate: true
2459
2456
  j1.adapter.amplitude.data.ytpGlobals['activeIndex'] = songIndex;
2460
2457
  j1.adapter.amplitude.data.ytpGlobals['activePlaylist'] = playlist;
2461
2458
 
2462
- // load next video
2459
+
2460
+ // save amplitudejs data for later use (e.g. events)
2461
+ // -----------------------------------------------------------------
2462
+ j1.modules.amplitudejs.data.activePlayer = songIndex;
2463
+ j1.modules.amplitudejs.data.activeIndex = songIndex;
2464
+ j1.modules.amplitudejs.data.activePlaylist = songIndex;
2465
+ j1.modules.amplitudejs.data.ytp.activeIndex = songIndex;
2466
+ j1.modules.amplitudejs.data.ytp.activePlaylist = playlist;
2467
+ j1.modules.amplitudejs.data.ytp.players[playerID].player = ytPlayer;
2468
+ j1.modules.amplitudejs.data.ytp.players[playerID].activeIndex = songIndex;
2469
+
2470
+
2471
+
2472
+ // load previous video
2463
2473
  // -----------------------------------------------------------------
2464
2474
 
2465
2475
  // save YT player data for later use (e.g. events)
@@ -2468,7 +2478,7 @@ regenerate: true
2468
2478
  j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2469
2479
 
2470
2480
  trackID = songIndex + 1;
2471
- logger.debug('\n' + `SWITCH video for PlayePreviousButton at trackID|VideoID: ${trackID}|${ytpVideoID}`);
2481
+ logger.debug(`SWITCH video for PlayePreviousButton at trackID|VideoID: ${trackID}|${ytpVideoID}`);
2472
2482
  ytPlayer.loadVideoById(ytpVideoID);
2473
2483
 
2474
2484
  // delay after switch video
@@ -2492,7 +2502,6 @@ regenerate: true
2492
2502
 
2493
2503
  // set AJS play_pause button paused
2494
2504
  var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2495
- // setPlayPauseButtonPlaying(playPauseButtonClass);
2496
2505
  togglePlayPauseButton(playPauseButtonClass);
2497
2506
  } else {
2498
2507
  // toggle AJS play_pause button
@@ -2509,7 +2518,7 @@ regenerate: true
2509
2518
  loadCoverImage(songMetaData);
2510
2519
 
2511
2520
  // update meta data
2512
- updatMetaContainers(songMetaData);
2521
+ // ytpUpdatMetaContainers(songMetaData);
2513
2522
 
2514
2523
  // set song at songIndex active in playlist
2515
2524
  setSongActive(playlist, songIndex);
@@ -2523,12 +2532,11 @@ regenerate: true
2523
2532
  event.stopImmediatePropagation();
2524
2533
 
2525
2534
  }); // END EventListener 'click' next button
2526
- } // END if
2535
+ } // END if classString.includes(ytPlayerID)
2527
2536
 
2528
2537
  } // END for largePlayerNextButton
2529
2538
 
2530
2539
  // click on song container
2531
- // TODO: Fix for multiple players in page
2532
2540
  // -------------------------------------------------------------------------
2533
2541
  var largePlayerSongContainer = document.getElementsByClassName("amplitude-song-container");
2534
2542
  for (var i=0; i<largePlayerSongContainer.length; i++) {
@@ -2537,62 +2545,98 @@ regenerate: true
2537
2545
 
2538
2546
  if (classString.includes(ytPlayerID)) {
2539
2547
  largePlayerSongContainer[i].addEventListener('click', function(event) {
2540
- var activeSongSettings, playlist, playerID, playerState,
2548
+ var activeSong, playlist, playerID,
2549
+ playerState, ytPlayerState,
2541
2550
  songs, songIndex, songName, singleAudio, trackID,
2542
- ytPlayer, ytpVideoID;
2551
+ ytPlayer, ytpVideoID, activeSongIndex, isSongIndexChanged;
2543
2552
 
2544
2553
  // set (current) playlist|song data
2545
- playlist = this.getAttribute("data-amplitude-playlist");
2546
- playerID = playlist + '_large';
2547
- songIndex = parseInt(this.getAttribute("data-amplitude-song-index"));
2548
- trackID = songIndex + 1;
2554
+ // -------------------------------------------------------------------
2555
+ playlist = this.getAttribute("data-amplitude-playlist");
2556
+ playerID = playlist + '_large';
2557
+ songIndex = parseInt(this.getAttribute("data-amplitude-song-index"));
2558
+ trackID = songIndex + 1;
2559
+ activeSongIndex = j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex;
2560
+ isSongIndexChanged = (activeSongIndex !== songIndex) ? true : false;
2561
+
2562
+ // set (current) song meta data
2563
+ // -------------------------------------------------------------------
2564
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2565
+ songMetaData = songs[songIndex];
2566
+ songURL = songMetaData.url;
2567
+ ytpVideoID = (ytPlayerErrorTest) ? 'invalidVideoID' : songURL.split('=')[1];
2568
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2569
+ playerState = ytPlayer.getPlayerState();
2570
+ ytPlayerState = (playerState < 0) ? YT_PLAYER_STATE_NAMES[6] : YT_PLAYER_STATE_NAMES[playerState];
2571
+
2572
+ // NOTE:
2573
+ // -------------------------------------------------------------------
2574
+ // unclear why player state 'cued' occurs
2575
+ // -------------------------------------------------------------------
2576
+ // load (cued) video
2577
+ if (ytPlayerState === 'cued') {
2578
+ ytPlayer.playVideo();
2549
2579
 
2550
- // update active song settings (manually)
2551
- checkActiveVideoElementYTP();
2580
+ // wait for API error state
2581
+ setTimeout(() => {
2582
+ if (j1.adapter.amplitude.data.ytpGlobals.ytApiError > 0) {
2583
+ var trackID = songIndex + 1;
2584
+ logger.error(`DISABLED player for playlist|trackID: ${playlist}|${trackID} on API error '${YT_PLAYER_ERROR_NAMES[j1.adapter.amplitude.data.ytpGlobals.ytApiError]}'`);
2552
2585
 
2553
- // get active song settings (manually)
2554
- activeSongSettings = getActiveSong();
2586
+ // do nothing on API errors
2587
+ return;
2588
+ }
2555
2589
 
2556
- if (activeSongSettings) {
2557
- // ytpCurrentTime = activeSongSettings.currentTime;
2558
- if (activeSongSettings.playlist !== playlist) {
2559
- // set current player settings
2560
- songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2561
- ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2590
+ // reset progress bar settings
2591
+ resetProgressBarYTP();
2562
2592
 
2563
- // reset previous player settings
2564
- if (activeSongSettings.player !== undefined) {
2565
- activeSongSettings.player.stopVideo();
2566
- var playPauseButtonClass = `large-player-play-pause-${activeSongSettings.playerID}`;
2567
- togglePlayPauseButton(playPauseButtonClass);
2593
+ var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2594
+ togglePlayPauseButton(playPauseButtonClass);
2595
+
2596
+ // set song at songIndex active in playlist
2597
+ setSongActive(playlist, songIndex);
2598
+
2599
+ // scroll song active at index in player
2600
+ if (playerAutoScrollSongElement) {
2601
+ scrollToActiveElement(playlist);
2568
2602
  }
2569
- } else {
2570
- // set current player settings
2571
- songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2572
- ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2573
- }
2574
- } else {
2575
- // set current player settings
2576
- songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2577
- ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2578
- }
2579
2603
 
2580
- // set (current) song meta data
2581
- songMetaData = songs[songIndex];
2582
- songURL = songMetaData.url;
2583
- ytpVideoID = songURL.split('=')[1];
2584
- playerState = ytPlayer.getPlayerState();
2604
+ // reset|update time settings
2605
+ resetCurrentTimeContainerYTP(ytPlayer, playlist);
2606
+ updateDurationTimeContainerYTP(ytPlayer, playlist);
2585
2607
 
2586
- // TOGGLE state 'playing'|'paused' if video (audio) NOT changed
2587
- var isItemChanged = (j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex !== songIndex) ? true : false;
2588
- if (!isItemChanged && (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED)) {
2608
+ }, 100);
2609
+
2610
+ return;
2611
+ } // END if ytPlayerState === 'cued'
2612
+
2613
+ // TOGGLE state 'playing' => 'paused' if video (audio) NOT changed
2614
+ if (!isSongIndexChanged && ytPlayerState === 'playing') {
2615
+ ytPlayer.pauseVideo();
2616
+ // get active song settings (manually)
2617
+ activeSong = getActiveSong();
2618
+
2619
+ if (activeSong) {
2620
+ // ytpCurrentTime = activeSong.currentTime;
2621
+ if (activeSong.playlist !== playlist) {
2622
+ // set current player settings
2623
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2624
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2625
+ } else {
2626
+ // set current player settings
2627
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2628
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2629
+ }
2630
+ } else {
2631
+ // set current player settings
2632
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2633
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2634
+ }
2589
2635
 
2590
- if (playerState === YT_PLAYER_STATE.PLAYING) {
2591
- ytPlayer.pauseVideo();
2592
2636
  ytPlayerCurrentTime = ytPlayer.getCurrentTime();
2593
2637
 
2594
2638
  var trackID = songIndex + 1;
2595
- logger.debug('\n' + `PAUSE video for PlayerSongContainer on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2639
+ logger.debug(`PAUSE video for PlayerSongContainer on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2596
2640
 
2597
2641
  var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2598
2642
  togglePlayPauseButton(playPauseButtonClass);
@@ -2600,92 +2644,191 @@ regenerate: true
2600
2644
  // reset|update time settings
2601
2645
  resetCurrentTimeContainerYTP(ytPlayer, playlist);
2602
2646
  updateDurationTimeContainerYTP(ytPlayer, playlist);
2603
- return;
2604
- }
2605
2647
 
2606
- if (playerState === YT_PLAYER_STATE.PAUSED) {
2648
+ // save YT player data for later use (e.g. events)
2649
+ // ---------------------------------------------------------------
2650
+ ytpSongIndex = songIndex;
2651
+ j1.modules.amplitudejs.data.ytp.songIndex = songIndex;
2652
+
2653
+ // save YT player GLOBAL data for later use (e.g. events)
2654
+ j1.adapter.amplitude.data.activePlayer = 'ytp';
2655
+ j1.adapter.amplitude.data.ytpGlobals['activeIndex'] = songIndex;
2656
+ j1.adapter.amplitude.data.ytpGlobals['activePlaylist'] = playlist;
2657
+
2658
+ // save YT player data for later use (e.g. events)
2659
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2660
+ j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2661
+
2662
+
2663
+ // save amplitudejs data for later use (e.g. events)
2664
+ // -----------------------------------------------------------------
2665
+ j1.modules.amplitudejs.data.activePlayer = ytPlayer;
2666
+ j1.modules.amplitudejs.data.activeIndex = songIndex;
2667
+ j1.modules.amplitudejs.data.activePlaylist = playlist;
2668
+ j1.modules.amplitudejs.data.ytp.activeIndex = songIndex;
2669
+ j1.modules.amplitudejs.data.ytp.activePlaylist = playlist;
2670
+ j1.modules.amplitudejs.data.ytp.players[playerID].player = ytPlayer;
2671
+ j1.modules.amplitudejs.data.ytp.players[playerID].activeIndex = songIndex;
2672
+ j1.modules.amplitudejs.data.ytp.players[playerID].ytpVideoID = ytpVideoID;
2673
+
2674
+
2675
+ // reset|update current time settings
2676
+ resetCurrentTimeContainerYTP(ytPlayer, playlist);
2677
+ updateDurationTimeContainerYTP(ytPlayer, playlist);
2678
+ resetProgressBarYTP();
2679
+
2680
+ // load the song cover image
2681
+ loadCoverImage(songMetaData);
2682
+
2683
+ // update meta data
2684
+ // ytpUpdatMetaContainers(songMetaData);
2685
+
2686
+ // set song at songIndex active in playlist
2687
+ setSongActive(playlist, songIndex);
2688
+
2689
+ // scroll song active at index in player
2690
+ if (playerAutoScrollSongElement) {
2691
+ scrollToActiveElement(playlist);
2692
+ }
2693
+
2694
+ // save YT player data for later use (e.g. events)
2695
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2696
+ j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2697
+
2698
+ return;
2699
+ } // END if playerState === PLAYING
2700
+
2701
+ // TOGGLE state 'paused' => 'playing' if video (audio) NOT changed
2702
+ if (!isSongIndexChanged && ytPlayerState === 'paused') {
2607
2703
  ytPlayer.playVideo();
2608
2704
  ytpSeekTo(ytPlayer, ytPlayerCurrentTime, true);
2609
2705
 
2706
+ activeSong = getActiveSong();
2707
+ if (activeSong) {
2708
+ // ytpCurrentTime = activeSong.currentTime;
2709
+ if (activeSong.playlist !== playlist) {
2710
+ // set current player settings
2711
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2712
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2713
+ } else {
2714
+ // set current player settings
2715
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2716
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2717
+ }
2718
+ } else {
2719
+ // set current player settings
2720
+ songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
2721
+ ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
2722
+ }
2723
+
2610
2724
  var trackID = songIndex + 1;
2611
- logger.debug('\n' + `PLAY video for PlayerSongContainer on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2725
+ logger.debug(`PLAY video for PlayerSongContainer on playlist|trackID: ${playlist}|${trackID} at: ${ytPlayerCurrentTime}`);
2612
2726
 
2613
2727
  var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2614
2728
  togglePlayPauseButton(playPauseButtonClass);
2615
2729
 
2730
+ // update meta data
2731
+ // ytpUpdatMetaContainers(songMetaData);
2732
+
2616
2733
  // reset|update time settings
2617
2734
  resetCurrentTimeContainerYTP(ytPlayer, playlist);
2618
2735
  updateDurationTimeContainerYTP(ytPlayer, playlist);
2619
- return;
2620
- }
2621
2736
 
2622
- } // END !changedAudio
2737
+ // set song at songIndex active in playlist
2738
+ setSongActive(playlist, songIndex);
2623
2739
 
2624
- // update global song index (start at 0)
2625
- ytpSongIndex = songIndex;
2740
+ return;
2741
+ } // END if playerState === PAUSED
2742
+
2743
+ if (isSongIndexChanged) {
2744
+ // load (next) video
2745
+ // -------------------------------------------------------------------
2746
+ trackID = songIndex + 1;
2747
+ logger.debug(`SWITCH video for PlayerSongContainer at trackID|VideoID: ${trackID}|${ytpVideoID}`);
2748
+ loadVideo(playlist, songIndex)
2626
2749
 
2627
- // stop active AT|YT players
2628
- // stopAllActivePlayers(playerID);
2750
+ // wait for API error state
2751
+ setTimeout(() => {
2752
+ if (j1.adapter.amplitude.data.ytpGlobals.ytApiError > 0) {
2753
+ var trackID = songIndex + 1;
2754
+ logger.error(`DISABLED player for playlist|trackID: ${playlist}|${trackID} on API error '${YT_PLAYER_ERROR_NAMES[j1.adapter.amplitude.data.ytpGlobals.ytApiError]}'`);
2629
2755
 
2630
- // save YT player GLOBAL data for later use (e.g. events)
2631
- j1.adapter.amplitude.data.activePlayer = 'ytp';
2632
- j1.adapter.amplitude.data.ytpGlobals['activeIndex'] = songIndex;
2633
- j1.adapter.amplitude.data.ytpGlobals['activePlaylist'] = playlist;
2756
+ // do nothing on API errors
2757
+ return;
2758
+ }
2634
2759
 
2635
- // save YT player data for later use (e.g. events)
2636
- j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2637
- j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2760
+ // save YT player data for later use (e.g. events)
2761
+ // -------------------------------------------------------------
2762
+ ytpSongIndex = songIndex;
2763
+ j1.modules.amplitudejs.data.ytp.songIndex = songIndex;
2638
2764
 
2639
- // reset|update current time settings
2640
- resetCurrentTimeContainerYTP(ytPlayer, playlist);
2641
- updateDurationTimeContainerYTP(ytPlayer, playlist);
2642
- resetProgressBarYTP();
2765
+ // save YT player GLOBAL data for later use (e.g. events)
2766
+ j1.adapter.amplitude.data.activePlayer = 'ytp';
2767
+ j1.adapter.amplitude.data.ytpGlobals['activeIndex'] = songIndex;
2768
+ j1.adapter.amplitude.data.ytpGlobals['activePlaylist'] = playlist;
2643
2769
 
2644
- // load the song cover image
2645
- loadCoverImage(songMetaData);
2770
+ // save YT player data for later use (e.g. events)
2771
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2772
+ j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2646
2773
 
2647
- // update meta data
2648
- updatMetaContainers(songMetaData);
2649
2774
 
2650
- // set AJS play_pause button playing
2651
- var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2652
- setPlayPauseButtonPlaying(playPauseButtonClass)
2775
+ // save amplitudejs data for later use (e.g. events)
2776
+ // -------------------------------------------------------------
2777
+ j1.modules.amplitudejs.data.activePlayer = 'ytp';
2778
+ j1.modules.amplitudejs.data.activeIndex = songIndex;
2779
+ j1.modules.amplitudejs.data.activePlaylist = playlist;
2780
+ j1.modules.amplitudejs.data.ytp.songIndex = songIndex;
2781
+ j1.modules.amplitudejs.data.ytp.activeIndex = songIndex;
2782
+ j1.modules.amplitudejs.data.ytp.activePlaylist = playlist;
2783
+ j1.modules.amplitudejs.data.ytp.players[playerID].player = ytPlayer;
2784
+ j1.modules.amplitudejs.data.ytp.players[playerID].activeIndex = songIndex;
2785
+ j1.modules.amplitudejs.data.ytp.players[playerID].ytpVideoID = ytpVideoID;
2653
2786
 
2654
- // set song at songIndex active in playlist
2655
- setSongActive(playlist, songIndex);
2656
2787
 
2657
- // scroll song active at index in player
2658
- if (playerAutoScrollSongElement) {
2659
- scrollToActiveElement(playlist);
2660
- }
2788
+ // reset|update current time settings
2789
+ resetCurrentTimeContainerYTP(ytPlayer, playlist);
2790
+ updateDurationTimeContainerYTP(ytPlayer, playlist);
2791
+ resetProgressBarYTP();
2661
2792
 
2662
- // save YT player data for later use (e.g. events)
2663
- j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2664
- j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2793
+ // load the song cover image
2794
+ loadCoverImage(songMetaData);
2665
2795
 
2666
- // load next video
2667
- // -------------------------------------------------------------------
2668
- trackID = songIndex + 1;
2669
- logger.debug('\n' + `SWITCH video for PlayerSongContainer at trackID|VideoID: ${trackID}|${ytpVideoID}`);
2670
- ytPlayer.loadVideoById(ytpVideoID);
2796
+ // update meta data
2797
+ // ytpUpdatMetaContainers(songMetaData);
2671
2798
 
2672
- // mute sound after next video load
2673
- // -------------------------------------------------------------------
2674
- if (muteAfterVideoSwitchInterval) {
2675
- ytPlayer.mute();
2676
- setTimeout(() => {
2677
- ytPlayer.unMute();
2678
- }, muteAfterVideoSwitchInterval);
2679
- }
2799
+ var playPauseButtonClass = `large-player-play-pause-${ytPlayerID}`;
2800
+ togglePlayPauseButton(playPauseButtonClass);
2680
2801
 
2681
- // deactivate AJS events (if any)
2682
- event.stopImmediatePropagation();
2683
- }); // END EventListener 'click' SongContainer
2684
- } // END ifSWITCH video
2685
- } // END for
2802
+ // set song at songIndex active in playlist
2803
+ setSongActive(playlist, songIndex);
2804
+
2805
+ // scroll song active at index in player
2806
+ if (playerAutoScrollSongElement) {
2807
+ scrollToActiveElement(playlist);
2808
+ }
2809
+
2810
+ // save YT player data for later use (e.g. events)
2811
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
2812
+ // j1.adapter.amplitude.data.ytPlayers[playerID].videoID = ytpVideoID;
2813
+
2814
+ // mute sound after next video load
2815
+ // -------------------------------------------------------------------
2816
+ if (muteAfterVideoSwitchInterval) {
2817
+ ytPlayer.mute();
2818
+ setTimeout(() => {
2819
+ ytPlayer.unMute();
2820
+ }, muteAfterVideoSwitchInterval);
2821
+ }
2822
+ }, 100); // END timeout
2823
+ } // END if isSongIndexChanged
2824
+
2825
+ // deactivate AJS events (if any)
2826
+ event.stopImmediatePropagation();
2827
+ }); // END EventListener
2828
+ } // END if classString
2829
+ } // END for largePlayerSongContainer
2686
2830
 
2687
2831
  // add listeners to all progress bars found
2688
- // TODO: Fix for multiple players in page
2689
2832
  // -------------------------------------------------------------------------
2690
2833
  var progressBars = document.getElementsByClassName("large-player-progress");
2691
2834
  if (progressBars.length) {
@@ -2705,30 +2848,24 @@ regenerate: true
2705
2848
  j1.adapter.amplitude.data.ytPlayers[playerID].progressBar = progressBar;
2706
2849
 
2707
2850
  progressBars[i].addEventListener('click', function(event) {
2708
- var activeSongSettings, playlist, ytPlayer,
2709
- playerState, progressBar, percentage, time;
2851
+ var activeSong, playlist, ytPlayer,
2852
+ playerState, progressBar, percentage, time;
2710
2853
 
2711
- // update active song settings (manually)
2712
- checkActiveVideoElementYTP();
2713
-
2714
- // get active song settings (manually)
2715
- activeSongSettings = getActiveSong();
2716
-
2717
- if (!activeSongSettings) {
2718
- // do nothing if current video (audio) item is NOT selected|active
2854
+ activeSong = getActiveSong();
2855
+ if (!activeSong) {
2856
+ // do nothing if activeSong data is missing (failsafe)
2719
2857
  return;
2720
2858
  }
2721
2859
 
2722
2860
  playlist = this.getAttribute("data-amplitude-playlist");
2723
- if (activeSongSettings.playlist !== playlist) {
2724
- // do nothing on PREVIOUS playlist (player)
2861
+ if (activeSong.playlist !== playlist) {
2862
+ // do nothing on PREVIOUS playlist
2725
2863
  return;
2726
2864
  }
2727
2865
 
2728
- ytPlayer = activeSongSettings.player;
2866
+ ytPlayer = activeSong.player;
2729
2867
  playerState = ytPlayer.getPlayerState();
2730
2868
 
2731
- //if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.BUFFERING) {
2732
2869
  if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.BUFFERING) {
2733
2870
  progressBar = this;
2734
2871
  percentage = getProgressBarSelectedPositionPercentage(event, progressBar);
@@ -2753,96 +2890,82 @@ regenerate: true
2753
2890
  } // END if progressBars
2754
2891
 
2755
2892
  // add listeners to all volume sliders found
2756
- // TODO: Fix for multiple players in page
2757
2893
  // -------------------------------------------------------------------------
2758
2894
  var volumeSliders = document.getElementsByClassName("amplitude-volume-slider");
2759
2895
  for (var i=0; i<volumeSliders.length; i++) {
2760
2896
  if (volumeSliders[i].dataset.amplitudeSource === 'audio') {
2761
2897
  // do nothing (managed by adapter)
2762
- var bla = 1;
2763
2898
  } else {
2764
2899
  if (volumeSliders[i]) {
2765
- // for (var i=0; i<volumeSliders.length; i++) {
2766
- var volumeSlider = volumeSliders[i];
2767
- var sliderID = volumeSliders[i].id;
2768
- var playerID = sliderID.split('volume_slider_')[1];
2900
+ var volumeSlider = volumeSliders[i];
2901
+ var sliderID = volumeSliders[i].id;
2902
+ var playerID = sliderID.split('volume_slider_')[1];
2769
2903
 
2770
- // save YT player data for later use (e.g. events)
2771
- // j1.adapter.amplitude.data.ytPlayers[playerID].volumeSlider = volumeSlider;
2904
+ // save YT player data for later use (e.g. events)
2905
+ if (volumeSlider.dataset.amplitudeSource === 'youtube') {
2906
+ j1.adapter.amplitude.data.ytPlayers[playerID].volumeSlider = volumeSlider;
2907
+ }
2772
2908
 
2773
- volumeSliders[i].addEventListener('click', function(event) {
2909
+ volumeSliders[i].addEventListener('click', function(event) {
2910
+ var activeSong = getActiveSong();
2774
2911
 
2775
- // update active song settings (manually)
2776
- checkActiveVideoElementYTP();
2777
-
2778
- // get active song settings (manually)
2779
- var activeSongSettings = getActiveSong();
2912
+ if (!activeSong) {
2913
+ // do nothing if activeSong data is missing (failsafe)
2914
+ return;
2915
+ }
2780
2916
 
2781
- if (!activeSongSettings) {
2782
- // do nothing if current video (audio) item is NOT selected|active
2783
- return;
2784
- }
2785
-
2786
- var ytPlayer = activeSongSettings.player;
2787
- var playerState = ytPlayer.getPlayerState();
2917
+ var ytPlayer = activeSong.player;
2918
+ var playerState = ytPlayer.getPlayerState();
2788
2919
 
2789
- if ((playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) && ytPlayer !== undefined) {
2790
- var volumeSlider, volumeValue;
2791
- var currenVolume = ytPlayer.getVolume();
2920
+ if ((playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) && ytPlayer !== undefined) {
2921
+ var volumeSlider, volumeValue;
2922
+ var currenVolume = ytPlayer.getVolume();
2792
2923
 
2793
- volumeSlider = this;
2794
- volumeValue = 50; // default
2924
+ volumeSlider = this;
2925
+ volumeValue = 50; // default
2795
2926
 
2796
- if (volumeSlider !== null) {
2797
- volumeValue = parseInt(volumeSlider.value);
2798
- }
2927
+ if (volumeSlider !== null) {
2928
+ volumeValue = parseInt(volumeSlider.value);
2929
+ }
2799
2930
 
2800
- ytPlayer.setVolume(volumeValue);
2801
- } // END if ytPlayer
2931
+ ytPlayer.setVolume(volumeValue);
2932
+ } // END if ytPlayer
2802
2933
 
2803
- }); // END EventListener 'click'
2804
- // } // END for
2934
+ }); // END EventListener 'click'
2805
2935
  } // END if volumeSliders
2806
2936
  } // END if volumeSliders
2807
2937
  } // END for volumeSliders
2808
2938
 
2809
2939
  // add listeners to all mute buttons found
2810
- // TODO: Fix for multiple buttons in page
2811
2940
  // -------------------------------------------------------------------------
2812
2941
  var volumeMutes = document.getElementsByClassName("amplitude-mute");
2813
2942
  for (var i=0; i<volumeMutes.length; i++) {
2814
2943
  if (volumeMutes[i].dataset.amplitudeSource === 'audio') {
2815
2944
  // do nothing (managed by adapter)
2816
- var bla = 1;
2817
2945
  } else {
2818
2946
  if (volumeMutes[i]) {
2819
2947
  var volumMute = volumeMutes[i];
2820
2948
  var sliderID = volumeMutes[i].id;
2821
2949
  var playerID = sliderID.split('amplitude-mute_')[1];
2822
2950
 
2823
- // save YT player data for later use (e.g. events)
2824
- // j1.adapter.amplitude.data.ytPlayers[playerID].volumMute = volumMute;
2825
-
2826
2951
  volumeMutes[i].addEventListener('click', function(event) {
2952
+ var activeSong = getActiveSong();
2827
2953
 
2828
- // update active song settings (manually)
2829
- checkActiveVideoElementYTP();
2830
-
2831
- // get active song settings (manually)
2832
- var activeSongSettings = getActiveSong();
2833
-
2834
- if (!activeSongSettings) {
2835
- // do nothing if current video (audio) item is NOT selected|active
2954
+ if (!activeSong) {
2955
+ // do nothing if activeSong data is missing (failsafe)
2836
2956
  return;
2837
2957
  }
2838
2958
 
2839
- var ytPlayer = activeSongSettings.player;
2959
+ var ytPlayer = activeSong.player;
2840
2960
  var playerState = ytPlayer.getPlayerState();
2841
2961
  var volumeSlider = j1.adapter.amplitude.data.ytPlayers[playerID].volumeSlider;
2842
2962
  var currenVolume = ytPlayer.getVolume();
2843
2963
  var playerVolumePreset = parseInt(j1.adapter.amplitude.data.ytPlayers[playerID].playerSettings.volume_slider.preset_value);
2844
-
2845
- if ((playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) && ytPlayer !== undefined) {
2964
+ var playerState = (ytPlayer.getPlayerState() > 0) ? ytPlayer.getPlayerState() : 6;
2965
+ var ytPlayerState = YT_PLAYER_STATE_NAMES[playerState];
2966
+
2967
+ var isValidPlayerState = /playing|paused/.test(ytPlayerState);
2968
+ if (isValidPlayerState && ytPlayer !== undefined) {
2846
2969
  if (currenVolume > 0) {
2847
2970
  volumeSlider.value = 0;
2848
2971
  ytPlayer.setVolume(0);
@@ -2860,8 +2983,7 @@ regenerate: true
2860
2983
 
2861
2984
  } // END if playerSettings.type 'large'
2862
2985
 
2863
- }
2864
-
2986
+ } // END if j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID] !== undefined
2865
2987
  } // END mimikYTPlayerUiEventsForAJS
2866
2988
 
2867
2989
  {%- endcapture -%}