apm-react-audio-player 1.2.0 → 2.0.1
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/index.js +206 -49
- package/dist/index.modern.js +206 -49
- package/package.json +10 -6
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
+
var Hls = require('hls.js');
|
|
4
5
|
|
|
5
6
|
function _arrayLikeToArray(r, a) {
|
|
6
7
|
(null == a || a > r.length) && (a = r.length);
|
|
@@ -10,6 +11,14 @@ function _arrayLikeToArray(r, a) {
|
|
|
10
11
|
function _arrayWithHoles(r) {
|
|
11
12
|
if (Array.isArray(r)) return r;
|
|
12
13
|
}
|
|
14
|
+
function _defineProperty(e, r, t) {
|
|
15
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
16
|
+
value: t,
|
|
17
|
+
enumerable: !0,
|
|
18
|
+
configurable: !0,
|
|
19
|
+
writable: !0
|
|
20
|
+
}) : e[r] = t, e;
|
|
21
|
+
}
|
|
13
22
|
function _extends() {
|
|
14
23
|
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
15
24
|
for (var e = 1; e < arguments.length; e++) {
|
|
@@ -27,15 +36,15 @@ function _iterableToArrayLimit(r, l) {
|
|
|
27
36
|
i,
|
|
28
37
|
u,
|
|
29
38
|
a = [],
|
|
30
|
-
f =
|
|
31
|
-
o =
|
|
39
|
+
f = !0,
|
|
40
|
+
o = !1;
|
|
32
41
|
try {
|
|
33
42
|
if (i = (t = t.call(r)).next, 0 === l) {
|
|
34
43
|
if (Object(t) !== t) return;
|
|
35
44
|
f = !1;
|
|
36
45
|
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
37
46
|
} catch (r) {
|
|
38
|
-
o =
|
|
47
|
+
o = !0, n = r;
|
|
39
48
|
} finally {
|
|
40
49
|
try {
|
|
41
50
|
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
@@ -49,9 +58,44 @@ function _iterableToArrayLimit(r, l) {
|
|
|
49
58
|
function _nonIterableRest() {
|
|
50
59
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
51
60
|
}
|
|
61
|
+
function ownKeys(e, r) {
|
|
62
|
+
var t = Object.keys(e);
|
|
63
|
+
if (Object.getOwnPropertySymbols) {
|
|
64
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
65
|
+
r && (o = o.filter(function (r) {
|
|
66
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
67
|
+
})), t.push.apply(t, o);
|
|
68
|
+
}
|
|
69
|
+
return t;
|
|
70
|
+
}
|
|
71
|
+
function _objectSpread2(e) {
|
|
72
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
73
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
74
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
75
|
+
_defineProperty(e, r, t[r]);
|
|
76
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
77
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return e;
|
|
81
|
+
}
|
|
52
82
|
function _slicedToArray(r, e) {
|
|
53
83
|
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
54
84
|
}
|
|
85
|
+
function _toPrimitive(t, r) {
|
|
86
|
+
if ("object" != typeof t || !t) return t;
|
|
87
|
+
var e = t[Symbol.toPrimitive];
|
|
88
|
+
if (void 0 !== e) {
|
|
89
|
+
var i = e.call(t, r || "default");
|
|
90
|
+
if ("object" != typeof i) return i;
|
|
91
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
92
|
+
}
|
|
93
|
+
return ("string" === r ? String : Number)(t);
|
|
94
|
+
}
|
|
95
|
+
function _toPropertyKey(t) {
|
|
96
|
+
var i = _toPrimitive(t, "string");
|
|
97
|
+
return "symbol" == typeof i ? i : i + "";
|
|
98
|
+
}
|
|
55
99
|
function _unsupportedIterableToArray(r, a) {
|
|
56
100
|
if (r) {
|
|
57
101
|
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
@@ -60,8 +104,11 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
60
104
|
}
|
|
61
105
|
}
|
|
62
106
|
|
|
63
|
-
var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef
|
|
64
|
-
var
|
|
107
|
+
var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef) {
|
|
108
|
+
var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
|
|
109
|
+
volumeCtrl = _ref.volumeCtrl,
|
|
110
|
+
initialDuration = _ref.initialDuration,
|
|
111
|
+
hlsRef = _ref.hlsRef;
|
|
65
112
|
var _useState = React.useState(false),
|
|
66
113
|
_useState2 = _slicedToArray(_useState, 2),
|
|
67
114
|
isPlaying = _useState2[0],
|
|
@@ -78,11 +125,12 @@ var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef, volumeCtr
|
|
|
78
125
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
79
126
|
isFinishedPlaying = _useState8[0],
|
|
80
127
|
setIsFinishedPlaying = _useState8[1];
|
|
81
|
-
var animationRef = React.useRef();
|
|
128
|
+
var animationRef = React.useRef();
|
|
129
|
+
var pendingPlayAbortRef = React.useRef(null);
|
|
82
130
|
var _useState9 = React.useState(false),
|
|
83
|
-
|
|
84
|
-
isMuted =
|
|
85
|
-
setIsMuted =
|
|
131
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
132
|
+
isMuted = _useState0[0],
|
|
133
|
+
setIsMuted = _useState0[1];
|
|
86
134
|
var isStream = audioRef.current && audioRef.current.duration === Infinity;
|
|
87
135
|
React.useEffect(function () {
|
|
88
136
|
if (currentTime === Number(duration)) {
|
|
@@ -141,6 +189,10 @@ var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef, volumeCtr
|
|
|
141
189
|
animationRef.current = window.requestAnimationFrame(_whilePlaying);
|
|
142
190
|
};
|
|
143
191
|
var pause = function pause() {
|
|
192
|
+
if (pendingPlayAbortRef.current) {
|
|
193
|
+
pendingPlayAbortRef.current();
|
|
194
|
+
pendingPlayAbortRef.current = null;
|
|
195
|
+
}
|
|
144
196
|
setIsPlaying(false);
|
|
145
197
|
audioRef.current.pause();
|
|
146
198
|
window.cancelAnimationFrame(animationRef.current);
|
|
@@ -152,26 +204,80 @@ var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef, volumeCtr
|
|
|
152
204
|
// pause()
|
|
153
205
|
// }
|
|
154
206
|
|
|
207
|
+
var _safePlay = function safePlay(audio) {
|
|
208
|
+
var promise = audio.play();
|
|
209
|
+
if (promise !== undefined) {
|
|
210
|
+
promise["catch"](function (err) {
|
|
211
|
+
if (err.name === 'NotAllowedError') {
|
|
212
|
+
setIsPlaying(false);
|
|
213
|
+
} else if (err.name === 'AbortError') {
|
|
214
|
+
// play() was interrupted by a concurrent load() (e.g. ReactAudioPlayerInner
|
|
215
|
+
// calling load() after a source change) — retry once canplay fires.
|
|
216
|
+
// If the audio element was already unlocked by a prior play() call within
|
|
217
|
+
// a user gesture (e.g. the Safari fix in AudioContext), this retry succeeds.
|
|
218
|
+
audio.addEventListener('canplay', function () {
|
|
219
|
+
return _safePlay(audio);
|
|
220
|
+
}, {
|
|
221
|
+
once: true
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
};
|
|
155
227
|
var play = function play() {
|
|
156
228
|
setIsPlaying(true);
|
|
157
229
|
setIsFinishedPlaying(false);
|
|
230
|
+
var elDuration = audioRef.current.duration;
|
|
231
|
+
var isLiveOrUnloaded = elDuration === Infinity || isNaN(elDuration);
|
|
232
|
+
if (isLiveOrUnloaded) {
|
|
233
|
+
var _audioRef$current$cur;
|
|
234
|
+
if (hlsRef !== null && hlsRef !== void 0 && hlsRef.current) {
|
|
235
|
+
var audio = audioRef.current;
|
|
236
|
+
var hls = hlsRef.current;
|
|
237
|
+
// If data is already buffered (e.g. resuming after pause), play immediately.
|
|
238
|
+
// Otherwise wait for the first fragment so Safari's audio decoder is warm
|
|
239
|
+
// before output starts, preventing the first syllable from being cut.
|
|
240
|
+
if (audio.buffered.length > 0) {
|
|
241
|
+
_safePlay(audio);
|
|
242
|
+
} else {
|
|
243
|
+
var _onFragBuffered = function onFragBuffered() {
|
|
244
|
+
pendingPlayAbortRef.current = null;
|
|
245
|
+
hls.off('hlsFragBuffered', _onFragBuffered);
|
|
246
|
+
_safePlay(audio);
|
|
247
|
+
};
|
|
248
|
+
pendingPlayAbortRef.current = function () {
|
|
249
|
+
return hls.off('hlsFragBuffered', _onFragBuffered);
|
|
250
|
+
};
|
|
251
|
+
hls.on('hlsFragBuffered', _onFragBuffered);
|
|
252
|
+
}
|
|
253
|
+
} else if (elDuration === Infinity && (_audioRef$current$cur = audioRef.current.currentSrc) !== null && _audioRef$current$cur !== void 0 && _audioRef$current$cur.split('?')[0].endsWith('.m3u8')) {
|
|
254
|
+
// Native live stream (no hls.js, e.g. iOS Safari): force a fresh manifest
|
|
255
|
+
// fetch so we don't play from a stale buffer position across a discontinuity.
|
|
256
|
+
var onCanPlay = function onCanPlay() {
|
|
257
|
+
pendingPlayAbortRef.current = null;
|
|
258
|
+
if (audioRef.current) _safePlay(audioRef.current);
|
|
259
|
+
};
|
|
260
|
+
pendingPlayAbortRef.current = function () {
|
|
261
|
+
var _audioRef$current;
|
|
262
|
+
return (_audioRef$current = audioRef.current) === null || _audioRef$current === void 0 ? void 0 : _audioRef$current.removeEventListener('canplay', onCanPlay);
|
|
263
|
+
};
|
|
264
|
+
audioRef.current.addEventListener('canplay', onCanPlay, {
|
|
265
|
+
once: true
|
|
266
|
+
});
|
|
267
|
+
audioRef.current.load();
|
|
268
|
+
} else {
|
|
269
|
+
// Finite audio not yet loaded (duration is NaN): call play() directly so
|
|
270
|
+
// Safari's user-gesture scope isn't lost waiting for an async canplay event.
|
|
271
|
+
_safePlay(audioRef.current);
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
_safePlay(audioRef.current);
|
|
158
275
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// position (e.g. 20s in), causing ads to start mid-stream. Calling load()
|
|
165
|
-
// here reconnects to the current live edge and gets a fresh manifest.
|
|
166
|
-
if (duration === Infinity) {
|
|
167
|
-
audioRef.current.load();
|
|
168
|
-
}
|
|
169
|
-
audioRef.current.play();
|
|
170
|
-
|
|
171
|
-
// Only start RAF loop for non-live streams with valid duration
|
|
172
|
-
var dur = audioRef.current.duration;
|
|
173
|
-
if (dur !== Infinity && !isNaN(dur) && isFinite(dur)) {
|
|
174
|
-
animationRef.current = window.requestAnimationFrame(_whilePlaying);
|
|
276
|
+
// Only start RAF loop for non-live streams with valid duration
|
|
277
|
+
var dur = audioRef.current.duration;
|
|
278
|
+
if (dur !== Infinity && !isNaN(dur) && isFinite(dur)) {
|
|
279
|
+
animationRef.current = window.requestAnimationFrame(_whilePlaying);
|
|
280
|
+
}
|
|
175
281
|
}
|
|
176
282
|
};
|
|
177
283
|
var toggleMute = function toggleMute() {
|
|
@@ -300,6 +406,13 @@ var Pause = function Pause() {
|
|
|
300
406
|
}));
|
|
301
407
|
};
|
|
302
408
|
|
|
409
|
+
var getHlsSrc = function getHlsSrc(audioSrc) {
|
|
410
|
+
var _urls$find;
|
|
411
|
+
var urls = Array.isArray(audioSrc) ? audioSrc : [audioSrc];
|
|
412
|
+
return (_urls$find = urls.find(function (url) {
|
|
413
|
+
return url && url.split('?')[0].endsWith('.m3u8');
|
|
414
|
+
})) !== null && _urls$find !== void 0 ? _urls$find : null;
|
|
415
|
+
};
|
|
303
416
|
var getTypeFromExtension = function getTypeFromExtension(url) {
|
|
304
417
|
var extension = url.split('.').pop().split('?')[0];
|
|
305
418
|
switch (extension) {
|
|
@@ -319,11 +432,15 @@ var getTypeFromExtension = function getTypeFromExtension(url) {
|
|
|
319
432
|
}
|
|
320
433
|
};
|
|
321
434
|
var ReactAudioPlayerInner = function ReactAudioPlayerInner(props) {
|
|
322
|
-
var _props$audioPlayerRef, _props$progressBarRef;
|
|
323
|
-
//
|
|
324
|
-
var
|
|
325
|
-
var
|
|
435
|
+
var _props$audioPlayerRef, _props$progressBarRef, _props$hlsRef;
|
|
436
|
+
// Always call hooks unconditionally — use internal refs when props don't provide them
|
|
437
|
+
var internalAudioRef = React.useRef();
|
|
438
|
+
var internalProgressBarRef = React.useRef();
|
|
439
|
+
var internalHlsRef = React.useRef(null);
|
|
326
440
|
var hasInitializedRef = React.useRef(false);
|
|
441
|
+
// Track isPlaying via a ref so the source-change useEffect can read the
|
|
442
|
+
// current value without adding isPlaying to its dependency array.
|
|
443
|
+
var isPlayingRef = React.useRef(false);
|
|
327
444
|
var customStyles = props ? props.style : '';
|
|
328
445
|
var title = props.title,
|
|
329
446
|
audioSrc = props.audioSrc,
|
|
@@ -346,27 +463,67 @@ var ReactAudioPlayerInner = function ReactAudioPlayerInner(props) {
|
|
|
346
463
|
forwardControl = props.forwardControl,
|
|
347
464
|
subtitle = props.subtitle,
|
|
348
465
|
prefix = props.prefix;
|
|
466
|
+
var audioPlayerRef = (_props$audioPlayerRef = props.audioPlayerRef) !== null && _props$audioPlayerRef !== void 0 ? _props$audioPlayerRef : internalAudioRef;
|
|
467
|
+
var progressBarRef = (_props$progressBarRef = props.progressBarRef) !== null && _props$progressBarRef !== void 0 ? _props$progressBarRef : internalProgressBarRef;
|
|
468
|
+
var hlsRef = (_props$hlsRef = props.hlsRef) !== null && _props$hlsRef !== void 0 ? _props$hlsRef : internalHlsRef;
|
|
469
|
+
var hlsSrcForRender = getHlsSrc(audioSrc);
|
|
470
|
+
var isHlsManaged = !!(hlsSrcForRender && Hls.isSupported());
|
|
471
|
+
|
|
472
|
+
// Keep isPlayingRef in sync on every render (runs before effects).
|
|
473
|
+
isPlayingRef.current = isPlaying;
|
|
349
474
|
var audioDuration = duration && !isNaN(duration) && calculateTime(duration);
|
|
350
475
|
var formatDuration = duration && !isNaN(duration) && audioDuration && formatCalculateTime(audioDuration);
|
|
351
476
|
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
//
|
|
355
|
-
// segments are stale. On first play the browser fetches the live edge
|
|
356
|
-
// naturally. On subsequent src changes we do call load() to reset the element.
|
|
357
|
-
// Use JSON.stringify to handle array comparisons by value instead of reference.
|
|
477
|
+
// Manage audio source changes. For HLS sources hls.js owns the loading cycle;
|
|
478
|
+
// for everything else we fall back to the native load() path.
|
|
479
|
+
// JSON.stringify handles array-valued audioSrc comparisons by value.
|
|
358
480
|
React.useEffect(function () {
|
|
359
|
-
if (audioPlayerRef.current
|
|
360
|
-
|
|
361
|
-
|
|
481
|
+
if (!audioPlayerRef.current || !audioSrc) return;
|
|
482
|
+
if (hasInitializedRef.current) {
|
|
483
|
+
resetDuration === null || resetDuration === void 0 ? void 0 : resetDuration();
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Tear down any existing hls.js instance before re-evaluating the source.
|
|
487
|
+
if (hlsRef.current) {
|
|
488
|
+
hlsRef.current.destroy();
|
|
489
|
+
hlsRef.current = null;
|
|
490
|
+
}
|
|
491
|
+
var hlsSrc = getHlsSrc(audioSrc);
|
|
492
|
+
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
493
|
+
if (hlsSrc && Hls.isSupported()) {
|
|
494
|
+
var hls = new Hls(_objectSpread2({
|
|
495
|
+
autoStartLoad: false,
|
|
496
|
+
liveSyncDurationCount: 3,
|
|
497
|
+
liveMaxLatencyDurationCount: 5,
|
|
498
|
+
enableWorker: !isSafari
|
|
499
|
+
}, isSafari && {
|
|
500
|
+
maxBufferHole: 2,
|
|
501
|
+
maxSeekHole: 2
|
|
502
|
+
}));
|
|
503
|
+
hls.loadSource(hlsSrc);
|
|
504
|
+
hls.attachMedia(audioPlayerRef.current);
|
|
505
|
+
hlsRef.current = hls;
|
|
506
|
+
} else {
|
|
507
|
+
// Non-HLS: call load() to prime the new source.
|
|
508
|
+
// Safari: skip load() when playing — the synchronous play() called in the
|
|
509
|
+
// gesture handler would be aborted (AbortError), losing the user activation token.
|
|
510
|
+
// Chrome/Firefox: always call load(); AudioContext defers play() via pendingPlayRef
|
|
511
|
+
// until after this effect, so load() and play() are sequenced with no concurrent abort.
|
|
512
|
+
if (hasInitializedRef.current && (!isSafari || !isPlayingRef.current)) {
|
|
362
513
|
try {
|
|
363
514
|
audioPlayerRef.current.load();
|
|
364
515
|
} catch (err) {
|
|
365
516
|
console.warn('Failed to reload audio source:', err);
|
|
366
517
|
}
|
|
367
518
|
}
|
|
368
|
-
hasInitializedRef.current = true;
|
|
369
519
|
}
|
|
520
|
+
hasInitializedRef.current = true;
|
|
521
|
+
return function () {
|
|
522
|
+
if (hlsRef.current) {
|
|
523
|
+
hlsRef.current.destroy();
|
|
524
|
+
hlsRef.current = null;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
370
527
|
}, [JSON.stringify(audioSrc)]);
|
|
371
528
|
|
|
372
529
|
// Set initial volume to 100%
|
|
@@ -386,16 +543,13 @@ var ReactAudioPlayerInner = function ReactAudioPlayerInner(props) {
|
|
|
386
543
|
preload: "none",
|
|
387
544
|
onLoadedMetadata: onLoadedMetadata,
|
|
388
545
|
muted: isMuted
|
|
389
|
-
}, Array.isArray(audioSrc) ? audioSrc.map(function (
|
|
546
|
+
}, !isHlsManaged && (Array.isArray(audioSrc) ? audioSrc : [audioSrc]).map(function (url, i) {
|
|
390
547
|
return /*#__PURE__*/React.createElement("source", {
|
|
391
|
-
key:
|
|
392
|
-
src:
|
|
393
|
-
type: getTypeFromExtension(
|
|
548
|
+
key: i,
|
|
549
|
+
src: url,
|
|
550
|
+
type: getTypeFromExtension(url)
|
|
394
551
|
});
|
|
395
|
-
})
|
|
396
|
-
src: audioSrc,
|
|
397
|
-
type: getTypeFromExtension(audioSrc)
|
|
398
|
-
}) : null, "Your browser does not support the audio element."), /*#__PURE__*/React.createElement("div", {
|
|
552
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
399
553
|
className: "player-layout"
|
|
400
554
|
}, volumeCtrl && /*#__PURE__*/React.createElement("div", {
|
|
401
555
|
className: "player-controls-secondary-outer"
|
|
@@ -492,11 +646,13 @@ var ReactAudioPlayer = function ReactAudioPlayer(props) {
|
|
|
492
646
|
// references
|
|
493
647
|
var audioPlayerRef = (_props$audioPlayerRef = props.audioPlayerRef) !== null && _props$audioPlayerRef !== void 0 ? _props$audioPlayerRef : React.useRef(); // reference our audio component
|
|
494
648
|
var progressBarRef = (_props$progressBarRef = props.progressBarRef) !== null && _props$progressBarRef !== void 0 ? _props$progressBarRef : React.useRef(); // reference our progress bar
|
|
495
|
-
|
|
649
|
+
var hlsRef = React.useRef(null);
|
|
496
650
|
var customStyles = props ? props.style : '';
|
|
497
651
|
|
|
498
652
|
// hooks
|
|
499
|
-
var _useAudioPlayer = useAudioPlayer(audioPlayerRef, progressBarRef
|
|
653
|
+
var _useAudioPlayer = useAudioPlayer(audioPlayerRef, progressBarRef, {
|
|
654
|
+
hlsRef: hlsRef
|
|
655
|
+
}),
|
|
500
656
|
isPlaying = _useAudioPlayer.isPlaying,
|
|
501
657
|
currentTime = _useAudioPlayer.currentTime,
|
|
502
658
|
duration = _useAudioPlayer.duration,
|
|
@@ -513,6 +669,7 @@ var ReactAudioPlayer = function ReactAudioPlayer(props) {
|
|
|
513
669
|
return /*#__PURE__*/React.createElement(ReactAudioPlayerInner, _extends({}, props, {
|
|
514
670
|
audioPlayerRef: audioPlayerRef,
|
|
515
671
|
progressBarRef: progressBarRef,
|
|
672
|
+
hlsRef: hlsRef,
|
|
516
673
|
isPlaying: isPlaying,
|
|
517
674
|
isMuted: isMuted,
|
|
518
675
|
currentTime: currentTime,
|
package/dist/index.modern.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import Hls from 'hls.js';
|
|
2
3
|
|
|
3
4
|
function _arrayLikeToArray(r, a) {
|
|
4
5
|
(null == a || a > r.length) && (a = r.length);
|
|
@@ -8,6 +9,14 @@ function _arrayLikeToArray(r, a) {
|
|
|
8
9
|
function _arrayWithHoles(r) {
|
|
9
10
|
if (Array.isArray(r)) return r;
|
|
10
11
|
}
|
|
12
|
+
function _defineProperty(e, r, t) {
|
|
13
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
14
|
+
value: t,
|
|
15
|
+
enumerable: !0,
|
|
16
|
+
configurable: !0,
|
|
17
|
+
writable: !0
|
|
18
|
+
}) : e[r] = t, e;
|
|
19
|
+
}
|
|
11
20
|
function _extends() {
|
|
12
21
|
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
13
22
|
for (var e = 1; e < arguments.length; e++) {
|
|
@@ -25,15 +34,15 @@ function _iterableToArrayLimit(r, l) {
|
|
|
25
34
|
i,
|
|
26
35
|
u,
|
|
27
36
|
a = [],
|
|
28
|
-
f =
|
|
29
|
-
o =
|
|
37
|
+
f = !0,
|
|
38
|
+
o = !1;
|
|
30
39
|
try {
|
|
31
40
|
if (i = (t = t.call(r)).next, 0 === l) {
|
|
32
41
|
if (Object(t) !== t) return;
|
|
33
42
|
f = !1;
|
|
34
43
|
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
35
44
|
} catch (r) {
|
|
36
|
-
o =
|
|
45
|
+
o = !0, n = r;
|
|
37
46
|
} finally {
|
|
38
47
|
try {
|
|
39
48
|
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
@@ -47,9 +56,44 @@ function _iterableToArrayLimit(r, l) {
|
|
|
47
56
|
function _nonIterableRest() {
|
|
48
57
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
49
58
|
}
|
|
59
|
+
function ownKeys(e, r) {
|
|
60
|
+
var t = Object.keys(e);
|
|
61
|
+
if (Object.getOwnPropertySymbols) {
|
|
62
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
63
|
+
r && (o = o.filter(function (r) {
|
|
64
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
65
|
+
})), t.push.apply(t, o);
|
|
66
|
+
}
|
|
67
|
+
return t;
|
|
68
|
+
}
|
|
69
|
+
function _objectSpread2(e) {
|
|
70
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
71
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
72
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
73
|
+
_defineProperty(e, r, t[r]);
|
|
74
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
75
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return e;
|
|
79
|
+
}
|
|
50
80
|
function _slicedToArray(r, e) {
|
|
51
81
|
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
52
82
|
}
|
|
83
|
+
function _toPrimitive(t, r) {
|
|
84
|
+
if ("object" != typeof t || !t) return t;
|
|
85
|
+
var e = t[Symbol.toPrimitive];
|
|
86
|
+
if (void 0 !== e) {
|
|
87
|
+
var i = e.call(t, r || "default");
|
|
88
|
+
if ("object" != typeof i) return i;
|
|
89
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
90
|
+
}
|
|
91
|
+
return ("string" === r ? String : Number)(t);
|
|
92
|
+
}
|
|
93
|
+
function _toPropertyKey(t) {
|
|
94
|
+
var i = _toPrimitive(t, "string");
|
|
95
|
+
return "symbol" == typeof i ? i : i + "";
|
|
96
|
+
}
|
|
53
97
|
function _unsupportedIterableToArray(r, a) {
|
|
54
98
|
if (r) {
|
|
55
99
|
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
@@ -58,8 +102,11 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
58
102
|
}
|
|
59
103
|
}
|
|
60
104
|
|
|
61
|
-
var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef
|
|
62
|
-
var
|
|
105
|
+
var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef) {
|
|
106
|
+
var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
|
|
107
|
+
volumeCtrl = _ref.volumeCtrl,
|
|
108
|
+
initialDuration = _ref.initialDuration,
|
|
109
|
+
hlsRef = _ref.hlsRef;
|
|
63
110
|
var _useState = useState(false),
|
|
64
111
|
_useState2 = _slicedToArray(_useState, 2),
|
|
65
112
|
isPlaying = _useState2[0],
|
|
@@ -76,11 +123,12 @@ var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef, volumeCtr
|
|
|
76
123
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
77
124
|
isFinishedPlaying = _useState8[0],
|
|
78
125
|
setIsFinishedPlaying = _useState8[1];
|
|
79
|
-
var animationRef = useRef();
|
|
126
|
+
var animationRef = useRef();
|
|
127
|
+
var pendingPlayAbortRef = useRef(null);
|
|
80
128
|
var _useState9 = useState(false),
|
|
81
|
-
|
|
82
|
-
isMuted =
|
|
83
|
-
setIsMuted =
|
|
129
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
130
|
+
isMuted = _useState0[0],
|
|
131
|
+
setIsMuted = _useState0[1];
|
|
84
132
|
var isStream = audioRef.current && audioRef.current.duration === Infinity;
|
|
85
133
|
useEffect(function () {
|
|
86
134
|
if (currentTime === Number(duration)) {
|
|
@@ -139,6 +187,10 @@ var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef, volumeCtr
|
|
|
139
187
|
animationRef.current = window.requestAnimationFrame(_whilePlaying);
|
|
140
188
|
};
|
|
141
189
|
var pause = function pause() {
|
|
190
|
+
if (pendingPlayAbortRef.current) {
|
|
191
|
+
pendingPlayAbortRef.current();
|
|
192
|
+
pendingPlayAbortRef.current = null;
|
|
193
|
+
}
|
|
142
194
|
setIsPlaying(false);
|
|
143
195
|
audioRef.current.pause();
|
|
144
196
|
window.cancelAnimationFrame(animationRef.current);
|
|
@@ -150,26 +202,80 @@ var useAudioPlayer = function useAudioPlayer(audioRef, progressBarRef, volumeCtr
|
|
|
150
202
|
// pause()
|
|
151
203
|
// }
|
|
152
204
|
|
|
205
|
+
var _safePlay = function safePlay(audio) {
|
|
206
|
+
var promise = audio.play();
|
|
207
|
+
if (promise !== undefined) {
|
|
208
|
+
promise["catch"](function (err) {
|
|
209
|
+
if (err.name === 'NotAllowedError') {
|
|
210
|
+
setIsPlaying(false);
|
|
211
|
+
} else if (err.name === 'AbortError') {
|
|
212
|
+
// play() was interrupted by a concurrent load() (e.g. ReactAudioPlayerInner
|
|
213
|
+
// calling load() after a source change) — retry once canplay fires.
|
|
214
|
+
// If the audio element was already unlocked by a prior play() call within
|
|
215
|
+
// a user gesture (e.g. the Safari fix in AudioContext), this retry succeeds.
|
|
216
|
+
audio.addEventListener('canplay', function () {
|
|
217
|
+
return _safePlay(audio);
|
|
218
|
+
}, {
|
|
219
|
+
once: true
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
};
|
|
153
225
|
var play = function play() {
|
|
154
226
|
setIsPlaying(true);
|
|
155
227
|
setIsFinishedPlaying(false);
|
|
228
|
+
var elDuration = audioRef.current.duration;
|
|
229
|
+
var isLiveOrUnloaded = elDuration === Infinity || isNaN(elDuration);
|
|
230
|
+
if (isLiveOrUnloaded) {
|
|
231
|
+
var _audioRef$current$cur;
|
|
232
|
+
if (hlsRef !== null && hlsRef !== void 0 && hlsRef.current) {
|
|
233
|
+
var audio = audioRef.current;
|
|
234
|
+
var hls = hlsRef.current;
|
|
235
|
+
// If data is already buffered (e.g. resuming after pause), play immediately.
|
|
236
|
+
// Otherwise wait for the first fragment so Safari's audio decoder is warm
|
|
237
|
+
// before output starts, preventing the first syllable from being cut.
|
|
238
|
+
if (audio.buffered.length > 0) {
|
|
239
|
+
_safePlay(audio);
|
|
240
|
+
} else {
|
|
241
|
+
var _onFragBuffered = function onFragBuffered() {
|
|
242
|
+
pendingPlayAbortRef.current = null;
|
|
243
|
+
hls.off('hlsFragBuffered', _onFragBuffered);
|
|
244
|
+
_safePlay(audio);
|
|
245
|
+
};
|
|
246
|
+
pendingPlayAbortRef.current = function () {
|
|
247
|
+
return hls.off('hlsFragBuffered', _onFragBuffered);
|
|
248
|
+
};
|
|
249
|
+
hls.on('hlsFragBuffered', _onFragBuffered);
|
|
250
|
+
}
|
|
251
|
+
} else if (elDuration === Infinity && (_audioRef$current$cur = audioRef.current.currentSrc) !== null && _audioRef$current$cur !== void 0 && _audioRef$current$cur.split('?')[0].endsWith('.m3u8')) {
|
|
252
|
+
// Native live stream (no hls.js, e.g. iOS Safari): force a fresh manifest
|
|
253
|
+
// fetch so we don't play from a stale buffer position across a discontinuity.
|
|
254
|
+
var onCanPlay = function onCanPlay() {
|
|
255
|
+
pendingPlayAbortRef.current = null;
|
|
256
|
+
if (audioRef.current) _safePlay(audioRef.current);
|
|
257
|
+
};
|
|
258
|
+
pendingPlayAbortRef.current = function () {
|
|
259
|
+
var _audioRef$current;
|
|
260
|
+
return (_audioRef$current = audioRef.current) === null || _audioRef$current === void 0 ? void 0 : _audioRef$current.removeEventListener('canplay', onCanPlay);
|
|
261
|
+
};
|
|
262
|
+
audioRef.current.addEventListener('canplay', onCanPlay, {
|
|
263
|
+
once: true
|
|
264
|
+
});
|
|
265
|
+
audioRef.current.load();
|
|
266
|
+
} else {
|
|
267
|
+
// Finite audio not yet loaded (duration is NaN): call play() directly so
|
|
268
|
+
// Safari's user-gesture scope isn't lost waiting for an async canplay event.
|
|
269
|
+
_safePlay(audioRef.current);
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
_safePlay(audioRef.current);
|
|
156
273
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// position (e.g. 20s in), causing ads to start mid-stream. Calling load()
|
|
163
|
-
// here reconnects to the current live edge and gets a fresh manifest.
|
|
164
|
-
if (duration === Infinity) {
|
|
165
|
-
audioRef.current.load();
|
|
166
|
-
}
|
|
167
|
-
audioRef.current.play();
|
|
168
|
-
|
|
169
|
-
// Only start RAF loop for non-live streams with valid duration
|
|
170
|
-
var dur = audioRef.current.duration;
|
|
171
|
-
if (dur !== Infinity && !isNaN(dur) && isFinite(dur)) {
|
|
172
|
-
animationRef.current = window.requestAnimationFrame(_whilePlaying);
|
|
274
|
+
// Only start RAF loop for non-live streams with valid duration
|
|
275
|
+
var dur = audioRef.current.duration;
|
|
276
|
+
if (dur !== Infinity && !isNaN(dur) && isFinite(dur)) {
|
|
277
|
+
animationRef.current = window.requestAnimationFrame(_whilePlaying);
|
|
278
|
+
}
|
|
173
279
|
}
|
|
174
280
|
};
|
|
175
281
|
var toggleMute = function toggleMute() {
|
|
@@ -298,6 +404,13 @@ var Pause = function Pause() {
|
|
|
298
404
|
}));
|
|
299
405
|
};
|
|
300
406
|
|
|
407
|
+
var getHlsSrc = function getHlsSrc(audioSrc) {
|
|
408
|
+
var _urls$find;
|
|
409
|
+
var urls = Array.isArray(audioSrc) ? audioSrc : [audioSrc];
|
|
410
|
+
return (_urls$find = urls.find(function (url) {
|
|
411
|
+
return url && url.split('?')[0].endsWith('.m3u8');
|
|
412
|
+
})) !== null && _urls$find !== void 0 ? _urls$find : null;
|
|
413
|
+
};
|
|
301
414
|
var getTypeFromExtension = function getTypeFromExtension(url) {
|
|
302
415
|
var extension = url.split('.').pop().split('?')[0];
|
|
303
416
|
switch (extension) {
|
|
@@ -317,11 +430,15 @@ var getTypeFromExtension = function getTypeFromExtension(url) {
|
|
|
317
430
|
}
|
|
318
431
|
};
|
|
319
432
|
var ReactAudioPlayerInner = function ReactAudioPlayerInner(props) {
|
|
320
|
-
var _props$audioPlayerRef, _props$progressBarRef;
|
|
321
|
-
//
|
|
322
|
-
var
|
|
323
|
-
var
|
|
433
|
+
var _props$audioPlayerRef, _props$progressBarRef, _props$hlsRef;
|
|
434
|
+
// Always call hooks unconditionally — use internal refs when props don't provide them
|
|
435
|
+
var internalAudioRef = useRef();
|
|
436
|
+
var internalProgressBarRef = useRef();
|
|
437
|
+
var internalHlsRef = useRef(null);
|
|
324
438
|
var hasInitializedRef = useRef(false);
|
|
439
|
+
// Track isPlaying via a ref so the source-change useEffect can read the
|
|
440
|
+
// current value without adding isPlaying to its dependency array.
|
|
441
|
+
var isPlayingRef = useRef(false);
|
|
325
442
|
var customStyles = props ? props.style : '';
|
|
326
443
|
var title = props.title,
|
|
327
444
|
audioSrc = props.audioSrc,
|
|
@@ -344,27 +461,67 @@ var ReactAudioPlayerInner = function ReactAudioPlayerInner(props) {
|
|
|
344
461
|
forwardControl = props.forwardControl,
|
|
345
462
|
subtitle = props.subtitle,
|
|
346
463
|
prefix = props.prefix;
|
|
464
|
+
var audioPlayerRef = (_props$audioPlayerRef = props.audioPlayerRef) !== null && _props$audioPlayerRef !== void 0 ? _props$audioPlayerRef : internalAudioRef;
|
|
465
|
+
var progressBarRef = (_props$progressBarRef = props.progressBarRef) !== null && _props$progressBarRef !== void 0 ? _props$progressBarRef : internalProgressBarRef;
|
|
466
|
+
var hlsRef = (_props$hlsRef = props.hlsRef) !== null && _props$hlsRef !== void 0 ? _props$hlsRef : internalHlsRef;
|
|
467
|
+
var hlsSrcForRender = getHlsSrc(audioSrc);
|
|
468
|
+
var isHlsManaged = !!(hlsSrcForRender && Hls.isSupported());
|
|
469
|
+
|
|
470
|
+
// Keep isPlayingRef in sync on every render (runs before effects).
|
|
471
|
+
isPlayingRef.current = isPlaying;
|
|
347
472
|
var audioDuration = duration && !isNaN(duration) && calculateTime(duration);
|
|
348
473
|
var formatDuration = duration && !isNaN(duration) && audioDuration && formatCalculateTime(audioDuration);
|
|
349
474
|
|
|
350
|
-
//
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
// segments are stale. On first play the browser fetches the live edge
|
|
354
|
-
// naturally. On subsequent src changes we do call load() to reset the element.
|
|
355
|
-
// Use JSON.stringify to handle array comparisons by value instead of reference.
|
|
475
|
+
// Manage audio source changes. For HLS sources hls.js owns the loading cycle;
|
|
476
|
+
// for everything else we fall back to the native load() path.
|
|
477
|
+
// JSON.stringify handles array-valued audioSrc comparisons by value.
|
|
356
478
|
useEffect(function () {
|
|
357
|
-
if (audioPlayerRef.current
|
|
358
|
-
|
|
359
|
-
|
|
479
|
+
if (!audioPlayerRef.current || !audioSrc) return;
|
|
480
|
+
if (hasInitializedRef.current) {
|
|
481
|
+
resetDuration === null || resetDuration === void 0 ? void 0 : resetDuration();
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Tear down any existing hls.js instance before re-evaluating the source.
|
|
485
|
+
if (hlsRef.current) {
|
|
486
|
+
hlsRef.current.destroy();
|
|
487
|
+
hlsRef.current = null;
|
|
488
|
+
}
|
|
489
|
+
var hlsSrc = getHlsSrc(audioSrc);
|
|
490
|
+
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
491
|
+
if (hlsSrc && Hls.isSupported()) {
|
|
492
|
+
var hls = new Hls(_objectSpread2({
|
|
493
|
+
autoStartLoad: false,
|
|
494
|
+
liveSyncDurationCount: 3,
|
|
495
|
+
liveMaxLatencyDurationCount: 5,
|
|
496
|
+
enableWorker: !isSafari
|
|
497
|
+
}, isSafari && {
|
|
498
|
+
maxBufferHole: 2,
|
|
499
|
+
maxSeekHole: 2
|
|
500
|
+
}));
|
|
501
|
+
hls.loadSource(hlsSrc);
|
|
502
|
+
hls.attachMedia(audioPlayerRef.current);
|
|
503
|
+
hlsRef.current = hls;
|
|
504
|
+
} else {
|
|
505
|
+
// Non-HLS: call load() to prime the new source.
|
|
506
|
+
// Safari: skip load() when playing — the synchronous play() called in the
|
|
507
|
+
// gesture handler would be aborted (AbortError), losing the user activation token.
|
|
508
|
+
// Chrome/Firefox: always call load(); AudioContext defers play() via pendingPlayRef
|
|
509
|
+
// until after this effect, so load() and play() are sequenced with no concurrent abort.
|
|
510
|
+
if (hasInitializedRef.current && (!isSafari || !isPlayingRef.current)) {
|
|
360
511
|
try {
|
|
361
512
|
audioPlayerRef.current.load();
|
|
362
513
|
} catch (err) {
|
|
363
514
|
console.warn('Failed to reload audio source:', err);
|
|
364
515
|
}
|
|
365
516
|
}
|
|
366
|
-
hasInitializedRef.current = true;
|
|
367
517
|
}
|
|
518
|
+
hasInitializedRef.current = true;
|
|
519
|
+
return function () {
|
|
520
|
+
if (hlsRef.current) {
|
|
521
|
+
hlsRef.current.destroy();
|
|
522
|
+
hlsRef.current = null;
|
|
523
|
+
}
|
|
524
|
+
};
|
|
368
525
|
}, [JSON.stringify(audioSrc)]);
|
|
369
526
|
|
|
370
527
|
// Set initial volume to 100%
|
|
@@ -384,16 +541,13 @@ var ReactAudioPlayerInner = function ReactAudioPlayerInner(props) {
|
|
|
384
541
|
preload: "none",
|
|
385
542
|
onLoadedMetadata: onLoadedMetadata,
|
|
386
543
|
muted: isMuted
|
|
387
|
-
}, Array.isArray(audioSrc) ? audioSrc.map(function (
|
|
544
|
+
}, !isHlsManaged && (Array.isArray(audioSrc) ? audioSrc : [audioSrc]).map(function (url, i) {
|
|
388
545
|
return /*#__PURE__*/React.createElement("source", {
|
|
389
|
-
key:
|
|
390
|
-
src:
|
|
391
|
-
type: getTypeFromExtension(
|
|
546
|
+
key: i,
|
|
547
|
+
src: url,
|
|
548
|
+
type: getTypeFromExtension(url)
|
|
392
549
|
});
|
|
393
|
-
})
|
|
394
|
-
src: audioSrc,
|
|
395
|
-
type: getTypeFromExtension(audioSrc)
|
|
396
|
-
}) : null, "Your browser does not support the audio element."), /*#__PURE__*/React.createElement("div", {
|
|
550
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
397
551
|
className: "player-layout"
|
|
398
552
|
}, volumeCtrl && /*#__PURE__*/React.createElement("div", {
|
|
399
553
|
className: "player-controls-secondary-outer"
|
|
@@ -490,11 +644,13 @@ var ReactAudioPlayer = function ReactAudioPlayer(props) {
|
|
|
490
644
|
// references
|
|
491
645
|
var audioPlayerRef = (_props$audioPlayerRef = props.audioPlayerRef) !== null && _props$audioPlayerRef !== void 0 ? _props$audioPlayerRef : useRef(); // reference our audio component
|
|
492
646
|
var progressBarRef = (_props$progressBarRef = props.progressBarRef) !== null && _props$progressBarRef !== void 0 ? _props$progressBarRef : useRef(); // reference our progress bar
|
|
493
|
-
|
|
647
|
+
var hlsRef = useRef(null);
|
|
494
648
|
var customStyles = props ? props.style : '';
|
|
495
649
|
|
|
496
650
|
// hooks
|
|
497
|
-
var _useAudioPlayer = useAudioPlayer(audioPlayerRef, progressBarRef
|
|
651
|
+
var _useAudioPlayer = useAudioPlayer(audioPlayerRef, progressBarRef, {
|
|
652
|
+
hlsRef: hlsRef
|
|
653
|
+
}),
|
|
498
654
|
isPlaying = _useAudioPlayer.isPlaying,
|
|
499
655
|
currentTime = _useAudioPlayer.currentTime,
|
|
500
656
|
duration = _useAudioPlayer.duration,
|
|
@@ -511,6 +667,7 @@ var ReactAudioPlayer = function ReactAudioPlayer(props) {
|
|
|
511
667
|
return /*#__PURE__*/React.createElement(ReactAudioPlayerInner, _extends({}, props, {
|
|
512
668
|
audioPlayerRef: audioPlayerRef,
|
|
513
669
|
progressBarRef: progressBarRef,
|
|
670
|
+
hlsRef: hlsRef,
|
|
514
671
|
isPlaying: isPlaying,
|
|
515
672
|
isMuted: isMuted,
|
|
516
673
|
currentTime: currentTime,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apm-react-audio-player",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"author": "Jason Phan <jphan@mpr.org>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"react": "^16.0.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"hls.js": "^1.6.16",
|
|
34
35
|
"rollup": "^4.59.0",
|
|
35
36
|
"rollup-plugin-babel": "^4.3.3"
|
|
36
37
|
},
|
|
@@ -69,12 +70,15 @@
|
|
|
69
70
|
"tough-cookie": ">=4.1.3",
|
|
70
71
|
"ajv": ">=6.14.0",
|
|
71
72
|
"qs": ">=6.14.1",
|
|
72
|
-
"lodash": ">=4.
|
|
73
|
+
"lodash": ">=4.18.0",
|
|
73
74
|
"js-yaml": ">=4.1.0",
|
|
74
|
-
"@babel/helpers": ">=7.26.
|
|
75
|
-
"@babel/runtime": ">=7.26.
|
|
76
|
-
"
|
|
77
|
-
"
|
|
75
|
+
"@babel/helpers": ">=7.26.10",
|
|
76
|
+
"@babel/runtime": ">=7.26.10",
|
|
77
|
+
"@babel/plugin-transform-modules-systemjs": ">=7.29.0",
|
|
78
|
+
"flatted": ">=3.4.2",
|
|
79
|
+
"brace-expansion": ">=5.0.5",
|
|
80
|
+
"fast-uri": ">=3.1.2",
|
|
81
|
+
"picomatch": ">=2.3.2",
|
|
78
82
|
"tmp": ">=0.2.3"
|
|
79
83
|
},
|
|
80
84
|
"files": [
|