@micromag/element-audio 0.3.147 → 0.3.152

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 (3) hide show
  1. package/es/index.js +141 -155
  2. package/lib/index.js +142 -156
  3. package/package.json +6 -5
package/es/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
- import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
3
- import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
4
- import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
5
2
  import classNames from 'classnames';
3
+ import isFunction from 'lodash/isFunction';
6
4
  import PropTypes from 'prop-types';
7
- import React, { useRef, useMemo, useEffect, useCallback, useState } from 'react';
5
+ import React, { useRef, useMemo, useEffect, useCallback } from 'react';
8
6
  import { PropTypes as PropTypes$1 } from '@micromag/core';
9
- import { useUserInteracted } from '@micromag/core/contexts';
10
- import { useResizeObserver, useMediaApi } from '@micromag/core/hooks';
7
+ import { useDimensionObserver, useMediaCurrentTime, useMediaReady, useMediaDuration, useMediaWaveform, useMediaLoad, useProgressSteps } from '@micromag/core/hooks';
8
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
9
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
11
10
  import { useSpring } from '@react-spring/core';
12
11
  import { animated } from '@react-spring/web';
13
12
  import { useGesture } from '@use-gesture/react';
@@ -74,14 +73,11 @@ function AudioWave(_ref) {
74
73
  return getContrastingColor(backgroundColor, progressColor);
75
74
  }, [progressColor, backgroundColor]);
76
75
 
77
- var _useResizeObserver = useResizeObserver(),
78
- elRef = _useResizeObserver.ref,
79
- elContentRect = _useResizeObserver.entry.contentRect;
80
-
81
- var _ref3 = elContentRect || {},
82
- _ref3$width = _ref3.width,
83
- elWidth = _ref3$width === void 0 ? null : _ref3$width,
84
- elHeight = _ref3.height; // Linear animation for progress bar
76
+ var _useDimensionObserver = useDimensionObserver(),
77
+ elRef = _useDimensionObserver.ref,
78
+ _useDimensionObserver2 = _useDimensionObserver.width,
79
+ elWidth = _useDimensionObserver2 === void 0 ? null : _useDimensionObserver2,
80
+ elHeight = _useDimensionObserver.height; // Linear animation for progress bar
85
81
 
86
82
 
