@tiny-codes/react-easy 1.4.12 → 1.4.14

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.
@@ -29,6 +29,12 @@ var AudioPlayer = /*#__PURE__*/function () {
29
29
  _defineProperty(this, "gainNode", null);
30
30
  _defineProperty(this, "sourceNode", null);
31
31
  _defineProperty(this, "options", void 0);
32
+ _defineProperty(this, "mediaSource", null);
33
+ _defineProperty(this, "sourceBuffer", null);
34
+ _defineProperty(this, "chunkQueue", []);
35
+ _defineProperty(this, "appending", false);
36
+ _defineProperty(this, "streamEnded", false);
37
+ _defineProperty(this, "stopLoadingSource", false);
32
38
  _defineProperty(this, "onPlayEnd", void 0);
33
39
  /**
34
40
  * - **EN:** Add audio event listener
@@ -77,8 +83,7 @@ var AudioPlayer = /*#__PURE__*/function () {
77
83
  _createClass(AudioPlayer, [{
78
84
  key: "isPlaying",
79
85
  get: function get() {
80
- var _this$audioContext;
81
- return ((_this$audioContext = this.audioContext) === null || _this$audioContext === void 0 ? void 0 : _this$audioContext.state) === 'running';
86
+ return !this.audio.paused && !this.audio.ended;
82
87
  }
83
88
  /**
84
89
  * - **EN:** Get current playback time (seconds)
@@ -116,7 +121,7 @@ var AudioPlayer = /*#__PURE__*/function () {
116
121
  key: "play",
117
122
  value: (function () {
118
123
  var _play = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
119
- var _this$audioContext2;
124
+ var _this$audioContext;
120
125
  var _this$options2, _this$options2$onPlay, _this$options3, _this$options3$onErro;
121
126
  return _regeneratorRuntime().wrap(function _callee$(_context) {
122
127
  while (1) switch (_context.prev = _context.next) {
@@ -124,7 +129,7 @@ var AudioPlayer = /*#__PURE__*/function () {
124
129
  if (!this.audioContext) {
125
130
  this.initAudioContext();
126
131
  }
127
- if (!(((_this$audioContext2 = this.audioContext) === null || _this$audioContext2 === void 0 ? void 0 : _this$audioContext2.state) === 'suspended')) {
132
+ if (!(((_this$audioContext = this.audioContext) === null || _this$audioContext === void 0 ? void 0 : _this$audioContext.state) === 'suspended')) {
128
133
  _context.next = 4;
129
134
  break;
130
135
  }
@@ -247,17 +252,23 @@ var AudioPlayer = /*#__PURE__*/function () {
247
252
  case 0:
248
253
  this.audio.pause();
249
254
  this.audio.src = '';
255
+ this.disposeMediaSourceInternal();
250
256
  if (!(typeof source === 'string')) {
251
- _context2.next = 6;
257
+ _context2.next = 8;
252
258
  break;
253
259
  }
254
260
  this.audio.src = source;
255
- _context2.next = 8;
256
- break;
257
- case 6:
258
- _context2.next = 8;
259
- return this.handleStreamSource(source);
261
+ return _context2.abrupt("return", {
262
+ stopLoading: function stopLoading() {
263
+ // empty function
264
+ }
265
+ });
260
266
  case 8:
267
+ _context2.next = 10;
268
+ return this.handleStreamSource(source);
269
+ case 10:
270
+ return _context2.abrupt("return", _context2.sent);
271
+ case 11:
261
272
  case "end":
262
273
  return _context2.stop();
263
274
  }
@@ -331,97 +342,81 @@ var AudioPlayer = /*#__PURE__*/function () {
331
342
  this.sourceNode = null;
332
343
  this.gainNode = null;
333
344
  }
345
+ }, {
346
+ key: "disposeMediaSourceInternal",
347
+ value: function disposeMediaSourceInternal() {
348
+ this.mediaSource = null;
349
+ this.sourceBuffer = null;
350
+ this.chunkQueue = [];
351
+ this.appending = false;
352
+ this.streamEnded = false;
353
+ }
334
354
 
335
- /** Process streaming data source */
355
+ /** Process streaming data source /ArrayBuffer/Uint8Array/Blob */
336
356
  }, {
337
357
  key: "handleStreamSource",
338
358
  value: (function () {
339
- var _handleStreamSource = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(source) {
340
- var blob, stream, response, url;
341
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
342
- while (1) switch (_context4.prev = _context4.next) {
359
+ var _handleStreamSource = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(source) {
360
+ var _this2 = this;
361
+ var result, url, blob, _url, _this$options6, mime, _this$options7, _this$options7$onErro;
362
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
363
+ while (1) switch (_context3.prev = _context3.next) {
343
364
  case 0:
365
+ result = {
366
+ stopLoading: function stopLoading() {
367
+ // empty function
368
+ }
369
+ };
344
370
  if (source) {
345
- _context4.next = 2;
371
+ _context3.next = 3;
346
372
  break;
347
373
  }
348
- return _context4.abrupt("return");
349
- case 2:
350
- _context4.prev = 2;
374
+ return _context3.abrupt("return", result);
375
+ case 3:
376
+ _context3.prev = 3;
351
377
  if (!(source instanceof Blob)) {
352
- _context4.next = 7;
378
+ _context3.next = 10;
353
379
  break;
354
380
  }
355
- blob = source;
356
- _context4.next = 16;
357
- break;
358
- case 7:
381
+ url = URL.createObjectURL(source);
382
+ this.audio.src = url;
383
+ return _context3.abrupt("return", result);
384
+ case 10:
359
385
  if (!(source instanceof ArrayBuffer || source instanceof Uint8Array)) {
360
- _context4.next = 11;
386
+ _context3.next = 18;
361
387
  break;
362
388
  }
363
- blob = new Blob([source]);
364
- _context4.next = 16;
365
- break;
366
- case 11:
389
+ blob = source instanceof Uint8Array ? new Blob([source]) : new Blob([new Uint8Array(source)]);
390
+ _url = URL.createObjectURL(blob);
391
+ this.audio.src = _url;
392
+ this.audio.onloadeddata = function () {
393
+ return URL.revokeObjectURL(_url);
394
+ };
395
+ return _context3.abrupt("return", result);
396
+ case 18:
367
397
  // Create a new ReadableStream to read data from the reader
368
- stream = new ReadableStream({
369
- pull: function pull(controller) {
370
- return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
371
- var _yield$source$read, done, value;
372
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
373
- while (1) switch (_context3.prev = _context3.next) {
374
- case 0:
375
- _context3.prev = 0;
376
- _context3.next = 3;
377
- return source.read();
378
- case 3:
379
- _yield$source$read = _context3.sent;
380
- done = _yield$source$read.done;
381
- value = _yield$source$read.value;
382
- if (done) {
383
- controller.close();
384
- } else {
385
- controller.enqueue(value);
386
- }
387
- _context3.next = 12;
388
- break;
389
- case 9:
390
- _context3.prev = 9;
391
- _context3.t0 = _context3["catch"](0);
392
- controller.error(_context3.t0);
393
- case 12:
394
- case "end":
395
- return _context3.stop();
396
- }
397
- }, _callee3, null, [[0, 9]]);
398
- }))();
399
- }
400
- }); // Convert stream to Blob and create URL
401
- response = new Response(stream);
402
- _context4.next = 15;
403
- return response.blob();
404
- case 15:
405
- blob = _context4.sent;
406
- case 16:
407
- url = URL.createObjectURL(blob);
408
- this.audio.src = url;
409
-
410
- // Release Blob URL after audio loads
411
- this.audio.onload = function () {
412
- URL.revokeObjectURL(url);
398
+ mime = ((_this$options6 = this.options) === null || _this$options6 === void 0 ? void 0 : _this$options6.mimeType) || 'audio/mpeg';
399
+ result.stopLoading = function () {
400
+ _this2.stopLoadingSource = true;
413
401
  };
414
- _context4.next = 24;
402
+ _context3.next = 22;
403
+ return this.initMediaSourceForReader(source, mime);
404
+ case 22:
405
+ return _context3.abrupt("return", result);
406
+ case 23:
407
+ _context3.next = 30;
415
408
  break;
416
- case 21:
417
- _context4.prev = 21;
418
- _context4.t0 = _context4["catch"](2);
419
- console.error('Error processing audio stream:', _context4.t0);
420
- case 24:
409
+ case 25:
410
+ _context3.prev = 25;
411
+ _context3.t0 = _context3["catch"](3);
412
+ console.error('Error processing audio stream:', _context3.t0);
413
+ (_this$options7 = this.options) === null || _this$options7 === void 0 || (_this$options7$onErro = _this$options7.onError) === null || _this$options7$onErro === void 0 || _this$options7$onErro.call(_this$options7, _context3.t0);
414
+ throw _context3.t0;
415
+ case 30:
421
416
  case "end":
422
- return _context4.stop();
417
+ return _context3.stop();
423
418
  }
424
- }, _callee4, this, [[2, 21]]);
419
+ }, _callee3, this, [[3, 25]]);
425
420
  }));
426
421
  function handleStreamSource(_x2) {
427
422
  return _handleStreamSource.apply(this, arguments);
@@ -450,6 +445,224 @@ var AudioPlayer = /*#__PURE__*/function () {
450
445
  this.audio.volume = this._volume;
451
446
  }
452
447
  }
448
+
449
+ /** Initialize MediaSource and push reader chunks into SourceBuffer */
450
+ }, {
451
+ key: "initMediaSourceForReader",
452
+ value: (function () {
453
+ var _initMediaSourceForReader = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(reader, mime) {
454
+ var _this3 = this;
455
+ var objectURL;
456
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
457
+ while (1) switch (_context4.prev = _context4.next) {
458
+ case 0:
459
+ if (!(typeof MediaSource === 'undefined')) {
460
+ _context4.next = 5;
461
+ break;
462
+ }
463
+ console.warn('MediaSource is not supported, falling back to one-time buffering.');
464
+ _context4.next = 4;
465
+ return this.fallbackReaderToBlob(reader);
466
+ case 4:
467
+ return _context4.abrupt("return");
468
+ case 5:
469
+ if (!(typeof MediaSource !== 'undefined' && !MediaSource.isTypeSupported(mime))) {
470
+ _context4.next = 10;
471
+ break;
472
+ }
473
+ console.warn('MIME type is not supported, falling back to one-time buffering.');
474
+ _context4.next = 9;
475
+ return this.fallbackReaderToBlob(reader);
476
+ case 9:
477
+ return _context4.abrupt("return");
478
+ case 10:
479
+ this.mediaSource = new MediaSource();
480
+ objectURL = URL.createObjectURL(this.mediaSource);
481
+ this.audio.src = objectURL;
482
+ this.stopLoadingSource = false;
483
+ this.mediaSource.addEventListener('sourceopen', function () {
484
+ if (!_this3.mediaSource) return;
485
+ _this3.sourceBuffer = _this3.mediaSource.addSourceBuffer(mime);
486
+ _this3.sourceBuffer.addEventListener('updateend', function () {
487
+ _this3.appending = false;
488
+ _this3.tryAppendNext();
489
+ _this3.finalizeMediaSourceIfPossible();
490
+ });
491
+
492
+ // Start reading loop
493
+ _this3.readLoop(reader);
494
+ });
495
+ case 15:
496
+ case "end":
497
+ return _context4.stop();
498
+ }
499
+ }, _callee4, this);
500
+ }));
501
+ function initMediaSourceForReader(_x3, _x4) {
502
+ return _initMediaSourceForReader.apply(this, arguments);
503
+ }
504
+ return initMediaSourceForReader;
505
+ }() /** Loop to read data from the reader */)
506
+ }, {
507
+ key: "readLoop",
508
+ value: (function () {
509
+ var _readLoop = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(reader) {
510
+ var _yield$reader$read, done, value, _this$options8, _this$options8$onErro;
511
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
512
+ while (1) switch (_context5.prev = _context5.next) {
513
+ case 0:
514
+ _context5.prev = 0;
515
+ // Auto play (optional)
516
+ if (this.audio.paused) {
517
+ void this.play();
518
+ }
519
+ // eslint-disable-next-line no-constant-condition
520
+ case 2:
521
+ if (!true) {
522
+ _context5.next = 16;
523
+ break;
524
+ }
525
+ _context5.next = 5;
526
+ return reader.read();
527
+ case 5:
528
+ _yield$reader$read = _context5.sent;
529
+ done = _yield$reader$read.done;
530
+ value = _yield$reader$read.value;
531
+ if (!(done || this.stopLoadingSource)) {
532
+ _context5.next = 11;
533
+ break;
534
+ }
535
+ this.streamEnded = true;
536
+ return _context5.abrupt("break", 16);
537
+ case 11:
538
+ if (value && value.byteLength) {
539
+ this.chunkQueue.push(value);
540
+ this.tryAppendNext();
541
+ }
542
+ _context5.next = 14;
543
+ return new Promise(function (resolve) {
544
+ return setTimeout(resolve, 100);
545
+ });
546
+ case 14:
547
+ _context5.next = 2;
548
+ break;
549
+ case 16:
550
+ // Try to finalize after the loop exits (including 0 chunk case)
551
+ this.finalizeMediaSourceIfPossible();
552
+ _context5.next = 23;
553
+ break;
554
+ case 19:
555
+ _context5.prev = 19;
556
+ _context5.t0 = _context5["catch"](0);
557
+ console.error('Error reading stream:', _context5.t0);
558
+ (_this$options8 = this.options) === null || _this$options8 === void 0 || (_this$options8$onErro = _this$options8.onError) === null || _this$options8$onErro === void 0 || _this$options8$onErro.call(_this$options8, _context5.t0);
559
+ case 23:
560
+ case "end":
561
+ return _context5.stop();
562
+ }
563
+ }, _callee5, this, [[0, 19]]);
564
+ }));
565
+ function readLoop(_x5) {
566
+ return _readLoop.apply(this, arguments);
567
+ }
568
+ return readLoop;
569
+ }() /** Try to append the next chunk from the queue to the SourceBuffer */)
570
+ }, {
571
+ key: "tryAppendNext",
572
+ value: function tryAppendNext() {
573
+ if (!this.sourceBuffer || this.appending) return;
574
+ if (!this.chunkQueue.length) return;
575
+ var chunk = this.chunkQueue.shift();
576
+ this.appending = true;
577
+ try {
578
+ this.sourceBuffer.appendBuffer(chunk);
579
+ } catch (e) {
580
+ var _this$options9, _this$options9$onErro;
581
+ console.error('Error appending buffer:', e);
582
+ this.appending = false;
583
+ (_this$options9 = this.options) === null || _this$options9 === void 0 || (_this$options9$onErro = _this$options9.onError) === null || _this$options9$onErro === void 0 || _this$options9$onErro.call(_this$options9, e);
584
+ this.finalizeMediaSourceIfPossible();
585
+ }
586
+ }
587
+
588
+ /** Finalize MediaSource if possible (stream ended, no pending chunks, and not updating) */
589
+ }, {
590
+ key: "finalizeMediaSourceIfPossible",
591
+ value: function finalizeMediaSourceIfPossible() {
592
+ var _this$sourceBuffer;
593
+ var receivedAnyChunk = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
594
+ if (this.mediaSource && this.mediaSource.readyState === 'open' && this.streamEnded && !((_this$sourceBuffer = this.sourceBuffer) !== null && _this$sourceBuffer !== void 0 && _this$sourceBuffer.updating) && this.chunkQueue.length === 0) {
595
+ try {
596
+ this.mediaSource.endOfStream();
597
+ } catch (e) {
598
+ console.warn('endOfStream error:', e);
599
+ }
600
+ }
601
+ }
602
+
603
+ /** Fallback to one-time Blob synthesis when streaming is not supported */
604
+ }, {
605
+ key: "fallbackReaderToBlob",
606
+ value: (function () {
607
+ var _fallbackReaderToBlob = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(reader) {
608
+ var stream, response, blob, url;
609
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
610
+ while (1) switch (_context7.prev = _context7.next) {
611
+ case 0:
612
+ stream = new ReadableStream({
613
+ pull: function pull(controller) {
614
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
615
+ var _yield$reader$read2, done, value;
616
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
617
+ while (1) switch (_context6.prev = _context6.next) {
618
+ case 0:
619
+ _context6.prev = 0;
620
+ _context6.next = 3;
621
+ return reader.read();
622
+ case 3:
623
+ _yield$reader$read2 = _context6.sent;
624
+ done = _yield$reader$read2.done;
625
+ value = _yield$reader$read2.value;
626
+ if (done) {
627
+ controller.close();
628
+ } else {
629
+ controller.enqueue(value);
630
+ }
631
+ _context6.next = 12;
632
+ break;
633
+ case 9:
634
+ _context6.prev = 9;
635
+ _context6.t0 = _context6["catch"](0);
636
+ controller.error(_context6.t0);
637
+ case 12:
638
+ case "end":
639
+ return _context6.stop();
640
+ }
641
+ }, _callee6, null, [[0, 9]]);
642
+ }))();
643
+ }
644
+ }); // Convert stream to Blob and create URL
645
+ response = new Response(stream);
646
+ _context7.next = 4;
647
+ return response.blob();
648
+ case 4:
649
+ blob = _context7.sent;
650
+ url = URL.createObjectURL(blob);
651
+ this.audio.src = url;
652
+ this.audio.onloadeddata = function () {
653
+ return URL.revokeObjectURL(url);
654
+ };
655
+ case 8:
656
+ case "end":
657
+ return _context7.stop();
658
+ }
659
+ }, _callee7, this);
660
+ }));
661
+ function fallbackReaderToBlob(_x6) {
662
+ return _fallbackReaderToBlob.apply(this, arguments);
663
+ }
664
+ return fallbackReaderToBlob;
665
+ }())
453
666
  }]);
454
667
  return AudioPlayer;
455
668
  }();