cloudinary-video-player 1.6.2-edge.13

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 (226) hide show
  1. package/.eslintignore +4 -0
  2. package/.snyk +19 -0
  3. package/.travis.yml +8 -0
  4. package/CHANGELOG.md +329 -0
  5. package/LICENSE +21 -0
  6. package/README.md +87 -0
  7. package/dist/cld-video-player.css +2110 -0
  8. package/dist/cld-video-player.js +5249 -0
  9. package/dist/cld-video-player.light.css +1766 -0
  10. package/dist/cld-video-player.light.js +1399 -0
  11. package/dist/cld-video-player.light.min.css +1 -0
  12. package/dist/cld-video-player.light.min.js +2 -0
  13. package/dist/cld-video-player.light.min.js.LICENSE.txt +23 -0
  14. package/dist/cld-video-player.min.css +1 -0
  15. package/dist/cld-video-player.min.js +2 -0
  16. package/dist/cld-video-player.min.js.LICENSE.txt +26 -0
  17. package/dist/fonts/cloudinary_icon_for_black_bg.svg +69 -0
  18. package/dist/fonts/cloudinary_icon_for_white_bg.svg +69 -0
  19. package/docs/360.html +102 -0
  20. package/docs/_template.html +93 -0
  21. package/docs/adaptive-streaming.html +297 -0
  22. package/docs/analytics.html +140 -0
  23. package/docs/api.html +302 -0
  24. package/docs/audio.html +136 -0
  25. package/docs/autoplay-fallback.html +138 -0
  26. package/docs/autoplay-on-scroll.html +107 -0
  27. package/docs/codec-fallback.html +158 -0
  28. package/docs/colors.html +135 -0
  29. package/docs/components.html +284 -0
  30. package/docs/custom-cld-errors.html +134 -0
  31. package/docs/floating-player.html +98 -0
  32. package/docs/fluid.html +117 -0
  33. package/docs/force-hls-subtitles-ios.html +159 -0
  34. package/docs/index.html +83 -0
  35. package/docs/interaction-area.html +398 -0
  36. package/docs/live-customer.html +128 -0
  37. package/docs/multiple-players.html +125 -0
  38. package/docs/playlist-by-tag-cap.html +182 -0
  39. package/docs/playlist-by-tag.html +133 -0
  40. package/docs/playlist.html +133 -0
  41. package/docs/poster.html +155 -0
  42. package/docs/raw-url.html +104 -0
  43. package/docs/recommendations.html +155 -0
  44. package/docs/scripts.js +156 -0
  45. package/docs/seek-thumbs.html +90 -0
  46. package/docs/shoppable.html +335 -0
  47. package/docs/subtitles-and-captions.html +267 -0
  48. package/docs/transformations.html +171 -0
  49. package/docs/ui-config.html +108 -0
  50. package/docs/vast-vpaid.html +149 -0
  51. package/env.example.js +6 -0
  52. package/env.js +6 -0
  53. package/jest-puppeteer.config.js +14 -0
  54. package/jest.config.js +196 -0
  55. package/package.json +99 -0
  56. package/sandbox.config.json +3 -0
  57. package/setupJest.js +1 -0
  58. package/src/assets/fonts/VideoJS.svg +120 -0
  59. package/src/assets/fonts/VideoJS.ttf +0 -0
  60. package/src/assets/fonts/VideoJS.woff +0 -0
  61. package/src/assets/fonts/icons.json +120 -0
  62. package/src/assets/icons/cloudinary_icon_for_black_bg.svg +69 -0
  63. package/src/assets/icons/cloudinary_icon_for_white_bg.svg +69 -0
  64. package/src/assets/icons/cloudinary_logo_for_dark_bg.svg +188 -0
  65. package/src/assets/icons/cloudinary_logo_for_white_bg.svg +188 -0
  66. package/src/assets/icons/info-circle.svg +17 -0
  67. package/src/assets/styles/ads-label.scss +16 -0
  68. package/src/assets/styles/components/interaction-areas.scss +158 -0
  69. package/src/assets/styles/components/playlist.scss +213 -0
  70. package/src/assets/styles/components/themedButton.scss +48 -0
  71. package/src/assets/styles/components/thumbnail.scss +94 -0
  72. package/src/assets/styles/components/title-bar.scss +67 -0
  73. package/src/assets/styles/components/triangle-volume-bar.scss +52 -0
  74. package/src/assets/styles/icons.scss +257 -0
  75. package/src/assets/styles/main.scss +324 -0
  76. package/src/assets/styles/mixins/aspect-ratio.scss +16 -0
  77. package/src/assets/styles/mixins/disable-transition.scss +3 -0
  78. package/src/assets/styles/mixins/mixins.scss +5 -0
  79. package/src/assets/styles/mixins/skin.scss +64 -0
  80. package/src/assets/styles/variables.scss +2 -0
  81. package/src/assets/styles/videojs-ima.scss +252 -0
  82. package/src/components/component-utils.js +20 -0
  83. package/src/components/index.js +21 -0
  84. package/src/components/interaction-area/interaction-area.const.js +30 -0
  85. package/src/components/interaction-area/interaction-area.service.js +223 -0
  86. package/src/components/interaction-area/interaction-area.utils.js +236 -0
  87. package/src/components/jumpButtons/jump-10-minus.js +21 -0
  88. package/src/components/jumpButtons/jump-10-plus.js +20 -0
  89. package/src/components/logoButton/logo-button.const.js +3 -0
  90. package/src/components/logoButton/logo-button.js +30 -0
  91. package/src/components/logoButton/logo-button.scss +15 -0
  92. package/src/components/playlist/components/playlist-button.js +34 -0
  93. package/src/components/playlist/components/playlist-next-button.js +18 -0
  94. package/src/components/playlist/components/playlist-previous-button.js +18 -0
  95. package/src/components/playlist/components/playlist.js +5 -0
  96. package/src/components/playlist/components/playlist.scss +15 -0
  97. package/src/components/playlist/components/upcoming-video-overlay.js +149 -0
  98. package/src/components/playlist/components/upcoming-video-overlay.scss +86 -0
  99. package/src/components/playlist/layout/playlist-layout-custom.js +21 -0
  100. package/src/components/playlist/layout/playlist-layout-horizontal.js +16 -0
  101. package/src/components/playlist/layout/playlist-layout-vertical.js +19 -0
  102. package/src/components/playlist/layout/playlist-layout.js +110 -0
  103. package/src/components/playlist/panel/playlist-panel-item.js +86 -0
  104. package/src/components/playlist/panel/playlist-panel.js +92 -0
  105. package/src/components/playlist/playlist-widget.js +119 -0
  106. package/src/components/playlist/playlist.const.js +14 -0
  107. package/src/components/playlist/playlist.js +413 -0
  108. package/src/components/playlist/thumbnail/thumbnail.js +69 -0
  109. package/src/components/progress-control-events-blocker/progress-control-events-blocker.js +17 -0
  110. package/src/components/qualitySelector/quality-selector.scss +10 -0
  111. package/src/components/qualitySelector/qualitySelector.js +152 -0
  112. package/src/components/recommendations-overlay/index.js +3 -0
  113. package/src/components/recommendations-overlay/recommendations-overlay-content.js +57 -0
  114. package/src/components/recommendations-overlay/recommendations-overlay-hide-button.js +18 -0
  115. package/src/components/recommendations-overlay/recommendations-overlay-item.js +35 -0
  116. package/src/components/recommendations-overlay/recommendations-overlay-primary-item.js +81 -0
  117. package/src/components/recommendations-overlay/recommendations-overlay-secondary-item.js +48 -0
  118. package/src/components/recommendations-overlay/recommendations-overlay-secondary-items-container.js +35 -0
  119. package/src/components/recommendations-overlay/recommendations-overlay.js +94 -0
  120. package/src/components/recommendations-overlay/recommendations-overlay.scss +182 -0
  121. package/src/components/shoppable-bar/layout/bar-layout.js +111 -0
  122. package/src/components/shoppable-bar/layout/shoppable-panel-toggle.js +64 -0
  123. package/src/components/shoppable-bar/layout/shoppable-products-overlay.js +87 -0
  124. package/src/components/shoppable-bar/panel/shoppable-panel-item.js +105 -0
  125. package/src/components/shoppable-bar/panel/shoppable-panel.js +172 -0
  126. package/src/components/shoppable-bar/shoppable-post-widget.js +110 -0
  127. package/src/components/shoppable-bar/shoppable-widget.const.js +52 -0
  128. package/src/components/shoppable-bar/shoppable-widget.js +111 -0
  129. package/src/components/shoppable-bar/shoppable-widget.scss +359 -0
  130. package/src/components/themeButton/themedButton.const.js +3 -0
  131. package/src/components/themeButton/themedButton.js +25 -0
  132. package/src/components/title-bar/title-bar.js +79 -0
  133. package/src/config/defaults.js +25 -0
  134. package/src/extended-events.js +228 -0
  135. package/src/index.js +18 -0
  136. package/src/mixins/eventable.js +54 -0
  137. package/src/mixins/playlistable.js +106 -0
  138. package/src/plugins/analytics/index.js +245 -0
  139. package/src/plugins/autoplay-on-scroll/index.js +86 -0
  140. package/src/plugins/cloudinary/common.js +216 -0
  141. package/src/plugins/cloudinary/event-handler-registry.js +46 -0
  142. package/src/plugins/cloudinary/index.js +345 -0
  143. package/src/plugins/cloudinary/models/audio-source/audio-source.const.js +11 -0
  144. package/src/plugins/cloudinary/models/audio-source/audio-source.js +82 -0
  145. package/src/plugins/cloudinary/models/base-source.js +107 -0
  146. package/src/plugins/cloudinary/models/image-source.js +26 -0
  147. package/src/plugins/cloudinary/models/video-source/video-source.const.js +32 -0
  148. package/src/plugins/cloudinary/models/video-source/video-source.js +239 -0
  149. package/src/plugins/cloudinary/models/video-source/video-source.utils.js +57 -0
  150. package/src/plugins/colors/index.js +303 -0
  151. package/src/plugins/context-menu/components/context-menu-item.js +12 -0
  152. package/src/plugins/context-menu/components/context-menu.js +63 -0
  153. package/src/plugins/context-menu/context-menu.scss +30 -0
  154. package/src/plugins/context-menu/contextMenuContent.js +53 -0
  155. package/src/plugins/context-menu/index.js +134 -0
  156. package/src/plugins/dash/index.js +26 -0
  157. package/src/plugins/dash/setup-audio-tracks.js +112 -0
  158. package/src/plugins/dash/setup-text-tracks.js +195 -0
  159. package/src/plugins/dash/videojs-dash.js +372 -0
  160. package/src/plugins/floating-player/floating-player.scss +74 -0
  161. package/src/plugins/floating-player/index.js +129 -0
  162. package/src/plugins/ima/index.js +1775 -0
  163. package/src/plugins/index.js +31 -0
  164. package/src/plugins/interactive-plugin/index.js +10 -0
  165. package/src/plugins/videojs-http-source-selector/components/SourceMenuButton.js +98 -0
  166. package/src/plugins/videojs-http-source-selector/components/SourceMenuItem.js +52 -0
  167. package/src/plugins/videojs-http-source-selector/plugin.js +82 -0
  168. package/src/plugins/videojs-http-source-selector/plugin.scss +9 -0
  169. package/src/plugins/vtt-thumbnails/index.js +526 -0
  170. package/src/plugins/vtt-thumbnails/vtt-thumbnails.scss +29 -0
  171. package/src/utils/api.js +32 -0
  172. package/src/utils/apply-with-props.js +32 -0
  173. package/src/utils/array.js +22 -0
  174. package/src/utils/assign.js +27 -0
  175. package/src/utils/attributes-normalizer.js +72 -0
  176. package/src/utils/cloudinary.js +165 -0
  177. package/src/utils/css-prefix.js +43 -0
  178. package/src/utils/dom.js +74 -0
  179. package/src/utils/find.js +28 -0
  180. package/src/utils/fontFace.js +25 -0
  181. package/src/utils/groupBy.js +12 -0
  182. package/src/utils/index.js +29 -0
  183. package/src/utils/matches.js +11 -0
  184. package/src/utils/mixin.js +5 -0
  185. package/src/utils/object.js +26 -0
  186. package/src/utils/playButton.js +9 -0
  187. package/src/utils/positioning.js +78 -0
  188. package/src/utils/querystring.js +12 -0
  189. package/src/utils/slicing.js +21 -0
  190. package/src/utils/string.js +15 -0
  191. package/src/utils/throttle.js +30 -0
  192. package/src/utils/time.js +77 -0
  193. package/src/utils/type-inference.js +35 -0
  194. package/src/validators/validators-functions.js +48 -0
  195. package/src/validators/validators-types.js +78 -0
  196. package/src/validators/validators.js +110 -0
  197. package/src/video-player.const.js +68 -0
  198. package/src/video-player.js +761 -0
  199. package/src/video-player.utils.js +123 -0
  200. package/test/adaptive-streaming.test.js +38 -0
  201. package/test/ads.test.js +35 -0
  202. package/test/analytics.test.js +111 -0
  203. package/test/api.test.js +111 -0
  204. package/test/autoplay.scroll.test.js +23 -0
  205. package/test/basic-ui.test.js +59 -0
  206. package/test/colors.test.js +58 -0
  207. package/test/components.test.js +21 -0
  208. package/test/custom-error.test.js +24 -0
  209. package/test/fluid.test.js +36 -0
  210. package/test/isValidConfig.test.js +224 -0
  211. package/test/mocks/cloudinary-core-mock.js +0 -0
  212. package/test/mocks/styleMock.js +1 -0
  213. package/test/multiplayer.test.js +25 -0
  214. package/test/playlist.test.js +60 -0
  215. package/test/puppeteer/vp-env.js +19 -0
  216. package/test/recommendations.test.js +38 -0
  217. package/test/title-bar.test.js +28 -0
  218. package/test/ui-conf.test.js +49 -0
  219. package/test/unit/cloudinaryConfig.test.js +22 -0
  220. package/test/unit/cloudinaryUtils.test.js +53 -0
  221. package/test/unit/utils.test.js +27 -0
  222. package/test/unit/videoSource.test.js +454 -0
  223. package/tsconfig.json +15 -0
  224. package/types/video-player-tests.js +12 -0
  225. package/types/video-player-tests.ts +31 -0
  226. package/types/video-player.d.ts +570 -0
