@micromag/element-video 0.3.679 → 0.3.700

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