cloudinary-video-player 3.12.1 → 3.12.2-edge.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/134.min.js +8 -0
  2. package/dist/309.min.js +6 -0
  3. package/dist/adaptive-streaming.js +9 -9
  4. package/dist/adaptive-streaming.min.js +2 -2
  5. package/dist/chapters.js +4 -4
  6. package/dist/chapters.min.js +3 -3
  7. package/dist/cld-player-core.js +37 -0
  8. package/dist/cld-player-core.min.js +6 -0
  9. package/dist/cld-video-player-lazy.js +494 -0
  10. package/dist/cld-video-player-lazy.min.js +6 -0
  11. package/dist/cld-video-player.css +2 -2
  12. package/dist/cld-video-player.js +366 -332
  13. package/dist/cld-video-player.light.js +366 -332
  14. package/dist/cld-video-player.light.min.js +4 -4
  15. package/dist/cld-video-player.min.css +2 -2
  16. package/dist/cld-video-player.min.js +4 -4
  17. package/dist/colors.js +4 -4
  18. package/dist/colors.min.js +2 -2
  19. package/dist/dash.js +6 -6
  20. package/dist/dash.min.js +2 -2
  21. package/dist/debug.js +8 -8
  22. package/dist/debug.min.js +3 -3
  23. package/dist/ima.js +9 -9
  24. package/dist/ima.min.js +2 -2
  25. package/dist/interaction-areas.js +11 -11
  26. package/dist/interaction-areas.min.js +2 -2
  27. package/dist/node_modules_lodash_throttle_js.js +8 -8
  28. package/dist/playlist.js +31 -31
  29. package/dist/playlist.min.js +3 -3
  30. package/dist/recommendations-overlay.js +10 -10
  31. package/dist/recommendations-overlay.min.js +2 -2
  32. package/dist/schema.json +19 -0
  33. package/dist/share.js +5 -5
  34. package/dist/share.min.js +3 -3
  35. package/dist/shoppable.js +12 -12
  36. package/dist/shoppable.min.js +2 -2
  37. package/dist/utils_fetch-config_js.js +81 -0
  38. package/dist/video-player_js.js +3111 -0
  39. package/dist/visual-search.js +7 -7
  40. package/dist/visual-search.min.js +2 -2
  41. package/lib/_commonjsHelpers.js +7 -0
  42. package/lib/_videojs-proxy.js +30294 -0
  43. package/lib/abr-strategies.js +31 -0
  44. package/lib/adaptive-streaming.js +468 -2
  45. package/lib/all.js +25 -2
  46. package/lib/chapters.js +205 -1
  47. package/lib/cld-video-player.min.css +5 -22
  48. package/lib/colors.js +59 -1
  49. package/lib/{schema.json → config/configSchema.json} +19 -0
  50. package/lib/dash.js +69943 -2
  51. package/lib/debug.js +322 -1
  52. package/lib/document.js +770 -0
  53. package/lib/download-button.js +48 -0
  54. package/lib/fetch-config.js +93 -0
  55. package/lib/ima.js +6851 -1
  56. package/lib/index.js +27 -0
  57. package/lib/interaction-areas.const.js +24 -0
  58. package/lib/interaction-areas.service.js +469 -0
  59. package/lib/lazy.js +20 -0
  60. package/lib/noop.js +33 -0
  61. package/lib/player-api.js +469 -0
  62. package/lib/player.js +7 -2
  63. package/lib/playlist-panel.js +602 -0
  64. package/lib/playlist.js +637 -1
  65. package/lib/querystring.js +81 -0
  66. package/lib/recommendations-overlay.js +320 -1
  67. package/lib/share.js +129 -1
  68. package/lib/shoppable-post-widget.js +572 -0
  69. package/lib/shoppable-widget.js +77 -0
  70. package/lib/throttle.js +318 -0
  71. package/lib/toNumber.js +134 -0
  72. package/lib/validators-functions.js +485 -0
  73. package/lib/video-player.js +16241 -0
  74. package/lib/videoPlayer.js +7 -2
  75. package/lib/videojs-contrib-hlsjs.js +37638 -0
  76. package/lib/visual-search.js +235 -1
  77. package/package.json +31 -15
  78. package/lib/adaptive-streaming.js.LICENSE.txt +0 -3
  79. package/lib/all.js.LICENSE.txt +0 -25
  80. package/lib/cld-video-player.js +0 -2
  81. package/lib/cld-video-player.js.LICENSE.txt +0 -21
  82. package/lib/dash.js.LICENSE.txt +0 -1842
  83. package/lib/interaction-areas.js +0 -1
  84. package/lib/player.js.LICENSE.txt +0 -21
  85. package/lib/shoppable.js +0 -1
  86. package/lib/videoPlayer.js.LICENSE.txt +0 -21
