@micromag/element-video 0.3.682 → 0.3.703

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 (2) hide show
  1. package/es/index.js +85 -211
  2. package/package.json +4 -4
package/es/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
2
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
3
3
  import classNames from 'classnames';
4
- import Hls from 'hls.js';
5
4
  import isFunction from 'lodash/isFunction';
6
5
  import PropTypes from 'prop-types';
7
6
  import React, { useMemo, useRef, useState, useEffect, useCallback } from 'react';
@@ -10,6 +9,65 @@ import { Spinner } from '@micromag/core/components';
10
9
  import { useMediaThumbnail, useMediaCurrentTime, useMediaDuration, useMediaReady, useProgressSteps } from '@micromag/core/hooks';
11
10
  import { getMediaFilesAsArray, getVideoSupportedMimes } from '@micromag/core/utils';
12
11
 
12
+ function useSources(media) {
13
+ var _ref = media || {},
14
+ _ref$files = _ref.files,
15
+ mediaFiles = _ref$files === void 0 ? null : _ref$files,
16
+ _ref$metadata = _ref.metadata,
17
+ metadata = _ref$metadata === void 0 ? null : _ref$metadata;
18
+ var _ref2 = metadata || {},
19
+ _ref2$mime = _ref2.mime,
20
+ mediaMime = _ref2$mime === void 0 ? null : _ref2$mime;
21
+ var files = useMemo(function () {
22
+ return getMediaFilesAsArray(mediaFiles);
23
+ }, [mediaFiles]);
24
+ var sources = useMemo(function () {
25
+ if (files.length === 0) {
26
+ return null;
27
+ }
28
+ var supportedMimes = getVideoSupportedMimes();
29
+ if (supportedMimes.length === 0) {
30
+ supportedMimes = ['video/mp4', 'video/webm'];
31
+ }
32
+ var supportedFiles = files.filter(function (file) {
33
+ var fileHandle = file.handle || file.id;
34
+ var _file$mime = file.mime,
35
+ mime = _file$mime === void 0 ? "video/".concat(fileHandle === 'h264' ? 'mp4' : fileHandle) : _file$mime;
36
+ return supportedMimes.indexOf(mime) !== -1;
37
+ });
38
+ var supportedFilesWithoutOriginal = supportedFiles.filter(function (file) {
39
+ var fileHandle = file.handle || file.id;
40
+ return fileHandle !== 'original';
41
+ });
42
+ return (supportedFilesWithoutOriginal.length > 0 ? supportedFilesWithoutOriginal : supportedFiles).sort(function (_ref3, _ref4) {
43
+ var _ref3$size = _ref3.size,
44
+ a = _ref3$size === void 0 ? Infinity : _ref3$size;
45
+ var _ref4$size = _ref4.size,
46
+ b = _ref4$size === void 0 ? Infinity : _ref4$size;
47
+ if (a === b) {
48
+ return 0;
49
+ }
50
+ return a > b ? 1 : -1;
51
+ });
52
+ }, [files]);
53
+
54
+ // @NOTE: Media is an animated image and doesn't have source files in video formats
55
+ var _ref5 = files.find(function (_ref6) {
56
+ var handle = _ref6.handle;
57
+ return handle === 'original';
58
+ }) || {},
59
+ _ref5$type = _ref5.type,
60
+ originalType = _ref5$type === void 0 ? null : _ref5$type,
61
+ _ref5$mime = _ref5.mime,
62
+ originalMime = _ref5$mime === void 0 ? mediaMime : _ref5$mime;
63
+ var originalFileIsImage = originalType === 'image' || originalMime !== null && originalMime.indexOf('image/') === 0;
64
+ return {
65
+ sources: sources !== null && sources.length > 0 ? sources : null,
66
+ files: files,
67
+ isImage: originalFileIsImage
68
+ };
69
+ }
70
+
13
71
  var styles = {"container":"micromag-element-video-container","withSize":"micromag-element-video-withSize","media":"micromag-element-video-media","spinner":"micromag-element-video-spinner"};
14
72
 