87
83
  var _useSpring = useSpring(function () {
@@ -195,8 +191,11 @@ function AudioWave(_ref) {
195
191
  }, [audioLevels, sampleWidth, sampleMargin, minSampleHeight, elWidth, elHeight, mainColor, alternateColor, onReady]); // User events
196
192
 
197
193
  var seekFromX = useCallback(function (x) {
198
- var elX = elRef.current.getBoundingClientRect().left;
199
- var progress = Math.max(0, Math.min(1, (x - elX) / elWidth));
194
+ var _elRef$current$getBou = elRef.current.getBoundingClientRect(),
195
+ elX = _elRef$current$getBou.left,
196
+ width = _elRef$current$getBou.width;
197
+
198
+ var progress = Math.max(0, Math.min(1, (x - elX) / width));
200
199
 
201
200
  if (onSeek !== null && duration !== null) {
202
201
  onSeek(progress * duration);
@@ -207,11 +206,11 @@ function AudioWave(_ref) {
207
206
  }
208
207
  }, [duration, playing, onSeek, onResume]);
209
208
  var bind = useGesture({
210
- onDrag: function onDrag(_ref4) {
211
- var _ref4$xy = _slicedToArray(_ref4.xy, 1),
212
- x = _ref4$xy[0],
213
- elapsedTime = _ref4.elapsedTime,
214
- active = _ref4.active;
209
+ onDrag: function onDrag(_ref3) {
210
+ var _ref3$xy = _slicedToArray(_ref3.xy, 1),
211
+ x = _ref3$xy[0],
212
+ elapsedTime = _ref3.elapsedTime,
213
+ active = _ref3.active;
215
214
 
216
215
  if (!active && elapsedTime > 300) {
217
216
  return;
@@ -247,22 +246,24 @@ AudioWave.defaultProps = defaultProps$1;
247
246
 
248
247
  var styles = {"container":"micromag-element-audio-container","wave":"micromag-element-audio-wave"};
249
248
 
250
- var _excluded = ["ref"];
251
249
  var propTypes = {
252
250
  media: PropTypes$1.audioMedia,
253
- apiRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
251
+ mediaRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
254
252
  current: PropTypes.any
255
253
  })]),
256
- initialMuted: PropTypes.oneOf(['auto', true, false]),
254
+ muted: PropTypes.bool,
257
255
  autoPlay: PropTypes.bool,
256
+ paused: PropTypes.bool,
258
257
  loop: PropTypes.bool,
258
+ preload: PropTypes.oneOf(['auto', 'none', 'metadata']),
259
+ shouldLoad: PropTypes.bool,
259
260
  waveFake: PropTypes.bool,
260
261
  waveProps: PropTypes.shape({
261
262
  sampleWidth: PropTypes.number,
262
263
  sampleMargin: PropTypes.number,
263
264
  minSampleHeight: PropTypes.number
264
265
  }),
265
- showWave: PropTypes.bool,
266
+ withWave: PropTypes.bool,
266
267
  reduceBufferFactor: PropTypes.number,
267
268
  className: PropTypes.string,
268
269
  onReady: PropTypes.func,
@@ -272,18 +273,21 @@ var propTypes = {
272
273
  onSeeked: PropTypes.func,
273
274
  onTimeUpdate: PropTypes.func,
274
275
  onProgressStep: PropTypes.func,
275
- onDurationChanged: PropTypes.func,
276
- onVolumeChanged: PropTypes.func
276
+ onDurationChange: PropTypes.func,
277
+ onVolumeChange: PropTypes.func
277
278
  };
278
279
  var defaultProps = {
279
280
  media: null,
280
- apiRef: null,
281
- initialMuted: 'auto',
281
+ mediaRef: null,
282
+ muted: false,
282
283
  autoPlay: false,
284
+ paused: false,
283
285
  loop: false,
286
+ preload: 'auto',
287
+ shouldLoad: true,
284
288
  waveFake: false,
285
289
  waveProps: null,
286
- showWave: false,
290
+ withWave: false,
287
291
  reduceBufferFactor: 100,
288
292
  className: null,
289
293
  onReady: null,
@@ -293,19 +297,22 @@ var defaultProps = {
293
297
  onSeeked: null,
294
298
  onTimeUpdate: null,
295
299
  onProgressStep: null,
296
- onDurationChanged: null,
297
- onVolumeChanged: null
300
+ onDurationChange: null,
301
+ onVolumeChange: null
298
302
  };
299
303
 
300
304
  var Audio = function Audio(_ref) {
301
305
  var media = _ref.media,
302
- apiRef = _ref.apiRef,
303
- initialMuted = _ref.initialMuted,
306
+ mediaRef = _ref.mediaRef,
307
+ muted = _ref.muted,
304
308
  autoPlay = _ref.autoPlay,
309
+ paused = _ref.paused,
305
310
  loop = _ref.loop,
311
+ preload = _ref.preload,
312
+ shouldLoad = _ref.shouldLoad,
306
313
  waveFake = _ref.waveFake,
307
314
  waveProps = _ref.waveProps,
308
- showWave = _ref.showWave,
315
+ withWave = _ref.withWave,
309
316
  reduceBufferFactor = _ref.reduceBufferFactor,
310
317
  className = _ref.className,
311
318
  onReady = _ref.onReady,
@@ -315,153 +322,132 @@ var Audio = function Audio(_ref) {
315
322
  onSeeked = _ref.onSeeked,
316
323
  onTimeUpdate = _ref.onTimeUpdate,
317
324
  onProgressStep = _ref.onProgressStep,
318
- onDurationChanged = _ref.onDurationChanged,
319
- onVolumeChanged = _ref.onVolumeChanged;
325
+ customOnDurationChange = _ref.onDurationChange,
326
+ customOnVolumeChange = _ref.onVolumeChange;
320
327
 
321
328
  var _ref2 = media || {},
322
329
  _ref2$url = _ref2.url,
323
- url = _ref2$url === void 0 ? null : _ref2$url,
324
- _ref2$metadata = _ref2.metadata,
325
- metadata = _ref2$metadata === void 0 ? null : _ref2$metadata;
330
+ url = _ref2$url === void 0 ? null : _ref2$url;
326
331
 
327
- var _ref3 = metadata || {},
328
- _ref3$waveform = _ref3.waveform,
329
- waveform = _ref3$waveform === void 0 ? null : _ref3$waveform;
332
+ var _ref4 = useRef(null);
330
333
 
331
- var userInteracted = useUserInteracted();
332
- var finalInitialMuted = initialMuted === true || initialMuted === 'auto' && autoPlay && !userInteracted;
334
+ var currentTime = useMediaCurrentTime(_ref4.current, {
335
+ id: url,
336
+ disabled: paused || !withWave && onProgressStep === null
337
+ });
338
+ var ready = useMediaReady(_ref4.current, {
339
+ id: url
340
+ });
341
+ var duration = useMediaDuration(_ref4.current, {
342
+ id: url
343
+ });
344
+ var audioLevels = useMediaWaveform(media, {
345
+ fake: waveFake,
346
+ reduceBufferFactor: reduceBufferFactor
347
+ });
348
+ useMediaLoad(_ref4.current, {
349
+ preload: preload,
350
+ shouldLoad: shouldLoad
351
+ });
352
+ var waveReady = waveFake || ready;
353
+ useEffect(function () {
354
+ if (duration > 0 && customOnDurationChange !== null) {
355
+ customOnDurationChange(duration);
356
+ }
357
+ }, [duration, customOnDurationChange]);
358
+ var onVolumeChange = useCallback(function () {
359
+ var _ref$current = _ref4.current,
360
+ element = _ref$current === void 0 ? null : _ref$current;
333
361
 
334
- var _useMediaApi = useMediaApi({
335
- url: url,
336
- initialMuted: finalInitialMuted,
337
- onPlay: onPlay,
338
- onPause: onPause,
339
- onEnded: onEnded,
340
- onSeeked: onSeeked,
341
- onTimeUpdate: onTimeUpdate,
342
- onProgressStep: onProgressStep,
343
- onDurationChanged: onDurationChanged,
344
- onVolumeChanged: onVolumeChanged
345
- }),
346
- ref = _useMediaApi.ref,
347
- api = _objectWithoutProperties(_useMediaApi, _excluded);
348
-
349
- if (apiRef !== null) {
350
- apiRef.current = api;
351
- apiRef.current.mediaRef = ref;
352
- }
353
-
354
- var currentTime = api.currentTime,
355
- duration = api.duration,
356
- playing = api.playing,
357
- seek = api.seek,
358
- audioReady = api.ready,
359
- play = api.play,
360
- pause = api.pause,
361
- muted = api.muted,
362
- unMute = api.unMute;
363
-
364
- var _useState = useState(null),
365
- _useState2 = _slicedToArray(_useState, 2),
366
- audioLevels = _useState2[0],
367
- setAudioLevels = _useState2[1];
368
-
369
- var _useState3 = useState(null),
370
- _useState4 = _slicedToArray(_useState3, 2),
371
- blobUrl = _useState4[0],
372
- setBlobUrl = _useState4[1];
362
+ if (element === null) {
363
+ return;
364
+ }
373
365
 
374
- useEffect(function () {
375
- var canceled = false;
376
- var AudioContext = typeof window !== 'undefined' ? window.AudioContext || window.webkitAudioContext : null;
377
-
378
- if (waveform !== null) {
379
- setAudioLevels(waveform.map(function (it) {
380
- return (it + 256 / 2) / 256;
381
- }));
382
- } else if (url !== null && waveFake) {
383
- var fakeLength = 1000;
384
- setAudioLevels(_toConsumableArray(new Array(fakeLength)).map(function () {
385
- return Math.random();
386
- }));
387
- } else if (url !== null && AudioContext !== null) {
388
- fetch(url, {
389
- mode: 'cors'
390
- }).then(function (response) {
391
- if (canceled) {
392
- throw new Error('Audio loading canceled');
393
- }
394
-
395
- return response.arrayBuffer();
396
- }).then(function (arrayBuffer) {
397
- if (canceled) {
398
- throw new Error('Audio loading canceled');
399
- }
400
-
401
- setBlobUrl(URL.createObjectURL(new Blob([arrayBuffer])));
402
- var audioCtx = new AudioContext();
403
- return audioCtx.decodeAudioData(arrayBuffer);
404
- }).then(function (buffer) {
405
- var channelsCount = buffer.numberOfChannels;
406
-
407
- if (channelsCount > 0) {
408
- var leftChannelData = buffer.getChannelData(0);
409
- setAudioLevels(leftChannelData.reduce(function (newArray, level, levelIndex) {
410
- // if (levelIndex % reduceBufferFactor === 0) {
411
- // console.log(level, (level + 1) / 2);
412
- newArray[newArray.length] = Math.abs(level); // }
413
-
414
- return newArray;
415
- }, []));
416
- }
417
- })["catch"](function (e) {
418
- throw e;
419
- });
366
+ if (customOnVolumeChange !== null) {
367
+ customOnVolumeChange(element.volume);
420
368
  }
369
+ }, [customOnVolumeChange]);
370
+ var onWavePlay = useCallback(function () {
371
+ var _ref$current2 = _ref4.current,
372
+ element = _ref$current2 === void 0 ? null : _ref$current2;
421
373
 
422
- return function () {
423
- if (url === null) {
424
- canceled = true;
425
- }
426
- };
427
- }, [url, waveform, setAudioLevels, setBlobUrl, reduceBufferFactor, waveFake]);
428
- var ready = waveFake || audioReady && blobUrl !== null;
374
+ if (element === null) {
375
+ return;
376
+ }
377
+
378
+ element.play();
379
+ }, []);
380
+ var onWaveSeek = useCallback(function (newTime) {
381
+ var _ref$current3 = _ref4.current,
382
+ element = _ref$current3 === void 0 ? null : _ref$current3;
383
+
384
+ if (element === null) {
385
+ return;
386
+ }
387
+
388
+ element.currentTime = newTime;
389
+ }, []);
429
390
  useEffect(function () {
430
- if (ready && onReady !== null) {
391
+ if (waveReady && onReady !== null) {
431
392
  onReady();
432
393
  }
433
- }, [ready, onReady]);
394
+ }, [waveReady, onReady]);
434
395
  useEffect(function () {
435
- if (autoPlay) {
436
- play();
396
+ var _ref$current4 = _ref4.current,
397
+ element = _ref$current4 === void 0 ? null : _ref$current4;
437
398
 
438
- if (initialMuted === 'auto' && muted && userInteracted) {
439
- unMute();
440
- }
441
- } else {
442
- pause();
399
+ if (element === null) {
400
+ return;
401
+ }
402
+
403
+ var isPaused = element.paused;
404
+
405
+ if (paused && !isPaused) {
406
+ element.pause();
407
+ } else if (!paused && isPaused) {
408
+ element.play();
443
409
  }
444
- }, [autoPlay]);
410
+ }, [paused, media]);
411
+ useProgressSteps({
412
+ currentTime: currentTime,
413
+ duration: duration,
414
+ disabled: paused,
415
+ onStep: onProgressStep
416
+ });
445
417
  return /*#__PURE__*/React.createElement("div", {
446
418
  className: classNames([styles.container, _defineProperty({}, className, className !== null)])
447
419
  }, /*#__PURE__*/React.createElement("audio", {
448
420
  key: url,
449
- ref: ref,
450
- src: waveFake ? url : blobUrl,
421
+ ref: function ref(newRef) {
422
+ _ref4.current = newRef;
423
+
424
+ if (mediaRef !== null && isFunction(mediaRef)) {
425
+ mediaRef(newRef);
426
+ } else if (mediaRef !== null) {
427
+ mediaRef.current = newRef;
428
+ }
429
+ },
430
+ src: url,
451
431
  autoPlay: autoPlay,
452
432
  muted: muted,
453
433
  loop: loop,
454
434
  crossOrigin: "anonymous",
455
- preload: "none"
456
- }), showWave ? /*#__PURE__*/React.createElement(AudioWave, Object.assign({
435
+ preload: preload,
436
+ onPlay: onPlay,
437
+ onPause: onPause,
438
+ onEnded: onEnded,
439
+ onSeeked: onSeeked,
440
+ onTimeUpdate: onTimeUpdate,
441
+ onVolumeChange: onVolumeChange
442
+ }), withWave ? /*#__PURE__*/React.createElement(AudioWave, Object.assign({
457
443
  className: styles.wave,
458
444
  media: media,
459
445
  currentTime: currentTime
460
446
  }, waveProps, {
461
447
  duration: duration,
462
- playing: playing,
463
- onSeek: seek,
464
- onResume: play,
448
+ playing: !paused,
449
+ onSeek: onWaveSeek,
450
+ onResume: onWavePlay,
465
451
  audioLevels: audioLevels
466
452
  })) : null);
467
453
  };
@@ -470,7 +456,7 @@ Audio.propTypes = propTypes;
470
456
  Audio.defaultProps = defaultProps;
471
457
  var Audio$1 = /*#__PURE__*/React.forwardRef(function (props, ref) {
472
458
  return /*#__PURE__*/React.createElement(Audio, Object.assign({
473
- apiRef: ref
459
+ mediaRef: ref
474
460
  }, props));
475
461
  });
476
462
 
package/lib/index.js CHANGED
@@ -3,15 +3,14 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
- var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
7
- var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
8
- var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
9
6
  var classNames = require('classnames');
7
+ var isFunction = require('lodash/isFunction');
10
8
  var PropTypes = require('prop-types');
11
9
  var React = require('react');
12
10
  var core = require('@micromag/core');
13
- var contexts = require('@micromag/core/contexts');
14
11
  var hooks = require('@micromag/core/hooks');
12
+ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
13
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
15
14
  var core$1 = require('@react-spring/core');
16
15
  var web = require('@react-spring/web');
17
16
  var react = require('@use-gesture/react');
@@ -21,12 +20,12 @@ var utils = require('@micromag/core/utils');
21
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
22
21
 
23
22
  var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
24
- var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
25
- var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
26
- var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
27
23
  var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
24
+ var isFunction__default = /*#__PURE__*/_interopDefaultLegacy(isFunction);
28
25
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
29
26
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
27
+ var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
28
+ var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
30
29
 
31
30
  var styles$1 = {"container":"micromag-element-audio-audio-wave-container","button":"micromag-element-audio-audio-wave-button","canvasBackground":"micromag-element-audio-audio-wave-canvasBackground","canvasProgress":"micromag-element-audio-audio-wave-canvasProgress"};
32
31
 
@@ -88,14 +87,11 @@ function AudioWave(_ref) {
88
87
  return utils.getContrastingColor(backgroundColor, progressColor);
89
88
  }, [progressColor, backgroundColor]);
90
89
 
91
- var _useResizeObserver = hooks.useResizeObserver(),
92
- elRef = _useResizeObserver.ref,
93
- elContentRect = _useResizeObserver.entry.contentRect;
94
-
95
- var _ref3 = elContentRect || {},
96
- _ref3$width = _ref3.width,
97
- elWidth = _ref3$width === void 0 ? null : _ref3$width,
98
- elHeight = _ref3.height; // Linear animation for progress bar
90
+ var _useDimensionObserver = hooks.useDimensionObserver(),
91
+ elRef = _useDimensionObserver.ref,
92
+ _useDimensionObserver2 = _useDimensionObserver.width,
93
+ elWidth = _useDimensionObserver2 === void 0 ? null : _useDimensionObserver2,
94
+ elHeight = _useDimensionObserver.height; // Linear animation for progress bar
99
95
 
100
96
 
101
97
  var _useSpring = core$1.useSpring(function () {
@@ -209,8 +205,11 @@ function AudioWave(_ref) {
209
205
  }, [audioLevels, sampleWidth, sampleMargin, minSampleHeight, elWidth, elHeight, mainColor, alternateColor, onReady]); // User events
210
206
 
211
207
  var seekFromX = React.useCallback(function (x) {
212
- var elX = elRef.current.getBoundingClientRect().left;
213
- var progress = Math.max(0, Math.min(1, (x - elX) / elWidth));
208
+ var _elRef$current$getBou = elRef.current.getBoundingClientRect(),
209
+ elX = _elRef$current$getBou.left,
210
+ width = _elRef$current$getBou.width;
211
+
212
+ var progress = Math.max(0, Math.min(1, (x - elX) / width));
214
213
 
215
214
  if (onSeek !== null && duration !== null) {
216
215
  onSeek(progress * duration);
@@ -221,11 +220,11 @@ function AudioWave(_ref) {
221
220
  }
222
221
  }, [duration, playing, onSeek, onResume]);
223
222
  var bind = react.useGesture({
224
- onDrag: function onDrag(_ref4) {
225
- var _ref4$xy = _slicedToArray__default["default"](_ref4.xy, 1),
226
- x = _ref4$xy[0],
227
- elapsedTime = _ref4.elapsedTime,
228
- active = _ref4.active;
223
+ onDrag: function onDrag(_ref3) {
224
+ var _ref3$xy = _slicedToArray__default["default"](_ref3.xy, 1),
225
+ x = _ref3$xy[0],
226
+ elapsedTime = _ref3.elapsedTime,
227
+ active = _ref3.active;
229
228
 
230
229
  if (!active && elapsedTime > 300) {
231
230
  return;
@@ -261,22 +260,24 @@ AudioWave.defaultProps = defaultProps$1;
261
260
 
262
261
  var styles = {"container":"micromag-element-audio-container","wave":"micromag-element-audio-wave"};
263
262
 
264
- var _excluded = ["ref"];
265
263
  var propTypes = {
266
264
  media: core.PropTypes.audioMedia,
267
- apiRef: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
265
+ mediaRef: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
268
266
  current: PropTypes__default["default"].any
269
267
  })]),
270
- initialMuted: PropTypes__default["default"].oneOf(['auto', true, false]),
268
+ muted: PropTypes__default["default"].bool,
271
269
  autoPlay: PropTypes__default["default"].bool,
270
+ paused: PropTypes__default["default"].bool,
272
271
  loop: PropTypes__default["default"].bool,
272
+ preload: PropTypes__default["default"].oneOf(['auto', 'none', 'metadata']),
273
+ shouldLoad: PropTypes__default["default"].bool,
273
274
  waveFake: PropTypes__default["default"].bool,
274
275
  waveProps: PropTypes__default["default"].shape({
275
276
  sampleWidth: PropTypes__default["default"].number,
276
277
  sampleMargin: PropTypes__default["default"].number,
277
278
  minSampleHeight: PropTypes__default["default"].number
278
279
  }),
279
- showWave: PropTypes__default["default"].bool,
280
+ withWave: PropTypes__default["default"].bool,
280
281
  reduceBufferFactor: PropTypes__default["default"].number,
281
282
  className: PropTypes__default["default"].string,
282
283
  onReady: PropTypes__default["default"].func,
@@ -286,18 +287,21 @@ var propTypes = {
286
287
  onSeeked: PropTypes__default["default"].func,
287
288
  onTimeUpdate: PropTypes__default["default"].func,
288
289
  onProgressStep: PropTypes__default["default"].func,
289
- onDurationChanged: PropTypes__default["default"].func,
290
- onVolumeChanged: PropTypes__default["default"].func
290
+ onDurationChange: PropTypes__default["default"].func,
291
+ onVolumeChange: PropTypes__default["default"].func
291
292
  };
292
293
  var defaultProps = {
293
294
  media: null,
294
- apiRef: null,
295
- initialMuted: 'auto',
295
+ mediaRef: null,
296
+ muted: false,
296
297
  autoPlay: false,
298
+ paused: false,
297
299
  loop: false,
300
+ preload: 'auto',
301
+ shouldLoad: true,
298
302
  waveFake: false,
299
303
  waveProps: null,
300
- showWave: false,
304
+ withWave: false,
301
305
  reduceBufferFactor: 100,
302
306
  className: null,
303
307
  onReady: null,
@@ -307,19 +311,22 @@ var defaultProps = {
307
311
  onSeeked: null,
308
312
  onTimeUpdate: null,
309
313
  onProgressStep: null,
310
- onDurationChanged: null,
311
- onVolumeChanged: null
314
+ onDurationChange: null,
315
+ onVolumeChange: null
312
316
  };
313
317
 
314
318
  var Audio = function Audio(_ref) {
315
319
  var media = _ref.media,
316
- apiRef = _ref.apiRef,
317
- initialMuted = _ref.initialMuted,
320
+ mediaRef = _ref.mediaRef,
321
+ muted = _ref.muted,
318
322
  autoPlay = _ref.autoPlay,
323
+ paused = _ref.paused,
319
324
  loop = _ref.loop,
325
+ preload = _ref.preload,
326
+ shouldLoad = _ref.shouldLoad,
320
327
  waveFake = _ref.waveFake,
321
328
  waveProps = _ref.waveProps,
322
- showWave = _ref.showWave,
329
+ withWave = _ref.withWave,
323
330
  reduceBufferFactor = _ref.reduceBufferFactor,
324
331
  className = _ref.className,
325
332
  onReady = _ref.onReady,
@@ -329,153 +336,132 @@ var Audio = function Audio(_ref) {
329
336
  onSeeked = _ref.onSeeked,
330
337
  onTimeUpdate = _ref.onTimeUpdate,
331
338
  onProgressStep = _ref.onProgressStep,
332
- onDurationChanged = _ref.onDurationChanged,
333
- onVolumeChanged = _ref.onVolumeChanged;
339
+ customOnDurationChange = _ref.onDurationChange,
340
+ customOnVolumeChange = _ref.onVolumeChange;
334
341
 
335
342
  var _ref2 = media || {},
336
343
  _ref2$url = _ref2.url,
337
- url = _ref2$url === void 0 ? null : _ref2$url,
338
- _ref2$metadata = _ref2.metadata,
339
- metadata = _ref2$metadata === void 0 ? null : _ref2$metadata;
344
+ url = _ref2$url === void 0 ? null : _ref2$url;
340
345
 
341
- var _ref3 = metadata || {},
342
- _ref3$waveform = _ref3.waveform,
343
- waveform = _ref3$waveform === void 0 ? null : _ref3$waveform;
346
+ var _ref4 = React.useRef(null);
344
347
 
345
- var userInteracted = contexts.useUserInteracted();
346
- var finalInitialMuted = initialMuted === true || initialMuted === 'auto' && autoPlay && !userInteracted;
348
+ var currentTime = hooks.useMediaCurrentTime(_ref4.current, {
349
+ id: url,
350
+ disabled: paused || !withWave && onProgressStep === null
351
+ });
352
+ var ready = hooks.useMediaReady(_ref4.current, {
353
+ id: url
354
+ });
355
+ var duration = hooks.useMediaDuration(_ref4.current, {
356
+ id: url
357
+ });
358
+ var audioLevels = hooks.useMediaWaveform(media, {
359
+ fake: waveFake,
360
+ reduceBufferFactor: reduceBufferFactor
361
+ });
362
+ hooks.useMediaLoad(_ref4.current, {
363
+ preload: preload,
364
+ shouldLoad: shouldLoad
365
+ });
366
+ var waveReady = waveFake || ready;
367
+ React.useEffect(function () {
368
+ if (duration > 0 && customOnDurationChange !== null) {
369
+ customOnDurationChange(duration);
370
+ }
371
+ }, [duration, customOnDurationChange]);
372
+ var onVolumeChange = React.useCallback(function () {
373
+ var _ref$current = _ref4.current,
374
+ element = _ref$current === void 0 ? null : _ref$current;
347
375
 
348
- var _useMediaApi = hooks.useMediaApi({
349
- url: url,
350
- initialMuted: finalInitialMuted,
351
- onPlay: onPlay,
352
- onPause: onPause,
353
- onEnded: onEnded,
354
- onSeeked: onSeeked,
355
- onTimeUpdate: onTimeUpdate,
356
- onProgressStep: onProgressStep,
357
- onDurationChanged: onDurationChanged,
358
- onVolumeChanged: onVolumeChanged
359
- }),
360
- ref = _useMediaApi.ref,
361
- api = _objectWithoutProperties__default["default"](_useMediaApi, _excluded);
362
-
363
- if (apiRef !== null) {
364
- apiRef.current = api;
365
- apiRef.current.mediaRef = ref;
366
- }
367
-
368
- var currentTime = api.currentTime,
369
- duration = api.duration,
370
- playing = api.playing,
371
- seek = api.seek,
372
- audioReady = api.ready,
373
- play = api.play,
374
- pause = api.pause,
375
- muted = api.muted,
376
- unMute = api.unMute;
377
-
378
- var _useState = React.useState(null),
379
- _useState2 = _slicedToArray__default["default"](_useState, 2),
380
- audioLevels = _useState2[0],
381
- setAudioLevels = _useState2[1];
382
-
383
- var _useState3 = React.useState(null),
384
- _useState4 = _slicedToArray__default["default"](_useState3, 2),
385
- blobUrl = _useState4[0],
386
- setBlobUrl = _useState4[1];
376
+ if (element === null) {
377
+ return;
378
+ }
387
379
 
388
- React.useEffect(function () {
389
- var canceled = false;
390
- var AudioContext = typeof window !== 'undefined' ? window.AudioContext || window.webkitAudioContext : null;
391
-
392
- if (waveform !== null) {
393
- setAudioLevels(waveform.map(function (it) {
394
- return (it + 256 / 2) / 256;
395
- }));
396
- } else if (url !== null && waveFake) {
397
- var fakeLength = 1000;
398
- setAudioLevels(_toConsumableArray__default["default"](new Array(fakeLength)).map(function () {
399
- return Math.random();
400
- }));
401
- } else if (url !== null && AudioContext !== null) {
402
- fetch(url, {
403
- mode: 'cors'
404
- }).then(function (response) {
405
- if (canceled) {
406
- throw new Error('Audio loading canceled');
407
- }
408
-
409
- return response.arrayBuffer();
410
- }).then(function (arrayBuffer) {
411
- if (canceled) {
412
- throw new Error('Audio loading canceled');
413
- }
414
-
415
- setBlobUrl(URL.createObjectURL(new Blob([arrayBuffer])));
416
- var audioCtx = new AudioContext();
417
- return audioCtx.decodeAudioData(arrayBuffer);
418
- }).then(function (buffer) {
419
- var channelsCount = buffer.numberOfChannels;
420
-
421
- if (channelsCount > 0) {
422
- var leftChannelData = buffer.getChannelData(0);
423
- setAudioLevels(leftChannelData.reduce(function (newArray, level, levelIndex) {
424
- // if (levelIndex % reduceBufferFactor === 0) {
425
- // console.log(level, (level + 1) / 2);
426
- newArray[newArray.length] = Math.abs(level); // }
427
-
428
- return newArray;
429
- }, []));
430
- }
431
- })["catch"](function (e) {
432
- throw e;
433
- });
380
+ if (customOnVolumeChange !== null) {
381
+ customOnVolumeChange(element.volume);
434
382
  }
383
+ }, [customOnVolumeChange]);
384
+ var onWavePlay = React.useCallback(function () {
385
+ var _ref$current2 = _ref4.current,
386
+ element = _ref$current2 === void 0 ? null : _ref$current2;
435
387
 
436
- return function () {
437
- if (url === null) {
438
- canceled = true;
439
- }
440
- };
441
- }, [url, waveform, setAudioLevels, setBlobUrl, reduceBufferFactor, waveFake]);
442
- var ready = waveFake || audioReady && blobUrl !== null;
388
+ if (element === null) {
389
+ return;
390
+ }
391
+
392
+ element.play();
393
+ }, []);
394
+ var onWaveSeek = React.useCallback(function (newTime) {
395
+ var _ref$current3 = _ref4.current,
396
+ element = _ref$current3 === void 0 ? null : _ref$current3;
397
+
398
+ if (element === null) {
399
+ return;
400
+ }
401
+
402
+ element.currentTime = newTime;
403
+ }, []);
443
404
  React.useEffect(function () {
444
- if (ready && onReady !== null) {
405
+ if (waveReady && onReady !== null) {
445
406
  onReady();
446
407
  }
447
- }, [ready, onReady]);
408
+ }, [waveReady, onReady]);
448
409
  React.useEffect(function () {
449
- if (autoPlay) {
450
- play();
410
+ var _ref$current4 = _ref4.current,
411
+ element = _ref$current4 === void 0 ? null : _ref$current4;
451
412
 
452
- if (initialMuted === 'auto' && muted && userInteracted) {
453
- unMute();
454
- }
455
- } else {
456
- pause();
413
+ if (element === null) {
414
+ return;
457
415
  }
458
- }, [autoPlay]);
416
+
417
+ var isPaused = element.paused;
418
+
419
+ if (paused && !isPaused) {
420
+ element.pause();
421
+ } else if (!paused && isPaused) {
422
+ element.play();
423
+ }
424
+ }, [paused, media]);
425
+ hooks.useProgressSteps({
426
+ currentTime: currentTime,
427
+ duration: duration,
428
+ disabled: paused,
429
+ onStep: onProgressStep
430
+ });
459
431
  return /*#__PURE__*/React__default["default"].createElement("div", {
460
432
  className: classNames__default["default"]([styles.container, _defineProperty__default["default"]({}, className, className !== null)])
461
433
  }, /*#__PURE__*/React__default["default"].createElement("audio", {
462
434
  key: url,
463
- ref: ref,
464
- src: waveFake ? url : blobUrl,
435
+ ref: function ref(newRef) {
436
+ _ref4.current = newRef;
437
+
438
+ if (mediaRef !== null && isFunction__default["default"](mediaRef)) {
439
+ mediaRef(newRef);
440
+ } else if (mediaRef !== null) {
441
+ mediaRef.current = newRef;
442
+ }
443
+ },
444
+ src: url,
465
445
  autoPlay: autoPlay,
466
446
  muted: muted,
467
447
  loop: loop,
468
448
  crossOrigin: "anonymous",
469
- preload: "none"
470
- }), showWave ? /*#__PURE__*/React__default["default"].createElement(AudioWave, Object.assign({
449
+ preload: preload,
450
+ onPlay: onPlay,
451
+ onPause: onPause,
452
+ onEnded: onEnded,
453
+ onSeeked: onSeeked,
454
+ onTimeUpdate: onTimeUpdate,
455
+ onVolumeChange: onVolumeChange
456
+ }), withWave ? /*#__PURE__*/React__default["default"].createElement(AudioWave, Object.assign({
471
457
  className: styles.wave,
472
458
  media: media,
473
459
  currentTime: currentTime
474
460
  }, waveProps, {
475
461
  duration: duration,
476
- playing: playing,
477
- onSeek: seek,
478
- onResume: play,
462
+ playing: !paused,
463
+ onSeek: onWaveSeek,
464
+ onResume: onWavePlay,
479
465
  audioLevels: audioLevels
480
466
  })) : null);
481
467
  };
@@ -484,7 +470,7 @@ Audio.propTypes = propTypes;
484
470
  Audio.defaultProps = defaultProps;
485
471
  var Audio$1 = /*#__PURE__*/React__default["default"].forwardRef(function (props, ref) {
486
472
  return /*#__PURE__*/React__default["default"].createElement(Audio, Object.assign({
487
- apiRef: ref
473
+ mediaRef: ref
488
474
  }, props));
489
475
  });
490
476
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micromag/element-audio",
3
- "version": "0.3.147",
3
+ "version": "0.3.152",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "javascript"
@@ -52,13 +52,14 @@
52
52
  "@fortawesome/fontawesome-svg-core": "^1.2.32",
53
53
  "@fortawesome/free-solid-svg-icons": "^5.15.1",
54
54
  "@fortawesome/react-fontawesome": "^0.1.13",
55
- "@micromag/core": "^0.3.147",
56
- "@micromag/element-closed-captions": "^0.3.147",
57
- "@micromag/element-media-controls": "^0.3.147",
55
+ "@micromag/core": "^0.3.152",
56
+ "@micromag/element-closed-captions": "^0.3.152",
57
+ "@micromag/element-media-controls": "^0.3.152",
58
58
  "@react-spring/core": "^9.1.1",
59
59
  "@react-spring/web": "^9.1.1",
60
60
  "@use-gesture/react": "^10.2.4",
61
61
  "classnames": "^2.2.6",
62
+ "lodash": "^4.17.21",
62
63
  "prop-types": "^15.7.2",
63
64
  "react-intl": "^5.12.1",
64
65
  "uuid": "^8.3.2",
@@ -67,5 +68,5 @@
67
68
  "publishConfig": {
68
69
  "access": "public"
69
70
  },
70
- "gitHead": "695a66acc54f4863dc44a98f0471e8233ca10aee"
71
+ "gitHead": "23db6c104c10cc70a73366c8b04576a312a36206"
71
72
  }