@@ -0,0 +1,81 @@
1
+ function utf8ToBase64(str) {
2
+ const utf8Bytes = new TextEncoder().encode(str);
3
+ const binaryStr = String.fromCharCode(...utf8Bytes);
4
+ return btoa(binaryStr);
5
+ }
6
+
7
+ const DEFAULT_POSTER_PARAMS = {
8
+ format: 'jpg',
9
+ resource_type: 'video'
10
+ };
11
+ const DEFAULT_VIDEO_PARAMS = {
12
+ resource_type: 'video',
13
+ type: 'upload',
14
+ hdr: false,
15
+ transformation: [],
16
+ sourceTransformation: {},
17
+ sourceTypes: ['auto'],
18
+ recommendations: null,
19
+ info: {},
20
+ interactionAreas: {},
21
+ chapters: {}
22
+ };
23
+ const COMMON_VIDEO_EXTENSIONS = ['3g2', '3gp', 'avi', 'flv', 'm3u8', 'ts', 'm2ts', 'mts', 'mov', 'mkv', 'mp4', 'mpeg', 'mpd', 'mxf', 'ogv', 'webm', 'wmv']; // https://cloudinary.com/documentation/video_manipulation_and_delivery#supported_video_formats
24
+
25
+ const VIDEO_SUFFIX_REMOVAL_PATTERN = RegExp(`\\.(${COMMON_VIDEO_EXTENSIONS.join('|')})$$`);
26
+
27
+ // eslint-disable-next-line no-control-regex
28
+ const URL_PATTERN = RegExp('https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\+.~#?&/=]*)');
29
+ const CONTAINER_MIME_TYPES = {
30
+ hls: 'application/x-mpegURL',
31
+ dash: 'application/dash+xml',
32
+ // See: https://docs.videojs.com/utils_mimetypes.js.html
33
+ opus: 'video/ogg',
34
+ ogv: 'video/ogg',
35
+ mp4: 'video/mp4',
36
+ mov: 'video/mp4',
37
+ m4v: 'video/mp4',
38
+ mkv: 'video/x-matroska',
39
+ m4a: 'audio/mp4',
40
+ mp3: 'audio/mpeg',
41
+ aac: 'audio/aac',
42
+ caf: 'audio/x-caf',
43
+ flac: 'audio/flac',
44
+ oga: 'audio/ogg',
45
+ wav: 'audio/wav',
46
+ m3u8: 'application/x-mpegURL',
47
+ mpd: 'application/dash+xml',
48
+ jpg: 'image/jpeg',
49
+ jpeg: 'image/jpeg',
50
+ gif: 'image/gif',
51
+ png: 'image/png',
52
+ svg: 'image/svg+xml',
53
+ webp: 'image/webp'
54
+ };
55
+ const ADAPTIVE_SOURCETYPES = ['hls', 'dash', 'mpd', 'm3u8'];
56
+ const FORMAT_MAPPINGS = {
57
+ hls: 'm3u8',
58
+ dash: 'mpd'
59
+ };
60
+
61
+ // Breakpoints constants
62
+ const DEFAULT_DPR = 2.0;
63
+ const RENDITIONS = [640, 848, 1280, 1920, 2560, 3840];
64
+
65
+ const isRawUrl = publicId => URL_PATTERN.test(publicId);
66
+
67
+ const appendQueryParams = (url, params) => {
68
+ if (!params || !Object.keys(params).length) {
69
+ return url;
70
+ }
71
+ const urlObj = new URL(url);
72
+ Object.entries(params).forEach(_ref => {
73
+ let [key, value] = _ref;
74
+ if (value != null) {
75
+ urlObj.searchParams.append(key, value);
76
+ }
77
+ });
78
+ return urlObj.href;
79
+ };
80
+
81
+ export { ADAPTIVE_SOURCETYPES as A, CONTAINER_MIME_TYPES as C, DEFAULT_VIDEO_PARAMS as D, FORMAT_MAPPINGS as F, RENDITIONS as R, VIDEO_SUFFIX_REMOVAL_PATTERN as V, appendQueryParams as a, DEFAULT_POSTER_PARAMS as b, DEFAULT_DPR as c, isRawUrl as i, utf8ToBase64 as u };
@@ -1 +1,320 @@
1
- (self.cloudinaryVideoPlayerChunkLoading=self.cloudinaryVideoPlayerChunkLoading||[]).push([[410],{7604:(e,t,s)=>{s.r(t),s.d(t,{default:()=>k});var i=s(6673),n=s.n(i);const r=n().getComponent("ClickableComponent"),o=class extends r{setItem(e){const{action:t,source:s}=e;this.source=s;const i=s.info();this.setTitle(i.title||s.publicId()),this.setPoster(this.source.poster().url({transformation:{aspect_ratio:"16:9",crop:"pad",background:"black"}})),this.setAction(t)}setTitle(e){this.title.innerText=e}setAction(e){this.action=e}handleClick(){super.handleClick(),this.player().trigger("recommendationshide"),this.action()}};var a=s(7878),c=s.n(a);const l=n().dom||n(),h=class extends o{setItem(e){super.setItem(e);const t=this.source.info();if(this.setTitle(t.title),this.setSubtitle(t.subtitle),t.description){const e=300,s=t.description.length>e?t.description.substring(0,e)+"...":t.description;this.setDescription(s)}}setPoster(e){this.poster.style.backgroundImage=`url('${e}')`}setTitle(e){c().setText(this.title,e),this.setAriaCheck(this.title,!!e)}setSubtitle(e){c().setText(this.subtitle,e),this.setAriaCheck(this.subtitle,!!e)}setDescription(e){c().setText(this.description,e),this.setAriaCheck(this.description,!!e)}setAriaCheck(e){arguments.length>1&&void 0!==arguments[1]&&!arguments[1]?e.setAttribute("aria-hidden","true"):e.removeAttribute("aria-hidden")}clearItem(){this.setTitle(""),this.setSubtitle(""),this.setDescription(""),this.poster.style.backgroundImage=null}createEl(){const e=super.createEl("div",{className:"vjs-recommendations-overlay-item vjs-recommendations-overlay-item-primary"});return this.poster=l.createEl("div",{className:"vjs-recommendations-overlay-item-primary-image"}),this.title=l.createEl("h2",{ariaLabel:"Recmmendation Title"}),this.setAriaCheck(this.title,!1),this.title.innerHTML="",this.subtitle=l.createEl("h3",{ariaLabel:"Recmmendation Subtitle"}),this.setAriaCheck(this.subtitle,!1),this.subtitle.innerHTML="",this.description=l.createEl("p"),this.setAriaCheck(this.description,!1),this.description.innerHTML="",this.content=l.createEl("div",{className:"vjs-recommendations-overlay-item-info vjs-recommendations-overlay-item-primary-content"}),this.content.appendChild(this.title),this.content.appendChild(this.subtitle),this.content.appendChild(this.description),e.appendChild(this.poster),e.appendChild(this.content),e}},d=n().dom||n(),m=class extends o{setItem(e){super.setItem(e),this.setDuration("")}setPoster(e){this.el().style.backgroundImage=`url('${e}')`}setDuration(e){this.duration.innerText=e}createEl(){const e=super.createEl("div",{className:"vjs-recommendations-overlay-item vjs-recommendations-overlay-item-secondary"});this.title=d.createEl("span",{className:"vjs-recommendations-overlay-item-secondary-title"}),this.title.innerHTML="",this.duration=d.createEl("span",{className:"vjs-recommendations-overlay-item-secondary-duration"}),this.duration.innerHTML="";const t=d.createEl("div",{className:"vjs-recommendations-overlay-item-info"});return t.appendChild(this.title),t.appendChild(this.duration),e.appendChild(t),e}handleClick(){super.handleClick(),this.action()}},p=n().getComponent("Component"),u=class extends p{setItems(){for(var e=arguments.length,t=new Array(e),s=0;s<e;s++)t[s]=arguments[s];this.clearItems(),t&&t.forEach(e=>{const t=new m(this.player());t.setItem(e),this.addChild(t)})}clearItems(){this.children().forEach(()=>{this.removeChild(this.children()[0])})}createEl(){return super.createEl("div",{className:"vjs-recommendations-overlay-item-secondary-container"})}},v=n().getComponent("Component");class y extends v{constructor(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),i=1;i<t;i++)s[i-1]=arguments[i];super(e,...s),this._primary=new h(e),this._secondaryContainer=new u(e),this.addChild(this._primary),this.addChild(this._secondaryContainer)}setItems(e){this._primary.setItem(e);for(var t=arguments.length,s=new Array(t>1?t-1:0),i=1;i<t;i++)s[i-1]=arguments[i];this._secondaryContainer.setItems(...s)}createEl(){return super.createEl("div",{className:"aspect-ratio-content"})}}const C=class extends v{constructor(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),i=1;i<t;i++)s[i-1]=arguments[i];super(e,...s),this._content=new y(e),this.addChild(this._content)}setItems(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),i=1;i<t;i++)s[i-1]=arguments[i];this._content.setItems(e,...s)}clearItems(){this._content._primary.clearItem(),this._content._secondaryContainer.clearItems()}createEl(){return super.createEl("div",{className:"vjs-recommendations-overlay-content"})}},g=n().getComponent("ClickableComponent"),I=class extends g{createEl(){return super.createEl("span",{className:"vjs-recommendations-overlay-hide vjs-icon-close"})}handleClick(){this.options_.clickHandler()}},b=n().getComponent("Component");class E extends b{constructor(e,t){for(var s=arguments.length,i=new Array(s>2?s-2:0),n=2;n<s;n++)i[n-2]=arguments[n];super(e,...i),this._content=new C(e),this.addChild(this._content),this.addChild(new I(e,{clickHandler:()=>{this.close()}},...i)),this.setEvents(e),this.doNotOpen=!1}setEvents(e){this.on(e,"recommendationschanged",(e,t)=>{this.setItems(...t.items)}),this.on(e,"recommendationsnoshow",this.setDoNotOpen),this.on(e,"recommendationsshow",this.open),this.on(e,"recommendationshide",this.close),this.on(e,"cldsourcechanged",()=>{this.clearItems(),this.close()})}setDoNotOpen(){this.doNotOpen=!0}open(){this.doNotOpen||(this._showControlsOnClose=this.player().controls(),this.player().controls(!1),this.el().style.visibility="visible")}clearItems(){this._content.clearItems()}close(){this.el().style.visibility="hidden",this._showControlsOnClose&&this.player().controls(!0)}createEl(){const e="vjs-recommendations-overlay",t=super.createEl("div",{className:e});return n().dom.addClass(t,e),t}setItems(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),i=1;i<t;i++)s[i-1]=arguments[i];this.doNotOpen=!1,s=s.slice(0,3),this._content.setItems(e,...s)}handleClick(){this.stopPropagation()}dispose(){super.dispose()}}n().registerComponent("recommendationsOverlay",E);const k=E}}]);
1
+ import { _ as _vjs } from './_videojs-proxy.js';
2
+ import { f as componentUtils } from './video-player.js';
3
+ import './_commonjsHelpers.js';
4
+ import './validators-functions.js';
5
+ import './querystring.js';
6
+ import './player-api.js';
7
+
8
+ const ClickableComponent$1 = _vjs.getComponent('ClickableComponent');
9
+ class RecommendationsOverlayItem extends ClickableComponent$1 {
10
+ setItem(item) {
11
+ const {
12
+ action,
13
+ source
14
+ } = item;
15
+ this.source = source;
16
+ const info = source.info();
17
+ this.setTitle(info.title || source.publicId());
18
+ this.setPoster(this.source.poster().url({
19
+ transformation: {
20
+ aspect_ratio: '16:9',
21
+ crop: 'pad',
22
+ background: 'black'
23
+ }
24
+ }));
25
+ this.setAction(action);
26
+ }
27
+ setTitle(text) {
28
+ this.title.innerText = text;
29
+ }
30
+ setAction(action) {
31
+ this.action = action;
32
+ }
33
+ handleClick() {
34
+ super.handleClick();
35
+ this.player().trigger('recommendationshide');
36
+ this.action();
37
+ }
38
+ }
39
+
40
+ // support VJS5 & VJS6 at the same time
41
+ const dom$1 = _vjs.dom || _vjs;
42
+ class RecommendationsOverlayPrimaryItem extends RecommendationsOverlayItem {
43
+ setItem(item) {
44
+ super.setItem(item);
45
+ const info = this.source.info();
46
+ this.setTitle(info.title);
47
+ this.setSubtitle(info.subtitle);
48
+ if (info.description) {
49
+ const descLength = 300;
50
+ const description = info.description.length > descLength ? info.description.substring(0, descLength) + '...' : info.description;
51
+ this.setDescription(description);
52
+ }
53
+ }
54
+ setPoster(url) {
55
+ this.poster.style.backgroundImage = `url('${url}')`;
56
+ }
57
+ setTitle(text) {
58
+ componentUtils.setText(this.title, text);
59
+ this.setAriaCheck(this.title, !!text);
60
+ }
61
+ setSubtitle(text) {
62
+ componentUtils.setText(this.subtitle, text);
63
+ this.setAriaCheck(this.subtitle, !!text);
64
+ }
65
+ setDescription(text) {
66
+ componentUtils.setText(this.description, text);
67
+ this.setAriaCheck(this.description, !!text);
68
+ }
69
+ setAriaCheck(element) {
70
+ let active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
71
+ if (active) {
72
+ element.removeAttribute('aria-hidden');
73
+ } else {
74
+ element.setAttribute('aria-hidden', 'true');
75
+ }
76
+ }
77
+ clearItem() {
78
+ this.setTitle('');
79
+ this.setSubtitle('');
80
+ this.setDescription('');
81
+ this.poster.style.backgroundImage = null;
82
+ }
83
+ createEl() {
84
+ const el = super.createEl('div', {
85
+ className: 'vjs-recommendations-overlay-item vjs-recommendations-overlay-item-primary'
86
+ });
87
+ this.poster = dom$1.createEl('div', {
88
+ className: 'vjs-recommendations-overlay-item-primary-image'
89
+ });
90
+ this.title = dom$1.createEl('h2', {
91
+ ariaLabel: 'Recmmendation Title'
92
+ });
93
+ this.setAriaCheck(this.title, false);
94
+ this.title.innerHTML = '';
95
+ this.subtitle = dom$1.createEl('h3', {
96
+ ariaLabel: 'Recmmendation Subtitle'
97
+ });
98
+ this.setAriaCheck(this.subtitle, false);
99
+ this.subtitle.innerHTML = '';
100
+ this.description = dom$1.createEl('p');
101
+ this.setAriaCheck(this.description, false);
102
+ this.description.innerHTML = '';
103
+ this.content = dom$1.createEl('div', {
104
+ className: 'vjs-recommendations-overlay-item-info vjs-recommendations-overlay-item-primary-content'
105
+ });
106
+ this.content.appendChild(this.title);
107
+ this.content.appendChild(this.subtitle);
108
+ this.content.appendChild(this.description);
109
+ el.appendChild(this.poster);
110
+ el.appendChild(this.content);
111
+ return el;
112
+ }
113
+ }
114
+
115
+ // support VJS5 & VJS6 at the same time
116
+ const dom = _vjs.dom || _vjs;
117
+ class RecommendationsOverlaySecondaryItem extends RecommendationsOverlayItem {
118
+ setItem(item) {
119
+ super.setItem(item);
120
+ this.setDuration('');
121
+ }
122
+ setPoster(url) {
123
+ this.el().style.backgroundImage = `url('${url}')`;
124
+ }
125
+ setDuration(text) {
126
+ this.duration.innerText = text;
127
+ }
128
+ createEl() {
129
+ const el = super.createEl('div', {
130
+ className: 'vjs-recommendations-overlay-item vjs-recommendations-overlay-item-secondary'
131
+ });
132
+ this.title = dom.createEl('span', {
133
+ className: 'vjs-recommendations-overlay-item-secondary-title'
134
+ });
135
+ this.title.innerHTML = '';
136
+ this.duration = dom.createEl('span', {
137
+ className: 'vjs-recommendations-overlay-item-secondary-duration'
138
+ });
139
+ this.duration.innerHTML = '';
140
+ const caption = dom.createEl('div', {
141
+ className: 'vjs-recommendations-overlay-item-info'
142
+ });
143
+ caption.appendChild(this.title);
144
+ caption.appendChild(this.duration);
145
+ el.appendChild(caption);
146
+ return el;
147
+ }
148
+ handleClick() {
149
+ super.handleClick();
150
+ this.action();
151
+ }
152
+ }
153
+
154
+ const Component$2 = _vjs.getComponent('Component');
155
+ class RecommendationsOverlaySecondaryItemsContainer extends Component$2 {
156
+ setItems() {
157
+ for (var _len = arguments.length, items = new Array(_len), _key = 0; _key < _len; _key++) {
158
+ items[_key] = arguments[_key];
159
+ }
160
+ this.clearItems();
161
+ if (!items) {
162
+ return;
163
+ }
164
+ items.forEach(item => {
165
+ const component = new RecommendationsOverlaySecondaryItem(this.player());
166
+ component.setItem(item);
167
+ this.addChild(component);
168
+ });
169
+ }
170
+ clearItems() {
171
+ this.children().forEach(() => {
172
+ this.removeChild(this.children()[0]);
173
+ });
174
+ }
175
+ createEl() {
176
+ return super.createEl('div', {
177
+ className: 'vjs-recommendations-overlay-item-secondary-container'
178
+ });
179
+ }
180
+ }
181
+
182
+ const Component$1 = _vjs.getComponent('Component');
183
+ class RecommendationsOverlayContent extends Component$1 {
184
+ constructor(player) {
185
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
186
+ args[_key - 1] = arguments[_key];
187
+ }
188
+ super(player, ...args);
189
+ this._content = new AspectRatioContent(player);
190
+ this.addChild(this._content);
191
+ }
192
+ setItems(primary) {
193
+ for (var _len2 = arguments.length, secondary = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
194
+ secondary[_key2 - 1] = arguments[_key2];
195
+ }
196
+ this._content.setItems(primary, ...secondary);
197
+ }
198
+ clearItems() {
199
+ this._content._primary.clearItem();
200
+ this._content._secondaryContainer.clearItems();
201
+ }
202
+ createEl() {
203
+ return super.createEl('div', {
204
+ className: 'vjs-recommendations-overlay-content'
205
+ });
206
+ }
207
+ }
208
+ class AspectRatioContent extends Component$1 {
209
+ constructor(player) {
210
+ for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
211
+ args[_key3 - 1] = arguments[_key3];
212
+ }
213
+ super(player, ...args);
214
+ this._primary = new RecommendationsOverlayPrimaryItem(player);
215
+ this._secondaryContainer = new RecommendationsOverlaySecondaryItemsContainer(player);
216
+ this.addChild(this._primary);
217
+ this.addChild(this._secondaryContainer);
218
+ }
219
+ setItems(primary) {
220
+ this._primary.setItem(primary);
221
+ for (var _len4 = arguments.length, secondary = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
222
+ secondary[_key4 - 1] = arguments[_key4];
223
+ }
224
+ this._secondaryContainer.setItems(...secondary);
225
+ }
226
+ createEl() {
227
+ return super.createEl('div', {
228
+ className: 'aspect-ratio-content'
229
+ });
230
+ }
231
+ }
232
+
233
+ const ClickableComponent = _vjs.getComponent('ClickableComponent');
234
+ class RecommendationOverlayHideButton extends ClickableComponent {
235
+ createEl() {
236
+ return super.createEl('span', {
237
+ className: 'vjs-recommendations-overlay-hide vjs-icon-close'
238
+ });
239
+ }
240
+ handleClick() {
241
+ this.options_.clickHandler();
242
+ }
243
+ }
244
+
245
+ const MAXIMUM_ITEMS = 4;
246
+ const Component = _vjs.getComponent('Component');
247
+
248
+ // TODO: Use Video.js's ModalDialog instead. It handles clicking block logic.
249
+ class RecommendationsOverlay extends Component {
250
+ constructor(player, options) {
251
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
252
+ args[_key - 2] = arguments[_key];
253
+ }
254
+ super(player, ...args);
255
+ this._content = new RecommendationsOverlayContent(player);
256
+ this.addChild(this._content);
257
+ this.addChild(new RecommendationOverlayHideButton(player, {
258
+ clickHandler: () => {
259
+ this.close();
260
+ }
261
+ }, ...args));
262
+ this.setEvents(player);
263
+ this.doNotOpen = false;
264
+ }
265
+ setEvents(player) {
266
+ this.on(player, 'recommendationschanged', (_, eventData) => {
267
+ this.setItems(...eventData.items);
268
+ });
269
+ this.on(player, 'recommendationsnoshow', this.setDoNotOpen);
270
+ this.on(player, 'recommendationsshow', this.open);
271
+ this.on(player, 'recommendationshide', this.close);
272
+ this.on(player, 'cldsourcechanged', () => {
273
+ this.clearItems();
274
+ this.close();
275
+ });
276
+ }
277
+ setDoNotOpen() {
278
+ this.doNotOpen = true;
279
+ }
280
+ open() {
281
+ if (!this.doNotOpen) {
282
+ // Only show controls on close if they were visible from the first place
283
+ this._showControlsOnClose = this.player().controls();
284
+ this.player().controls(false);
285
+ this.el().style.visibility = 'visible';
286
+ }
287
+ }
288
+ clearItems() {
289
+ this._content.clearItems();
290
+ }
291
+ close() {
292
+ this.el().style.visibility = 'hidden';
293
+ if (this._showControlsOnClose) {
294
+ this.player().controls(true);
295
+ }
296
+ }
297
+ createEl() {
298
+ const recommendationsOverlayClass = 'vjs-recommendations-overlay';
299
+ const el = super.createEl('div', {
300
+ className: recommendationsOverlayClass
301
+ });
302
+ _vjs.dom.addClass(el, recommendationsOverlayClass);
303
+ return el;
304
+ }
305
+ setItems(primary) {
306
+ for (var _len2 = arguments.length, secondary = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
307
+ secondary[_key2 - 1] = arguments[_key2];
308
+ }
309
+ this.doNotOpen = false;
310
+ secondary = secondary.slice(0, MAXIMUM_ITEMS - 1);
311
+ this._content.setItems(primary, ...secondary);
312
+ }
313
+ handleClick() {
314
+ this.stopPropagation();
315
+ }
316
+ dispose() {
317
+ super.dispose();
318
+ }
319
+ }
320
+ _vjs.registerComponent('recommendationsOverlay', RecommendationsOverlay);
package/lib/share.js CHANGED
@@ -1 +1,129 @@
1
- (self.cloudinaryVideoPlayerChunkLoading=self.cloudinaryVideoPlayerChunkLoading||[]).push([[976],{2130:(o,e,t)=>{t.d(e,{default:()=>s});var n=t(6673),a=t.n(n);const r=a().getComponent("ClickableComponent");a().registerComponent("ShareDownloadButton",class extends r{constructor(o){super(o,arguments.length>1&&void 0!==arguments[1]?arguments[1]:{})}handleClick(o){super.handleClick(o),this.player().share&&"function"==typeof this.player().share.download&&this.player().share.download()}createEl(){const o=a().dom.createEl("button",{className:"vjs-control vjs-share-download-button vjs-button",ariaLabel:"Download video",title:"Download video"}),e=a().dom.createEl("span",{className:"vjs-icon-file-download vjs-icon-placeholder"});o.appendChild(e);const t=a().dom.createEl("span",{className:"vjs-loading-spinner"});return o.appendChild(t),o}setPreparing(o){const e=this.el();o?(e.classList.add("vjs-waiting"),e.setAttribute("title","Download is being prepared")):(e.classList.remove("vjs-waiting"),e.setAttribute("title","Download video"))}});var d=t(1865),i=t(4319),l=t.n(i);const s=function(){let o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const e=(arguments.length>1?arguments[1]:void 0)||this;e.addClass("vjs-share");const t=()=>{const o=e.getChild("ControlBar");if(!o||o.getChild("ShareDownloadButton"))return;const t=o.children().findIndex(o=>"FullscreenToggle"===o.name_);o.addChild("ShareDownloadButton",{},-1!==t?t:void 0)};o.download&&t(),e.share={download:()=>{const o=(()=>{const o=e.currentSource?.();if(!o)return null;const t=["format","video_codec","streaming_profile"],n=o=>{if(Array.isArray(o))return o.map(n);if(o&&"object"==typeof o){const e=l()(o,t);return Object.keys(e).forEach(o=>{e[o]=n(e[o])}),e}return o},a=n(e.cloudinary.transformation()||{}),r=e.cloudinary.currentPublicId()?.split("/")?.pop(),i={...e.cloudinary.cloudinaryConfig(),...a,resource_type:"video",format:"mp4",video_codec:"h264",flags:`streaming_attachment:${r}`};return o.isAdaptive&&Object.assign(i,{crop:"limit",width:1920,height:1920}),"AudioSource"===e.cloudinary.source()?.getType()&&Object.assign(i,{format:"mp3",video_codec:void 0}),(0,d.KA)(e.cloudinary.currentPublicId(),i)})();if(!o)return void console.warn("Share plugin: Unable to resolve download URL.");const t=[423],n=e.controlBar?.getChild("ShareDownloadButton"),a=o=>{n?.setPreparing?.(o)},r=async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;const n=await fetch(o,{method:"HEAD"});if(t.includes(n.status)&&e<60)return await new Promise(o=>setTimeout(o,1e4)),r(e+1);a(!1),(()=>{const e=document.createElement("a");e.href=o,e.download="",document.body.appendChild(e),e.click(),document.body.removeChild(e)})()};a(!0),r()},addDownloadButton:t,removeDownloadButton:()=>{if(!e.controlBar)return;const o=e.controlBar.getChild("ShareDownloadButton");o&&e.controlBar.removeChild(o)}}}}}]);
1
+ import './download-button.js';
2
+ import { g as getCloudinaryUrl, o as omit } from './video-player.js';
3
+ import './_videojs-proxy.js';
4
+ import './_commonjsHelpers.js';
5
+ import './validators-functions.js';
6
+ import './querystring.js';
7
+ import './player-api.js';
8
+
9
+ const SharePlugin = function () {
10
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11
+ let playerInstance = arguments.length > 1 ? arguments[1] : undefined;
12
+ const player = playerInstance || this;
13
+ player.addClass('vjs-share');
14
+ const addDownloadButton = () => {
15
+ const controlBar = player.getChild('ControlBar');
16
+ if (!controlBar || controlBar.getChild('ShareDownloadButton')) {
17
+ return;
18
+ }
19
+ const children = controlBar.children();
20
+ const insertBeforeIndex = children.findIndex(c => c.name_ === 'FullscreenToggle');
21
+ controlBar.addChild('ShareDownloadButton', {}, insertBeforeIndex !== -1 ? insertBeforeIndex : undefined);
22
+ };
23
+ const removeDownloadButton = () => {
24
+ if (!player.controlBar) {
25
+ return;
26
+ }
27
+ const btn = player.controlBar.getChild('ShareDownloadButton');
28
+ if (btn) {
29
+ player.controlBar.removeChild(btn);
30
+ }
31
+ };
32
+ const getDownloadUrl = () => {
33
+ const source = player.currentSource?.();
34
+ if (!source) {
35
+ return null;
36
+ }
37
+
38
+ // Strip format / codec related transformation arrays
39
+ const STRIP_KEYS = ['format', 'video_codec', 'streaming_profile'];
40
+ const stripKeysDeep = value => {
41
+ if (Array.isArray(value)) {
42
+ return value.map(stripKeysDeep);
43
+ }
44
+ if (value && typeof value === 'object') {
45
+ const cleaned = omit(value, STRIP_KEYS);
46
+ Object.keys(cleaned).forEach(k => {
47
+ cleaned[k] = stripKeysDeep(cleaned[k]);
48
+ });
49
+ return cleaned;
50
+ }
51
+ return value;
52
+ };
53
+ const transformations = stripKeysDeep(player.cloudinary.transformation() || {});
54
+ const filename = player.cloudinary.currentPublicId()?.split('/')?.pop();
55
+ const baseOptions = {
56
+ ...player.cloudinary.cloudinaryConfig(),
57
+ ...transformations,
58
+ resource_type: 'video',
59
+ format: 'mp4',
60
+ video_codec: 'h264',
61
+ flags: `streaming_attachment:${filename}`
62
+ };
63
+
64
+ // For ABR - download a limited-size video
65
+ if (source.isAdaptive) {
66
+ Object.assign(baseOptions, {
67
+ crop: 'limit',
68
+ width: 1920,
69
+ height: 1920
70
+ });
71
+ }
72
+
73
+ // For audio sources, set the format to mp3
74
+ if (player.cloudinary.source()?.getType() === 'AudioSource') {
75
+ Object.assign(baseOptions, {
76
+ format: 'mp3',
77
+ video_codec: undefined
78
+ });
79
+ }
80
+ return getCloudinaryUrl(player.cloudinary.currentPublicId(), baseOptions);
81
+ };
82
+ const download = () => {
83
+ const url = getDownloadUrl();
84
+ if (!url) {
85
+ console.warn('Share plugin: Unable to resolve download URL.');
86
+ return;
87
+ }
88
+ const MAX_ATTEMPTS = 60; // 60 tries / 10s interval
89
+ const INTERVAL_MS = 10000;
90
+ const RETRY_STATUS_CODES = [423];
91
+ const triggerDownload = () => {
92
+ const a = document.createElement('a');
93
+ a.href = url;
94
+ a.download = '';
95
+ document.body.appendChild(a);
96
+ a.click();
97
+ document.body.removeChild(a);
98
+ };
99
+ const btn = player.controlBar?.getChild('ShareDownloadButton');
100
+ const setPreparingState = isPreparing => {
101
+ btn?.setPreparing?.(isPreparing);
102
+ };
103
+ const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
104
+ const fetchDownload = async function () {
105
+ let attempt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
106
+ const response = await fetch(url, {
107
+ method: 'HEAD'
108
+ });
109
+ if (RETRY_STATUS_CODES.includes(response.status) && attempt < MAX_ATTEMPTS) {
110
+ await wait(INTERVAL_MS);
111
+ return fetchDownload(attempt + 1);
112
+ }
113
+ setPreparingState(false);
114
+ triggerDownload();
115
+ };
116
+ setPreparingState(true);
117
+ fetchDownload();
118
+ };
119
+ if (options.download) {
120
+ addDownloadButton();
121
+ }
122
+ player.share = {
123
+ download,
124
+ addDownloadButton,
125
+ removeDownloadButton
126
+ };
127
+ };
128
+
129
+ export { SharePlugin as default };