15
73
  var propTypes = {
@@ -27,7 +85,6 @@ var propTypes = {
27
85
  playsInline: PropTypes.bool,
28
86
  preload: PropTypes.oneOf(['auto', 'metadata', 'none', null]),
29
87
  disablePictureInPicture: PropTypes.bool,
30
- disableHls: PropTypes.bool,
31
88
  shouldLoad: PropTypes.bool,
32
89
  withoutCors: PropTypes.bool,
33
90
  className: PropTypes.string,
@@ -44,11 +101,9 @@ var propTypes = {
44
101
  onSuspend: PropTypes.func,
45
102
  onSuspended: PropTypes.func,
46
103
  onPlayError: PropTypes.func,
47
- onQualityLevelChange: PropTypes.func,
48
104
  focusable: PropTypes.bool,
49
105
  withPoster: PropTypes.bool,
50
- withLoading: PropTypes.bool,
51
- qualityStartLevel: PropTypes.number
106
+ withLoading: PropTypes.bool
52
107
  };
53
108
  var defaultProps = {
54
109
  media: null,
@@ -63,7 +118,6 @@ var defaultProps = {
63
118
  playsInline: true,
64
119
  preload: 'auto',
65
120
  disablePictureInPicture: true,
66
- disableHls: true,
67
121
  shouldLoad: true,
68
122
  withoutCors: false,
69
123
  className: null,
@@ -80,11 +134,9 @@ var defaultProps = {
80
134
  onSuspend: null,
81
135
  onSuspended: null,
82
136
  onPlayError: null,
83
- onQualityLevelChange: null,
84
137
  focusable: true,
85
138
  withPoster: false,
86
- withLoading: false,
87
- qualityStartLevel: null
139
+ withLoading: false
88
140
  };
89
141
  var Video = function Video(_ref) {
90
142
  var media = _ref.media,
@@ -114,44 +166,38 @@ var Video = function Video(_ref) {
114
166
  customOnSuspend = _ref.onSuspend,
115
167
  onSuspended = _ref.onSuspended,
116
168
  onPlayError = _ref.onPlayError,
117
- onQualityLevelChange = _ref.onQualityLevelChange,
118
169
  focusable = _ref.focusable,
119
170
  withPoster = _ref.withPoster,
120
171
  withLoading = _ref.withLoading,
121
- disablePictureInPicture = _ref.disablePictureInPicture,
122
- disableHls = _ref.disableHls,
123
- qualityStartLevel = _ref.qualityStartLevel;
172
+ disablePictureInPicture = _ref.disablePictureInPicture;
124
173
  var _ref2 = media || {},
125
174
  _ref2$url = _ref2.url,
126
175
  mediaUrl = _ref2$url === void 0 ? null : _ref2$url,
127
- _ref2$files = _ref2.files,
128
- files = _ref2$files === void 0 ? null : _ref2$files,
129
176
  _ref2$metadata = _ref2.metadata,
130
177
  metadata = _ref2$metadata === void 0 ? null : _ref2$metadata;
131
178
  var _ref3 = metadata || {},
132
179
  _ref3$description = _ref3.description,
133
180
  description = _ref3$description === void 0 ? null : _ref3$description,
134
- _ref3$mime = _ref3.mime,
135
- mediaMime = _ref3$mime === void 0 ? null : _ref3$mime,
136
181
  _ref3$has_audio = _ref3.has_audio,
137
182
  hasAudio = _ref3$has_audio === void 0 ? null : _ref3$has_audio;
138
- var filesArray = useMemo(function () {
139
- return getMediaFilesAsArray(files);
140
- }, [files]);
141
183
  var finalThumbnail = useMediaThumbnail(media, thumbnail);
142
- var _ref17 = useRef(null);
143
- var currentTime = useMediaCurrentTime(_ref17.current, {
184
+ var _useSources = useSources(media),
185
+ sources = _useSources.sources,
186
+ isImage = _useSources.isImage;
187
+ var isImageWithoutSourceFile = isImage && (sources === null || sources.length === 0);
188
+ var _ref6 = useRef(null);
189
+ var currentTime = useMediaCurrentTime(_ref6.current, {
144
190
  id: mediaUrl,
145
191
  disabled: paused || onProgressStep === null
146
192
  });
147
- var duration = useMediaDuration(_ref17.current, {
193
+ var duration = useMediaDuration(_ref6.current, {
148
194
  id: mediaUrl
149
195
  });
150
196
  var _useState = useState(false),
151
197
  _useState2 = _slicedToArray(_useState, 2),
152
198
  showLoading = _useState2[0],
153
199
  setShowLoading = _useState2[1];
154
- var ready = useMediaReady(_ref17.current, {
200
+ var ready = useMediaReady(_ref6.current, {
155
201
  id: mediaUrl
156
202
  });
157
203
  useEffect(function () {
@@ -166,176 +212,6 @@ var Video = function Video(_ref) {
166
212
  clearTimeout(id);
167
213
  };
168
214
  }, [mediaUrl, withLoading]);
169
- var _useState3 = useState(false),
170
- _useState4 = _slicedToArray(_useState3, 2),
171
- hlsFailed = _useState4[0],
172
- setHlsFailed = _useState4[1];
173
- var hlsSources = useMemo(function () {
174
- if (filesArray.length === 0 || disableHls || !Hls.isSupported() || hlsFailed) {
175
- return null;
176
- }
177
- return filesArray.filter(function (_ref4) {
178
- var _ref4$mime = _ref4.mime,
179
- mime = _ref4$mime === void 0 ? null : _ref4$mime,
180
- _ref4$name = _ref4.name,
181
- name = _ref4$name === void 0 ? null : _ref4$name;
182
- return mime === 'application/vnd.apple.mpegurl' || (name || '').endsWith('.m3u8');
183
- });
184
- }, [filesArray, disableHls, hlsFailed]);
185
- var _useState5 = useState(null),
186
- _useState6 = _slicedToArray(_useState5, 2),
187
- hlsJs = _useState6[0],
188
- setHlsJs = _useState6[1];
189
- var _useState7 = useState(0),
190
- _useState8 = _slicedToArray(_useState7, 2),
191
- hlsTsOffset = _useState8[0],
192
- setHlsTsOffset = _useState8[1];
193
-
194
- // initialize hls instance if an hls source is provided
195
- useEffect(function () {
196
- setHlsTsOffset(0);
197
- setHlsFailed(false);
198
- if (!shouldLoad || hlsSources === null || hlsSources.length === 0) {
199
- setHlsJs(null);
200
- return;
201
- }
202
- var hls = new Hls({
203
- maxBufferLength: 15,
204
- // seconds. prevents loading too much per screen.
205
- startLevel: qualityStartLevel !== null ? qualityStartLevel : -1,
206
- enableWorker: true
207
- // debug: true,
208
- // lowLatencyMode: true,
209
- // backBufferLength: 90,
210
- // testBandwidth: qualityStartLevel === null,
211
- // startFragPrefetch: true,
212
- });
213
- hls.on(Hls.Events.LEVEL_SWITCHED, function (_, _ref5) {
214
- var level = _ref5.level;
215
- if (onQualityLevelChange !== null) {
216
- onQualityLevelChange(level, _ref17.current);
217
- }
218
- });
219
- hls.on(Hls.Events.ERROR, function (_, _ref6) {
220
- var isFatal = _ref6.fatal,
221
- errorType = _ref6.type;
222
- if (isFatal) {
223
- switch (errorType) {
224
- case Hls.ErrorTypes.MEDIA_ERROR:
225
- // automatically try to recover from media errors
226
- hls.recoverMediaError();
227
- break;
228
- case Hls.ErrorTypes.NETWORK_ERROR:
229
- // happens when all retries and media options have been exhausted. in that case, fallback to mp4/webm playback
230
- setHlsJs(null);
231
- setHlsFailed(true);
232
- break;
233
- }
234
- }
235
- });
236
-
237
- // compute hls timestamp offset when we get the first video fragment
238
- var _onHlsBufferAppended = function onHlsBufferAppended(_, _ref7) {
239
- var frag = _ref7.frag;
240
- var fragStart = frag.start,
241
- fragType = frag.type,
242
- _frag$sn = frag.sn,
243
- fragSn = _frag$sn === void 0 ? null : _frag$sn,
244
- _frag$elementaryStrea = frag.elementaryStreams.video,
245
- videoStream = _frag$elementaryStrea === void 0 ? null : _frag$elementaryStrea;
246
- var _ref8 = videoStream || {},
247
- _ref8$startPTS = _ref8.startPTS,
248
- videoStartPTS = _ref8$startPTS === void 0 ? null : _ref8$startPTS;
249
- if (fragType === 'main' && fragSn !== 'initSegment' && videoStartPTS !== null) {
250
- var tOffset = videoStartPTS - fragStart;
251
- hls.off(Hls.Events.BUFFER_APPENDED, _onHlsBufferAppended);
252
- setHlsTsOffset(tOffset);
253
- }
254
- };
255
- hls.on(Hls.Events.BUFFER_APPENDED, _onHlsBufferAppended);
256
- hls.loadSource(hlsSources[0].url);
257
- setHlsJs(hls);
258
- }, [shouldLoad, hlsSources]);
259
-
260
- // attach hls.js when the <video> ref or the hls.js instance is ready
261
- useEffect(function () {
262
- if (hlsJs !== null && _ref17.current !== null) {
263
- hlsJs.attachMedia(_ref17.current);
264
- // if (onQualityLevelChange !== null) {
265
- // onQualityLevelChange(hlsJs.currentLevel, ref.current);
266
- // }
267
- }
268
- return function () {
269
- if (hlsJs !== null) {
270
- hlsJs.detachMedia();
271
- }
272
- };
273
- }, [hlsJs, _ref17.current]);
274
-
275
- // cleanup hls.js instance when it is no longer needed
276
- useEffect(function () {
277
- return (
278
- // teardown func
279
- function () {
280
- if (hlsJs !== null) {
281
- hlsJs.destroy();
282
- }
283
- }
284
- );
285
- }, [hlsJs]);
286
-
287
- // handle changes of qualityStartLevel when an hls.js instance exists
288
- useEffect(function () {
289
- if (hlsJs !== null) {
290
- var qualityLevel = qualityStartLevel !== null ? qualityStartLevel : -1;
291
- hlsJs.startLevel = qualityLevel;
292
- if (_ref17.current !== null && _ref17.current.paused) {
293
- hlsJs.currentLevel = qualityLevel;
294
- hlsJs.nextLevel = -1; // force auto quality selection for the next fragment
295
- }
296
- }
297
- }, [qualityStartLevel]);
298
- var sourceFiles = useMemo(function () {
299
- if (filesArray.length === 0 || hlsSources !== null && hlsSources.length > 0) {
300
- return null;
301
- }
302
- var supportedMimes = getVideoSupportedMimes();
303
- if (supportedMimes.length === 0) {
304
- supportedMimes = ['video/mp4', 'video/webm'];
305
- }
306
- var supportedFiles = filesArray.filter(function (file) {
307
- var fileHandle = file.handle || file.id;
308
- var _file$mime = file.mime,
309
- mime = _file$mime === void 0 ? "video/".concat(fileHandle === 'h264' ? 'mp4' : fileHandle) : _file$mime;
310
- return supportedMimes.indexOf(mime) !== -1;
311
- });
312
- var supportedFilesWithoutOriginal = supportedFiles.filter(function (file) {
313
- var fileHandle = file.handle || file.id;
314
- return fileHandle !== 'original';
315
- });
316
- return (supportedFilesWithoutOriginal.length > 0 ? supportedFilesWithoutOriginal : supportedFiles).sort(function (_ref9, _ref10) {
317
- var _ref9$size = _ref9.size,
318
- a = _ref9$size === void 0 ? '' : _ref9$size;
319
- var _ref10$size = _ref10.size,
320
- b = _ref10$size === void 0 ? '' : _ref10$size;
321
- if (a === b) {
322
- return 0;
323
- }
324
- return a > b ? 1 : -1;
325
- });
326
- }, [filesArray, hlsSources]);
327
-
328
- // @NOTE: Media is an animated image and doesn't have source files in video formats
329
- var _ref11 = filesArray.find(function (_ref12) {
330
- var handle = _ref12.handle;
331
- return handle === 'original';
332
- }) || {},
333
- _ref11$type = _ref11.type,
334
- originalType = _ref11$type === void 0 ? null : _ref11$type,
335
- _ref11$mime = _ref11.mime,
336
- originalMime = _ref11$mime === void 0 ? mediaMime : _ref11$mime;
337
- var originalFileIsImage = originalType === 'image' || originalMime !== null && originalMime.indexOf('image/') === 0;
338
- var isImageWithoutSourceFile = originalFileIsImage && (sourceFiles === null || sourceFiles.length === 0);
339
215
  var withSize = width !== null && height !== null;
340
216
  useEffect(function () {
341
217
  if (duration > 0 && customOnDurationChange !== null) {
@@ -343,7 +219,7 @@ var Video = function Video(_ref) {
343
219
  }
344
220
  }, [duration, customOnDurationChange]);
345
221
  var onVolumeChange = useCallback(function () {
346
- var _ref$current = _ref17.current,
222
+ var _ref$current = _ref6.current,
347
223
  element = _ref$current === void 0 ? null : _ref$current;
348
224
  if (element === null) {
349
225
  return;
@@ -354,10 +230,10 @@ var Video = function Video(_ref) {
354
230
  }, [customOnVolumeChange]);
355
231
 
356
232
  // Manage suspend
357
- var _useState9 = useState(false),
358
- _useState10 = _slicedToArray(_useState9, 2),
359
- isSuspended = _useState10[0],
360
- setIsSuspended = _useState10[1];
233
+ var _useState3 = useState(false),
234
+ _useState4 = _slicedToArray(_useState3, 2),
235
+ isSuspended = _useState4[0],
236
+ setIsSuspended = _useState4[1];
361
237
  var onPlay = useCallback(function (e) {
362
238
  if (isSuspended) {
363
239
  setIsSuspended(false);
@@ -388,7 +264,7 @@ var Video = function Video(_ref) {
388
264
  }
389
265
  }, [ready, onReady]);
390
266
  useEffect(function () {
391
- var _ref$current2 = _ref17.current,
267
+ var _ref$current2 = _ref6.current,
392
268
  element = _ref$current2 === void 0 ? null : _ref$current2;
393
269
  if (element === null) {
394
270
  return;
@@ -412,7 +288,7 @@ var Video = function Video(_ref) {
412
288
  onStep: onProgressStep
413
289
  });
414
290
  return /*#__PURE__*/React.createElement("div", {
415
- className: classNames([styles.container, _defineProperty(_defineProperty({}, className, className !== null), styles.withSize, withSize)]),
291
+ className: classNames([styles.container, _defineProperty({}, styles.withSize, withSize), className]),
416
292
  style: withSize ? {
417
293
  width: width,
418
294
  height: height
@@ -421,18 +297,18 @@ var Video = function Video(_ref) {
421
297
  src: mediaUrl,
422
298
  alt: description,
423
299
  tabIndex: "-1",
424
- className: classNames([styles.media, _defineProperty({}, innerClassName, innerClassName !== null)])
300
+ className: classNames([styles.media, innerClassName])
425
301
  }) : null, !isImageWithoutSourceFile ? /*#__PURE__*/React.createElement("video", {
426
302
  key: mediaUrl,
427
303
  ref: function ref(newRef) {
428
- _ref17.current = newRef;
304
+ _ref6.current = newRef;
429
305
  if (mediaRef !== null && isFunction(mediaRef)) {
430
306
  mediaRef(newRef);
431
307
  } else if (mediaRef !== null) {
432
308
  mediaRef.current = newRef;
433
309
  }
434
310
  },
435
- src: (sourceFiles === null || sourceFiles.length === 0) && (hlsSources === null || hlsSources.length === 0) && shouldLoad ? "".concat(mediaUrl, "#t=0.001") : null,
311
+ src: sources === null && shouldLoad ? "".concat(mediaUrl, "#t=0.001") : null,
436
312
  autoPlay: autoPlay && !paused,
437
313
  loop: loop,
438
314
  muted: muted,
@@ -442,7 +318,7 @@ var Video = function Video(_ref) {
442
318
  crossOrigin: withoutCors ? 'anonymous' : null,
443
319
  disablePictureInPicture: disablePictureInPicture,
444
320
  tabIndex: focusable ? '0' : '-1',
445
- className: classNames([styles.media, _defineProperty({}, innerClassName, innerClassName !== null)]),
321
+ className: classNames([styles.media, innerClassName]),
446
322
  onPlay: onPlay,
447
323
  onPlaying: onPlaying,
448
324
  onPause: onPause,
@@ -453,14 +329,12 @@ var Video = function Video(_ref) {
453
329
  onSuspend: onSuspend,
454
330
  "data-has-audio": hasAudio,
455
331
  "data-is-suspended": isSuspended,
456
- "data-hls": hlsJs !== null,
457
- "data-ts-offset": hlsTsOffset,
458
332
  "aria-hidden": true
459
- }, (shouldLoad ? sourceFiles || [] : []).map(function (_ref16) {
460
- var sourceUrl = _ref16.url,
461
- sourceMime = _ref16.mime;
333
+ }, (shouldLoad && sources !== null ? sources : []).map(function (_ref5) {
334
+ var sourceUrl = _ref5.url,
335
+ sourceMime = _ref5.mime;
462
336
  return /*#__PURE__*/React.createElement("source", {
463
- key: "".concat(sourceUrl, "-").concat(sourceMime),
337
+ key: "source-".concat(sourceUrl, "-").concat(sourceMime),
464
338
  src: sourceUrl !== null ? "".concat(sourceUrl, "#t=0.001") : null,
465
339
  type: sourceMime
466
340
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micromag/element-video",
3
- "version": "0.3.682",
3
+ "version": "0.3.703",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "keywords": [
@@ -59,8 +59,8 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@babel/runtime": "^7.13.10",
62
- "@micromag/core": "^0.3.679",
63
- "@micromag/element-closed-captions": "^0.3.679",
62
+ "@micromag/core": "^0.3.703",
63
+ "@micromag/element-closed-captions": "^0.3.703",
64
64
  "classnames": "^2.2.6",
65
65
  "hls.js": "^1.5.15",
66
66
  "lodash": "^4.17.21",
@@ -72,5 +72,5 @@
72
72
  "access": "public",
73
73
  "registry": "https://registry.npmjs.org/"
74
74
  },
75
- "gitHead": "ff77a57d44913b0e5afa373445ae9f014799e183"
75
+ "gitHead": "15a0df01ed9d05f47a056fb2ff078aded803d33d"
76
76
  }