@@ -0,0 +1,252 @@
1
+ .cld-video-player {
2
+ .ima-fullscreen-div, .ima-mute-div, .ima-play-pause-div, .ima-slider-div {
3
+ line-height: 1.7;
4
+ }
5
+
6
+ &.vjs-ad-loading {
7
+ > video,
8
+ > .vjs-poster {
9
+ opacity: 0;
10
+ }
11
+ }
12
+ }
13
+
14
+ .ima-ad-container {
15
+ top: 0;
16
+ left: 0;
17
+ position: absolute;
18
+ display: block;
19
+ width: 100%;
20
+ height: 100%;
21
+ video {
22
+ left: 0;
23
+ }
24
+ }
25
+
26
+ /* Move overlay if user fast-clicks play button. */
27
+ .video-js.vjs-playing .bumpable-ima-ad-container {
28
+ margin-top: -50px;
29
+ }
30
+
31
+ /* Move overlay when controls are active. */
32
+ .video-js.vjs-user-inactive.vjs-playing .bumpable-ima-ad-container {
33
+ margin-top: 0px;
34
+ }
35
+
36
+ .video-js.vjs-paused .bumpable-ima-ad-container,
37
+ .video-js.vjs-playing:hover .bumpable-ima-ad-container,
38
+ .video-js.vjs-user-active.vjs-playing .bumpable-ima-ad-container {
39
+ margin-top: -50px;
40
+ }
41
+
42
+ .vjs-ima-non-linear .vjs-big-play-button,
43
+ .vjs-ima-non-linear .vjs-menu.vjs-settings-menu,
44
+ .vjs-ima-non-linear .vjs-info-overlay,
45
+ .vjs-ima-non-linear .vjs-modal-overlay,
46
+ .vjs-ima-non-linear .vjs-control-bar {
47
+ z-index: 1112;
48
+ }
49
+
50
+ .ima-controls-div {
51
+ bottom:0px;
52
+ height: 37px;
53
+ position: absolute;
54
+ overflow: hidden;
55
+ display: none;
56
+ opacity: 1;
57
+ background-color: rgba(7, 20, 30, .7);
58
+ background: -moz-linear-gradient(
59
+ bottom,
60
+ rgba(7, 20, 30, .7) 0%,
61
+ rgba(7, 20, 30, 0) 100%); /* FF3.6+ */
62
+ background: -webkit-gradient(
63
+ linear,
64
+ left bottom,
65
+ left top,
66
+ color-stop(0%,rgba(7, 20, 30, .7)),
67
+ color-stop(100%,rgba(7, 20, 30, 0))); /* Chrome,Safari4+ */
68
+ background: -webkit-linear-gradient(
69
+ bottom,
70
+ rgba(7, 20, 30, .7) 0%,
71
+ rgba(7, 20, 30, 0) 100%); /* Chrome10+,Safari5.1+ */
72
+ background: -o-linear-gradient(bottom,
73
+ rgba(7, 20, 30, .7) 0%,
74
+ rgba(7, 20, 30, 0) 100%); /* Opera 11.10+ */
75
+ background: -ms-linear-gradient(bottom,
76
+ rgba(7, 20, 30, .7) 0%,
77
+ rgba(7, 20, 30, 0) 100%); /* IE10+ */
78
+ background: linear-gradient(to top,
79
+ rgba(7, 20, 30, .7) 0%,
80
+ rgba(7, 20, 30, 0) 100%); /* W3C */
81
+ filter: progid:DXImageTransform.Microsoft.gradient(
82
+ startColorstr='#0007141E',
83
+ endColorstr='#07141E',GradientType=0 ); /* IE6-9 */
84
+ }
85
+
86
+ .ima-countdown-div {
87
+ height: 10px;
88
+ color: #FFFFFF;
89
+ text-shadow: 0 0 0.2em #000;
90
+ cursor: default;
91
+ }
92
+
93
+ .ima-seek-bar-div {
94
+ top: 12px;
95
+ height: 3px;
96
+ position: absolute;
97
+ background: rgba(255, 255, 255, .4);
98
+ }
99
+
100
+ .ima-progress-div {
101
+ width: 0px;
102
+ height: 3px;
103
+ background-color: #ECC546;
104
+ }
105
+
106
+ .ima-play-pause-div, .ima-mute-div, .ima-slider-div, .ima-fullscreen-div {
107
+ width: 35px;
108
+ height: 20px;
109
+ top: 11px;
110
+ left: 0px;
111
+ position: absolute;
112
+ color: #CCCCCC;
113
+ font-size: 1.5em;
114
+ line-height: 2;
115
+ text-align: center;
116
+ font-family: VideoJS;
117
+ cursor: pointer;
118
+ }
119
+
120
+ .ima-mute-div {
121
+ left: auto;
122
+ right: 85px;
123
+ }
124
+
125
+ .ima-slider-div {
126
+ left: auto;
127
+ right: 35px;
128
+ width: 50px;
129
+ height: 10px;
130
+ top: 20px;
131
+ background-color: #555555;
132
+ }
133
+
134
+ .ima-slider-level-div {
135
+ width: 100%;
136
+ height: 10px;
137
+ background-color: #ECC546;
138
+ }
139
+
140
+ .ima-fullscreen-div {
141
+ left: auto;
142
+ right: 0px;
143
+ }
144
+
145
+ .ima-playing:before {
146
+ content: "\00f103";
147
+ }
148
+
149
+ .ima-paused:before {
150
+ content: "\00f101";
151
+ }
152
+
153
+ .ima-playing:hover:before, .ima-paused:hover:before {
154
+ text-shadow: 0 0 1em #fff;
155
+ }
156
+
157
+ .ima-non-muted:before {
158
+ content: "\00f107";
159
+ }
160
+
161
+ .ima-muted:before {
162
+ content: "\00f104";
163
+ }
164
+
165
+ .ima-non-muted:hover:before, .ima-muted:hover:before {
166
+ text-shadow: 0 0 1em #fff;
167
+ }
168
+
169
+ .ima-non-fullscreen:before {
170
+ content: "\00f108";
171
+ }
172
+
173
+ .ima-fullscreen:before {
174
+ content: "\00f109";
175
+ }
176
+
177
+ .ima-non-fullscreen:hover:before, .ima-fullscreen:hover:before {
178
+ text-shadow: 0 0 1em #fff;
179
+ }
180
+
181
+ .video-js.vjs-ad-playing .vjs-control-bar {
182
+ z-index: 1112;
183
+ }
184
+
185
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control {
186
+ pointer-events: none;
187
+ }
188
+
189
+ .video-js.vjs-ad-playing .vjs-control-bar>:not(.vjs-play-control):not(.vjs-volume-menu-button):not(.vjs-time-control):not(.vjs-progress-control):not(.vjs-spacer):not(.vjs-fullscreen-control):not(.vjs-gradient):not(.ima-countdown-div),
190
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-mouse-display-tooltip,
191
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control:before,
192
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-play-progress:before,
193
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control .vjs-load-progress,
194
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control .vjs-mouse-display {
195
+ display: none;
196
+ }
197
+
198
+ .video-js.vjs-ad-playing .vjs-control-bar {
199
+ transition: height 0.1s ease;
200
+ }
201
+
202
+ .video-js.vjs-ad-playing.vjs-user-inactive:not(.vjs-ad-paused) .vjs-control-bar {
203
+ opacity: 1;
204
+ height: 0;
205
+ }
206
+
207
+ .video-js.vjs-ad-playing.vjs-user-inactive:not(.vjs-ad-paused) .vjs-control-bar .vjs-progress-holder {
208
+ margin: 0;
209
+ }
210
+
211
+ .video-js.vjs-ad-playing .vjs-control-bar>:not(.vjs-progress-control):not(.ima-countdown-div) {
212
+ transition: opacity 0.1s ease, visibility 0.1s ease;
213
+ }
214
+
215
+ .video-js.vjs-ad-playing .vjs-control-bar>:not(.vjs-progress-control):not(.ima-countdown-div) div{
216
+ transition: line-height 0.1s ease;
217
+ }
218
+
219
+ .video-js.vjs-ad-playing.vjs-user-inactive:not(.vjs-ad-paused) .vjs-control-bar>:not(.vjs-progress-control):not(.ima-countdown-div) {
220
+ opacity: 0;
221
+ visibility: hidden;
222
+ overflow: hidden;
223
+ }
224
+
225
+ .video-js.vjs-ad-playing.vjs-user-inactive:not(.vjs-ad-paused) .vjs-control-bar>:not(.vjs-progress-control):not(.ima-countdown-div) div{
226
+ line-height: 0.01em;
227
+ }
228
+
229
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control .vjs-thumbnail-holder,
230
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control .vjs-thumbnail {
231
+ display: none !important;
232
+ }
233
+
234
+ .video-js.vjs-ad-playing .vjs-control-bar .vjs-progress-control .vjs-progress-holder {
235
+ cursor: auto;
236
+ box-shadow: none;
237
+ font-size: 100%;
238
+ margin: 0 1em;
239
+ }
240
+
241
+ .video-js .vjs-control-bar .ima-countdown-div {
242
+ display: none;
243
+ z-index: 1;
244
+ }
245
+
246
+ .video-js.vjs-ad-playing .vjs-control-bar .ima-countdown-div {
247
+ display: block;
248
+ position: absolute;
249
+ margin-top: -2em;
250
+ left: 2em;
251
+ font-size: 1.2em;
252
+ }
@@ -0,0 +1,20 @@
1
+ const hide = (el) => {
2
+ el.style.display = 'none';
3
+ };
4
+
5
+ const show = (el) => {
6
+ el.style.display = '';
7
+ };
8
+
9
+ const setText = (el, text) => {
10
+ if (!text || text.length <= 0) {
11
+ el.innerText = '';
12
+ hide(el);
13
+ return;
14
+ }
15
+
16
+ el.innerText = text;
17
+ show(el);
18
+ };
19
+
20
+ module.exports = { hide, show, setText };
@@ -0,0 +1,21 @@
1
+ import JumpForwardButton from './jumpButtons/jump-10-plus';
2
+ import JumpBackButton from './jumpButtons/jump-10-minus';
3
+ import LogoButton from './logoButton/logo-button';
4
+ import PlaylistPanel from './playlist/panel/playlist-panel';
5
+ import ProgressControlEventsBlocker from './progress-control-events-blocker/progress-control-events-blocker';
6
+ import RecommendationsOverlay from './recommendations-overlay';
7
+ import ShoppablePanel from './shoppable-bar/panel/shoppable-panel';
8
+ import TitleBar from './title-bar/title-bar';
9
+
10
+ import 'assets/styles/components/triangle-volume-bar.scss';
11
+
12
+ export {
13
+ JumpForwardButton,
14
+ JumpBackButton,
15
+ LogoButton,
16
+ PlaylistPanel,
17
+ ProgressControlEventsBlocker,
18
+ RecommendationsOverlay,
19
+ ShoppablePanel,
20
+ TitleBar
21
+ };
@@ -0,0 +1,30 @@
1
+ export const INTERACTION_AREA_LAYOUT_LOCAL_STORAGE_NAME = 'cld-ia-layout-state';
2
+
3
+ export const INTERACTION_AREAS_PREFIX = 'vp-ia';
4
+
5
+ export const INTERACTION_AREAS_CONTAINER_CLASS_NAME = 'interaction-areas-container';
6
+
7
+ export const INTERACTION_AREAS_TEMPLATE = {
8
+ PORTRAIT: 'portrait',
9
+ LANDSCAPE: 'landscape',
10
+ All: 'all',
11
+ CENTER: 'center'
12
+ };
13
+
14
+ export const INTERACTION_AREAS_THEME = {
15
+ PULSING: 'pulsing',
16
+ SHADOWED: 'shadowed'
17
+ };
18
+
19
+ export const TEMPLATE_INTERACTION_AREAS_VTT = {
20
+ [INTERACTION_AREAS_TEMPLATE.PORTRAIT]: 'https://res.cloudinary.com/prod/raw/upload/v1623772481/video-player/vtts/portrait.vtt',
21
+ [INTERACTION_AREAS_TEMPLATE.LANDSCAPE]: 'https://res.cloudinary.com/prod/raw/upload/v1623772303/video-player/vtts/landscape.vtt',
22
+ [INTERACTION_AREAS_TEMPLATE.All]: 'https://res.cloudinary.com/prod/raw/upload/v1623250266/video-player/vtts/all.vtt',
23
+ [INTERACTION_AREAS_TEMPLATE.CENTER]: 'https://res.cloudinary.com/prod/raw/upload/v1623250265/video-player/vtts/center.vtt'
24
+ };
25
+
26
+ export const INTERACTION_AREA_HAND_ICON = 'https://res.cloudinary.com/prod/image/upload/v1626764643/video-player/interaction-area-hand.svg';
27
+
28
+ export const CLOSE_INTERACTION_AREA_LAYOUT_DELAY = 4500;
29
+
30
+ export const DEFAULT_INTERACTION_ARE_TRANSITION = 250;
@@ -0,0 +1,223 @@
1
+ import videojs from 'video.js';
2
+ import {
3
+ CLOSE_INTERACTION_AREA_LAYOUT_DELAY,
4
+ DEFAULT_INTERACTION_ARE_TRANSITION,
5
+ INTERACTION_AREAS_CONTAINER_CLASS_NAME, TEMPLATE_INTERACTION_AREAS_VTT
6
+ } from './interaction-area.const';
7
+ import {
8
+ createInteractionAreaLayoutMessage,
9
+ getInteractionAreaItem,
10
+ getZoomTransformation,
11
+ removeInteractionAreasContainer,
12
+ setInteractionAreasContainer,
13
+ setInteractionAreasContainerSize,
14
+ shouldShowAreaLayoutMessage,
15
+ updateInteractionAreasItem
16
+ } from './interaction-area.utils';
17
+ import { addEventListener, createElement } from '../../utils/dom';
18
+ import { throttle } from '../../utils/time';
19
+ import { get } from '../../utils/object';
20
+ import { noop } from '../../utils/type-inference';
21
+ import { addMetadataTrack } from '../../video-player.utils';
22
+
23
+
24
+ export const interactionAreaService = (player, playerOptions, videojsOptions) => {
25
+
26
+ let firstPlayed = false;
27
+ let isZoomed = false;
28
+ let currentTrack = null;
29
+ let unZoom = noop;
30
+
31
+ const shouldLayoutMessage = () => shouldShowAreaLayoutMessage(videojsOptions.interactionAreas);
32
+
33
+ function isInteractionAreasEnabled(enabled = false) {
34
+ const interactionAreasConfig = getInteractionAreasConfig();
35
+ return enabled || (interactionAreasConfig && interactionAreasConfig.enable);
36
+ }
37
+
38
+ function setAreasPositionListener() {
39
+ currentTrack && player.videojs.removeRemoteTextTrack(currentTrack);
40
+
41
+ const isEnabled = isInteractionAreasEnabled();
42
+ const interactionAreasConfig = getInteractionAreasConfig();
43
+
44
+ if (!isEnabled || isZoomed) {
45
+ return null;
46
+ }
47
+
48
+ if (Array.isArray(interactionAreasConfig.template)) {
49
+ addInteractionAreasItems(interactionAreasConfig.template);
50
+ setContainerSize();
51
+ } else {
52
+ const vttUrl = interactionAreasConfig.vttUrl || TEMPLATE_INTERACTION_AREAS_VTT[interactionAreasConfig.template];
53
+
54
+ if (vttUrl) {
55
+ currentTrack = addMetadataTrack(player.videojs, vttUrl);
56
+ addCueListener(currentTrack);
57
+ }
58
+ }
59
+ }
60
+
61
+ function setGoBackButton() {
62
+ const button = createElement('div', { 'class': 'go-back-button' });
63
+
64
+ button.addEventListener('click', () => {
65
+ unZoom();
66
+ }, false);
67
+
68
+ const tracksContainer = createElement('div', { 'class': INTERACTION_AREAS_CONTAINER_CLASS_NAME }, button);
69
+ setInteractionAreasContainer(player.videojs, tracksContainer);
70
+ }
71
+
72
+ function getInteractionAreasConfig() {
73
+ const { cldSrc } = player.videojs.currentSource();
74
+ return cldSrc && cldSrc.getInteractionAreas();
75
+ }
76
+
77
+ function removeLayoutMessage() {
78
+ removeInteractionAreasContainer(player.videojs);
79
+ setAreasPositionListener();
80
+ player.play();
81
+ }
82
+
83
+ function setLayoutMessage() {
84
+ if (!isInteractionAreasEnabled()) {
85
+ return;
86
+ }
87
+
88
+ if (shouldLayoutMessage()) {
89
+ let layoutMessageTimout = null;
90
+ const showItAgainCheckbox = get(videojsOptions, 'interactionAreas.layout.showAgain', false);
91
+ player.pause();
92
+
93
+ createInteractionAreaLayoutMessage(player.videojs, () => {
94
+ clearTimeout(layoutMessageTimout);
95
+ removeLayoutMessage();
96
+ }, showItAgainCheckbox);
97
+
98
+ if (!showItAgainCheckbox) {
99
+ layoutMessageTimout = setTimeout(removeLayoutMessage, CLOSE_INTERACTION_AREA_LAYOUT_DELAY);
100
+ }
101
+ } else {
102
+ removeLayoutMessage();
103
+ }
104
+ }
105
+
106
+ function init() {
107
+
108
+ if (isInteractionAreasEnabled()) {
109
+
110
+ player.videojs.one('play', () => {
111
+ firstPlayed = true;
112
+ setLayoutMessage();
113
+ });
114
+
115
+ player.videojs.on('sourcechanged', () => {
116
+ firstPlayed && setAreasPositionListener();
117
+ });
118
+
119
+ const setInteractionAreasContainerSize = throttle(setContainerSize, 100);
120
+
121
+ player.videojs.on('fullscreenchange', () => {
122
+ // waiting for fullscreen will end
123
+ setTimeout(setInteractionAreasContainerSize, 100);
124
+ });
125
+
126
+ const resizeDestroy = addEventListener(window, 'resize', setContainerSize, false);
127
+
128
+ player.videojs.on('dispose', resizeDestroy);
129
+ }
130
+
131
+ player.videojs.on('ended', () => {
132
+ unZoom();
133
+ });
134
+ }
135
+
136
+ function onZoom(src, newOption, item) {
137
+ const currentSource = player.videojs.currentSource();
138
+ const { cldSrc } = currentSource;
139
+ const currentSrcOptions = cldSrc.getInitOptions();
140
+ const option = newOption || { transformation: currentSrcOptions.transformation.toOptions() };
141
+ const transformation = !src && getZoomTransformation(player.videoElement, item);
142
+ const sourceOptions = transformation ? videojs.mergeOptions({ transformation }, option) : option;
143
+
144
+ const newSource = cldSrc.isRawUrl ? currentSource.src : { publicId: cldSrc.publicId() };
145
+ player.source(transformation ? { publicId: cldSrc.publicId() } : src, sourceOptions).play();
146
+
147
+ isZoomed = true;
148
+
149
+ setGoBackButton();
150
+
151
+ unZoom = () => {
152
+ if (isZoomed) {
153
+ isZoomed = false;
154
+ player.source(newSource, currentSrcOptions).play();
155
+ }
156
+ };
157
+ }
158
+
159
+ function onInteractionAreasClick({ event, item, index }) {
160
+ const interactionAreasConfig = getInteractionAreasConfig();
161
+
162
+ interactionAreasConfig.onClick && interactionAreasConfig.onClick({
163
+ item,
164
+ index,
165
+ event,
166
+ zoom: (source, option) => {
167
+ onZoom(source, option, item);
168
+ }
169
+ });
170
+ }
171
+
172
+ function addInteractionAreasItems(interactionAreasData, previousInteractionAreasData, durationTime = 0) {
173
+ const configs = { playerOptions: playerOptions, videojsOptions: videojsOptions };
174
+
175
+ if (previousInteractionAreasData) {
176
+ updateInteractionAreasItem(player.videojs, configs, interactionAreasData, previousInteractionAreasData, durationTime, onInteractionAreasClick);
177
+ } else {
178
+ const interactionAreasItems = interactionAreasData.map((item, index) => {
179
+ return getInteractionAreaItem(configs, item, index, durationTime, (event) => {
180
+ onInteractionAreasClick({ event, item, index });
181
+ });
182
+ });
183
+
184
+ setInteractionAreasContainer(player.videojs, createElement('div', { 'class': INTERACTION_AREAS_CONTAINER_CLASS_NAME }, interactionAreasItems));
185
+ }
186
+ }
187
+
188
+ function setContainerSize() {
189
+ if (isInteractionAreasEnabled()) {
190
+ setInteractionAreasContainerSize(player.videojs, player.videoElement);
191
+ }
192
+ }
193
+
194
+ function addCueListener(track) {
195
+ if (!track) {
196
+ return;
197
+ }
198
+
199
+ let previousTracksData = null;
200
+
201
+ track.addEventListener('cuechange', () => {
202
+ const activeCue = track.activeCues && track.activeCues[0];
203
+
204
+ if (activeCue) {
205
+ const durationTime = Math.max(Math.floor((activeCue.endTime - activeCue.startTime) * 1000), DEFAULT_INTERACTION_ARE_TRANSITION);
206
+
207
+ const tracksData = JSON.parse(activeCue.text);
208
+
209
+ addInteractionAreasItems(tracksData, previousTracksData, durationTime);
210
+ !previousTracksData && setContainerSize();
211
+ previousTracksData = tracksData;
212
+ } else {
213
+ removeInteractionAreasContainer(player.videojs);
214
+ previousTracksData = null;
215
+ }
216
+ });
217
+ }
218
+
219
+ return {
220
+ init
221
+ };
222
+
223
+ };