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.
- package/dist/134.min.js +8 -0
- package/dist/309.min.js +6 -0
- package/dist/adaptive-streaming.js +9 -9
- package/dist/adaptive-streaming.min.js +2 -2
- package/dist/chapters.js +4 -4
- package/dist/chapters.min.js +3 -3
- package/dist/cld-player-core.js +37 -0
- package/dist/cld-player-core.min.js +6 -0
- package/dist/cld-video-player-lazy.js +494 -0
- package/dist/cld-video-player-lazy.min.js +6 -0
- package/dist/cld-video-player.css +2 -2
- package/dist/cld-video-player.js +366 -332
- package/dist/cld-video-player.light.js +366 -332
- package/dist/cld-video-player.light.min.js +4 -4
- package/dist/cld-video-player.min.css +2 -2
- package/dist/cld-video-player.min.js +4 -4
- package/dist/colors.js +4 -4
- package/dist/colors.min.js +2 -2
- package/dist/dash.js +6 -6
- package/dist/dash.min.js +2 -2
- package/dist/debug.js +8 -8
- package/dist/debug.min.js +3 -3
- package/dist/ima.js +9 -9
- package/dist/ima.min.js +2 -2
- package/dist/interaction-areas.js +11 -11
- package/dist/interaction-areas.min.js +2 -2
- package/dist/node_modules_lodash_throttle_js.js +8 -8
- package/dist/playlist.js +31 -31
- package/dist/playlist.min.js +3 -3
- package/dist/recommendations-overlay.js +10 -10
- package/dist/recommendations-overlay.min.js +2 -2
- package/dist/schema.json +19 -0
- package/dist/share.js +5 -5
- package/dist/share.min.js +3 -3
- package/dist/shoppable.js +12 -12
- package/dist/shoppable.min.js +2 -2
- package/dist/utils_fetch-config_js.js +81 -0
- package/dist/video-player_js.js +3111 -0
- package/dist/visual-search.js +7 -7
- package/dist/visual-search.min.js +2 -2
- package/lib/_commonjsHelpers.js +7 -0
- package/lib/_videojs-proxy.js +30294 -0
- package/lib/abr-strategies.js +31 -0
- package/lib/adaptive-streaming.js +468 -2
- package/lib/all.js +25 -2
- package/lib/chapters.js +205 -1
- package/lib/cld-video-player.min.css +5 -22
- package/lib/colors.js +59 -1
- package/lib/{schema.json → config/configSchema.json} +19 -0
- package/lib/dash.js +69943 -2
- package/lib/debug.js +322 -1
- package/lib/document.js +770 -0
- package/lib/download-button.js +48 -0
- package/lib/fetch-config.js +93 -0
- package/lib/ima.js +6851 -1
- package/lib/index.js +27 -0
- package/lib/interaction-areas.const.js +24 -0
- package/lib/interaction-areas.service.js +469 -0
- package/lib/lazy.js +20 -0
- package/lib/noop.js +33 -0
- package/lib/player-api.js +469 -0
- package/lib/player.js +7 -2
- package/lib/playlist-panel.js +602 -0
- package/lib/playlist.js +637 -1
- package/lib/querystring.js +81 -0
- package/lib/recommendations-overlay.js +320 -1
- package/lib/share.js +129 -1
- package/lib/shoppable-post-widget.js +572 -0
- package/lib/shoppable-widget.js +77 -0
- package/lib/throttle.js +318 -0
- package/lib/toNumber.js +134 -0
- package/lib/validators-functions.js +485 -0
- package/lib/video-player.js +16241 -0
- package/lib/videoPlayer.js +7 -2
- package/lib/videojs-contrib-hlsjs.js +37638 -0
- package/lib/visual-search.js +235 -1
- package/package.json +31 -15
- package/lib/adaptive-streaming.js.LICENSE.txt +0 -3
- package/lib/all.js.LICENSE.txt +0 -25
- package/lib/cld-video-player.js +0 -2
- package/lib/cld-video-player.js.LICENSE.txt +0 -21
- package/lib/dash.js.LICENSE.txt +0 -1842
- package/lib/interaction-areas.js +0 -1
- package/lib/player.js.LICENSE.txt +0 -21
- package/lib/shoppable.js +0 -1
- 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
|
-
|
|
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
|
-
|
|
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 };
|