@scarlett-player/embed 0.5.3 → 1.0.0

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.
@@ -43,6 +43,18 @@ function mapLevels(levels, _currentLevel) {
43
43
  codec: level.codecSet
44
44
  }));
45
45
  }
46
+ function getInitialBandwidthEstimate(overrideBps) {
47
+ const HLS_DEFAULT_ESTIMATE = 5e5;
48
+ if (overrideBps !== void 0 && overrideBps > 0) {
49
+ return overrideBps;
50
+ }
51
+ const connection = navigator.connection;
52
+ if (connection?.downlink && connection.downlink > 0) {
53
+ const bps = connection.downlink * 1e6;
54
+ return Math.round(bps * 0.85);
55
+ }
56
+ return HLS_DEFAULT_ESTIMATE;
57
+ }
46
58
  var HLS_ERROR_TYPES = {
47
59
  NETWORK_ERROR: "networkError",
48
60
  MEDIA_ERROR: "mediaError",
@@ -113,6 +125,14 @@ function setupHlsEventHandlers(hls, api, callbacks) {
113
125
  });
114
126
  callbacks.onLevelSwitched?.(data.level);
115
127
  });
128
+ let lastBandwidthUpdate = 0;
129
+ addHandler("hlsFragLoaded", () => {
130
+ const now = Date.now();
131
+ if (now - lastBandwidthUpdate >= 2e3 && hls.bandwidthEstimate) {
132
+ lastBandwidthUpdate = now;
133
+ api.setState("bandwidth", Math.round(hls.bandwidthEstimate));
134
+ }
135
+ });
116
136
  addHandler("hlsFragBuffered", () => {
117
137
  api.setState("buffering", false);
118
138
  callbacks.onBufferUpdate?.();
@@ -355,6 +375,7 @@ var DEFAULT_CONFIG$3 = {
355
375
  maxMaxBufferLength: 600,
356
376
  backBufferLength: 30,
357
377
  enableWorker: true,
378
+ capLevelToPlayerSize: true,
358
379
  // Error recovery settings
359
380
  maxNetworkRetries: 3,
360
381
  maxMediaRetries: 2,
@@ -424,11 +445,13 @@ function createHLSPlugin(config) {
424
445
  startPosition: mergedConfig.startPosition,
425
446
  startLevel: -1,
426
447
  // Auto quality selection (ABR)
448
+ abrEwmaDefaultEstimate: getInitialBandwidthEstimate(mergedConfig.initialBandwidthEstimate),
427
449
  lowLatencyMode: mergedConfig.lowLatencyMode,
428
450
  maxBufferLength: mergedConfig.maxBufferLength,
429
451
  maxMaxBufferLength: mergedConfig.maxMaxBufferLength,
430
452
  backBufferLength: mergedConfig.backBufferLength,
431
453
  enableWorker: mergedConfig.enableWorker,
454
+ capLevelToPlayerSize: mergedConfig.capLevelToPlayerSize,
432
455
  // Minimize hls.js internal retries - we handle retries ourselves
433
456
  fragLoadingMaxRetry: 1,
434
457
  manifestLoadingMaxRetry: 1,
@@ -699,7 +722,10 @@ function createHLSPlugin(config) {
699
722
  currentSrc = src;
700
723
  api.setState("playbackState", "loading");
701
724
  api.setState("buffering", true);
702
- if (isHlsJsSupported()) {
725
+ if (api.getState("airplayActive") && supportsNativeHLS()) {
726
+ api.logger.info("Using native HLS (AirPlay active)");
727
+ await loadNative(src);
728
+ } else if (isHlsJsSupported()) {
703
729
  api.logger.info("Using hls.js for HLS playback");
704
730
  await loadWithHlsJs(src);
705
731
  } else if (supportsNativeHLS()) {
@@ -1561,7 +1587,9 @@ var DEFAULT_CONFIG$1 = {
1561
1587
  persist: false,
1562
1588
  persistKey: "scarlett-playlist",
1563
1589
  shuffle: false,
1564
- repeat: "none"
1590
+ repeat: "none",
1591
+ autoLoad: true,
1592
+ advanceDelay: 0
1565
1593
  };
1566
1594
  function generateId() {
1567
1595
  return `track-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
@@ -1705,6 +1733,9 @@ function createPlaylistPlugin(config) {
1705
1733
  }
1706
1734
  api?.setState("mediaType", track.type || "audio");
1707
1735
  emitChange();
1736
+ if (mergedConfig.autoLoad !== false && track.src) {
1737
+ api?.emit("media:load-request", { src: track.src, autoplay: true });
1738
+ }
1708
1739
  };
1709
1740
  const plugin = {
1710
1741
  id: "playlist",
@@ -1719,12 +1750,20 @@ function createPlaylistPlugin(config) {
1719
1750
  if (shuffle && tracks.length > 0) {
1720
1751
  generateShuffleOrder();
1721
1752
  }
1753
+ let advanceTimeout = null;
1722
1754
  const unsubEnded = api.on("playback:ended", () => {
1723
1755
  if (!mergedConfig.autoAdvance) return;
1724
1756
  const nextIdx = getNextIndex();
1725
1757
  if (nextIdx >= 0) {
1726
- api?.logger.debug("Auto-advancing to next track", { nextIdx });
1727
- setCurrentTrack(nextIdx);
1758
+ const advance = () => {
1759
+ api?.logger.debug("Auto-advancing to next track", { nextIdx });
1760
+ setCurrentTrack(nextIdx);
1761
+ };
1762
+ if (mergedConfig.advanceDelay) {
1763
+ advanceTimeout = setTimeout(advance, mergedConfig.advanceDelay);
1764
+ } else {
1765
+ advance();
1766
+ }
1728
1767
  } else {
1729
1768
  api?.logger.info("Playlist ended");
1730
1769
  api?.emit("playlist:ended", void 0);
@@ -1732,6 +1771,10 @@ function createPlaylistPlugin(config) {
1732
1771
  });
1733
1772
  api.onDestroy(() => {
1734
1773
  unsubEnded();
1774
+ if (advanceTimeout) {
1775
+ clearTimeout(advanceTimeout);
1776
+ advanceTimeout = null;
1777
+ }
1735
1778
  persistPlaylist();
1736
1779
  });
1737
1780
  },
@@ -3716,6 +3759,13 @@ class ScarlettPlayer {
3716
3759
  await this.pluginManager.initPlugin(id);
3717
3760
  }
3718
3761
  }
3762
+ this.eventBus.on("media:load-request", async ({ src, autoplay }) => {
3763
+ if (this.stateManager.getValue("chromecastActive")) return;
3764
+ await this.load(src);
3765
+ if (autoplay !== false) {
3766
+ await this.play();
3767
+ }
3768
+ });
3719
3769
  if (this.initialSrc) {
3720
3770
  await this.load(this.initialSrc);
3721
3771
  }
@@ -4543,6 +4593,12 @@ async function createEmbedPlayer(container, config, pluginCreators2, availableTy
4543
4593
  artwork: config.artwork || config.poster || config.playlist?.[0]?.artwork
4544
4594
  }));
4545
4595
  }
4596
+ if (pluginCreators2.watermark && config.watermark) {
4597
+ plugins.push(pluginCreators2.watermark(config.watermark));
4598
+ }
4599
+ if (pluginCreators2.captions) {
4600
+ plugins.push(pluginCreators2.captions(config.captions || {}));
4601
+ }
4546
4602
  if (pluginCreators2.analytics && config.analytics?.beaconUrl) {
4547
4603
  plugins.push(pluginCreators2.analytics({
4548
4604
  beaconUrl: config.analytics.beaconUrl,
@@ -4660,7 +4716,7 @@ function setupAutoInit(pluginCreators2, availableTypes) {
4660
4716
  }
4661
4717
  }
4662
4718
  }
4663
- const VERSION = "0.3.0-audio";
4719
+ const VERSION = "0.5.3-audio";
4664
4720
  const AVAILABLE_TYPES = ["audio", "audio-mini"];
4665
4721
  const pluginCreators = {
4666
4722
  hls: createHLSPlugin,