@scarlett-player/hls 1.11.0 → 1.12.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.
package/dist/light.cjs CHANGED
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/light.ts
31
31
  var light_exports = {};
32
32
  __export(light_exports, {
33
+ DEFAULT_TARGET_LATENCY: () => DEFAULT_TARGET_LATENCY,
34
+ computeLiveMetrics: () => computeLiveMetrics,
33
35
  createHLSPlugin: () => createHLSPlugin,
34
36
  default: () => light_default,
35
37
  sanitizeUrl: () => import_core.sanitizeUrl
@@ -167,6 +169,107 @@ function getInitialBandwidthEstimate(overrideBps) {
167
169
  // src/sanitize-url.ts
168
170
  var import_core = require("@scarlett-player/core");
169
171
 
172
+ // src/live-metrics.ts
173
+ var DEFAULT_TARGET_LATENCY = 3;
174
+ var MIN_EDGE_TOLERANCE = 1.5;
175
+ var NATIVE_EDGE_TOLERANCE = 7;
176
+ var EPSILON = 0.05;
177
+ function finite(value) {
178
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
179
+ }
180
+ function rangeFromDetails(details) {
181
+ if (!details) return null;
182
+ const start = finite(details.fragmentStart) ?? finite(details.fragments?.[0]?.start) ?? 0;
183
+ const total = finite(details.totalduration);
184
+ const end = finite(details.edge) ?? (total === null ? null : start + total);
185
+ if (end === null) return null;
186
+ return { start, end };
187
+ }
188
+ function rangeFromMedia(media) {
189
+ const seekable = media?.seekable;
190
+ if (!seekable || seekable.length === 0) return null;
191
+ const start = seekable.start(0);
192
+ const end = seekable.end(seekable.length - 1);
193
+ if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
194
+ return { start, end };
195
+ }
196
+ function targetFromDetails(details) {
197
+ if (!details) return null;
198
+ const targetduration = finite(details.targetduration);
199
+ return finite(details.partHoldBack) ?? finite(details.holdBack) ?? (targetduration !== null ? targetduration * 3 : null);
200
+ }
201
+ function edgeTolerance(details, targetLatency) {
202
+ const targetduration = finite(details?.targetduration);
203
+ const half = targetduration !== null ? targetduration / 2 : targetLatency / 2;
204
+ return Math.max(MIN_EDGE_TOLERANCE, finite(details?.partTarget) ?? half);
205
+ }
206
+ function computeLiveMetrics(source) {
207
+ if (source.kind === "hls") {
208
+ const { hls, details } = source;
209
+ const media2 = hls.media;
210
+ const seekableRange2 = rangeFromDetails(details) ?? rangeFromMedia(media2);
211
+ const targetLatency2 = finite(hls.targetLatency) ?? targetFromDetails(details) ?? DEFAULT_TARGET_LATENCY;
212
+ const latency2 = finite(hls.latency) ?? (seekableRange2 && media2 ? Math.max(0, seekableRange2.end - media2.currentTime) : null);
213
+ if (latency2 === null && seekableRange2 === null) return null;
214
+ const resolvedLatency = latency2 ?? 0;
215
+ return {
216
+ latency: resolvedLatency,
217
+ targetLatency: targetLatency2,
218
+ atEdge: resolvedLatency <= targetLatency2 + edgeTolerance(details, targetLatency2),
219
+ seekableRange: seekableRange2,
220
+ // Effective LL, not requested LL: the manifest has to carry parts or
221
+ // advertise blocking reloads, AND the host has to have asked for it.
222
+ lowLatency: source.lowLatencyRequested !== false && (!!details?.partList?.length || details?.canBlockReload === true)
223
+ };
224
+ }
225
+ const { media } = source;
226
+ const seekableRange = rangeFromMedia(media);
227
+ if (!seekableRange) return null;
228
+ const targetLatency = source.targetLatency ?? DEFAULT_TARGET_LATENCY;
229
+ const tolerance = source.targetLatency === void 0 ? NATIVE_EDGE_TOLERANCE : Math.max(MIN_EDGE_TOLERANCE, source.targetLatency / 2);
230
+ const latency = Math.max(0, seekableRange.end - media.currentTime);
231
+ return {
232
+ latency,
233
+ targetLatency,
234
+ atEdge: latency <= targetLatency + tolerance,
235
+ seekableRange,
236
+ lowLatency: source.lowLatency === true
237
+ };
238
+ }
239
+ function applyLiveMetrics(api, metrics) {
240
+ if (!metrics) return;
241
+ const previousLatency = api.getState("liveLatency");
242
+ if (Math.abs(previousLatency - metrics.latency) > EPSILON) {
243
+ api.setState("liveLatency", metrics.latency);
244
+ api.emit("live:latency", { latency: metrics.latency });
245
+ }
246
+ if (api.getState("liveEdge") !== metrics.atEdge) {
247
+ api.setState("liveEdge", metrics.atEdge);
248
+ api.emit("live:edgechange", { atEdge: metrics.atEdge });
249
+ }
250
+ const range = metrics.seekableRange;
251
+ if (range) {
252
+ const previous = api.getState("seekableRange");
253
+ if (!previous || Math.abs(previous.start - range.start) > EPSILON || Math.abs(previous.end - range.end) > EPSILON) {
254
+ api.setState("seekableRange", { start: range.start, end: range.end });
255
+ api.emit("live:seekablerange", { start: range.start, end: range.end });
256
+ }
257
+ }
258
+ if (api.getState("lowLatencyMode") !== metrics.lowLatency) {
259
+ api.setState("lowLatencyMode", metrics.lowLatency);
260
+ api.emit("live:lowlatency", { enabled: metrics.lowLatency });
261
+ }
262
+ }
263
+ function resetLiveMetrics(api) {
264
+ if (api.getState("lowLatencyMode")) {
265
+ api.setState("lowLatencyMode", false);
266
+ api.emit("live:lowlatency", { enabled: false });
267
+ }
268
+ api.setState("liveLatency", 0);
269
+ api.setState("liveEdge", false);
270
+ api.setState("seekableRange", null);
271
+ }
272
+
170
273
  // src/event-map.ts
171
274
  var HLS_ERROR_TYPES = {
172
275
  NETWORK_ERROR: "networkError",
@@ -304,16 +407,18 @@ function setupHlsEventHandlers(hls, api, callbacks) {
304
407
  if (data.details?.live !== void 0) {
305
408
  api.setState("live", data.details.live);
306
409
  if (data.details.live) {
307
- const details = data.details;
308
- const start = details.fragmentStart ?? (details.fragments?.[0]?.start ?? 0);
309
- const end = details.edge ?? details.totalduration ?? 0;
310
- api.setState("seekableRange", { start, end });
311
- const video = hls.media;
312
- if (video) {
313
- const latency = Math.max(0, end - video.currentTime);
314
- api.setState("liveLatency", latency);
315
- api.setState("liveEdge", latency < (details.targetduration ?? 3) * 3);
316
- }
410
+ callbacks.onLevelDetails?.(data.details);
411
+ applyLiveMetrics(
412
+ api,
413
+ computeLiveMetrics({
414
+ kind: "hls",
415
+ hls,
416
+ details: data.details,
417
+ lowLatencyRequested: callbacks.isLowLatencyRequested?.() ?? true
418
+ })
419
+ );
420
+ } else {
421
+ resetLiveMetrics(api);
317
422
  }
318
423
  callbacks.onLiveUpdate?.();
319
424
  }
@@ -353,7 +458,7 @@ function setupHlsEventHandlers(hls, api, callbacks) {
353
458
  api.setState("currentAudioTrack", null);
354
459
  };
355
460
  }
356
- function setupVideoEventHandlers(video, api) {
461
+ function setupVideoEventHandlers(video, api, getLiveMetrics) {
357
462
  const handlers = [];
358
463
  const addHandler = (event, handler) => {
359
464
  video.addEventListener(event, handler);
@@ -390,15 +495,11 @@ function setupVideoEventHandlers(video, api) {
390
495
  addHandler("timeupdate", () => {
391
496
  api.setState("currentTime", video.currentTime);
392
497
  api.emit("playback:timeupdate", { currentTime: video.currentTime });
393
- if (video.seekable && video.seekable.length > 0) {
394
- if (api.getState("live") || !Number.isFinite(video.duration)) {
395
- const start = video.seekable.start(0);
396
- const end = video.seekable.end(video.seekable.length - 1);
397
- api.setState("seekableRange", { start, end });
398
- const latency = Math.max(0, end - video.currentTime);
399
- api.setState("liveEdge", latency < 10);
400
- api.setState("liveLatency", latency);
401
- }
498
+ if (api.getState("live") || !Number.isFinite(video.duration)) {
499
+ applyLiveMetrics(
500
+ api,
501
+ getLiveMetrics ? getLiveMetrics() : computeLiveMetrics({ kind: "media", media: video })
502
+ );
402
503
  }
403
504
  });
404
505
  addHandler("durationchange", () => {
@@ -546,7 +647,7 @@ function createValidatingPlaylistLoader(Hls) {
546
647
  }
547
648
 
548
649
  // src/version.ts
549
- var PKG_VERSION = true ? "1.11.0" : "0.0.0-dev";
650
+ var PKG_VERSION = true ? "1.12.0" : "0.0.0-dev";
550
651
 
551
652
  // src/create-hls-plugin.ts
552
653
  var DEFAULT_CONFIG = {
@@ -574,6 +675,7 @@ var DEFAULT_CONFIG = {
574
675
  // Never index a malformed live playlist refresh blindly
575
676
  validatePlaylists: true
576
677
  };
678
+ var LL_CATCH_UP_PLAYBACK_RATE = 1.1;
577
679
  var MANIFEST_PHASE_ERRORS = [
578
680
  "manifestLoadError",
579
681
  "manifestLoadTimeOut",
@@ -589,6 +691,9 @@ function createHLSPluginWith(loader, variant, config) {
589
691
  let cleanupHlsEvents = null;
590
692
  let cleanupVideoEvents = null;
591
693
  let isAutoQuality = true;
694
+ let lastLevelDetails = null;
695
+ let lastLiveMetrics = null;
696
+ let lastKnownTargetLatency = null;
592
697
  let loadSession = 0;
593
698
  let abortPendingLoad = null;
594
699
  let networkRetryCount = 0;
@@ -611,6 +716,24 @@ function createHLSPluginWith(loader, variant, config) {
611
716
  let stallWatchdogTimer = null;
612
717
  let lastStallCheckTime = 0;
613
718
  let lastStallCheckPosition = 0;
719
+ const readLiveMetrics = () => {
720
+ const metrics = hls && !isNative ? computeLiveMetrics({
721
+ kind: "hls",
722
+ hls,
723
+ details: lastLevelDetails,
724
+ lowLatencyRequested: mergedConfig.lowLatencyMode === true
725
+ }) : video ? computeLiveMetrics({
726
+ kind: "media",
727
+ media: video,
728
+ targetLatency: lastKnownTargetLatency ?? void 0,
729
+ lowLatency: lastLiveMetrics?.lowLatency
730
+ }) : null;
731
+ if (metrics) {
732
+ lastLiveMetrics = metrics;
733
+ if (hls && !isNative) lastKnownTargetLatency = metrics.targetLatency;
734
+ }
735
+ return metrics;
736
+ };
614
737
  const applyPoster = () => {
615
738
  if (!video) return;
616
739
  video.poster = api?.getState("poster") || "";
@@ -660,6 +783,10 @@ function createHLSPluginWith(loader, variant, config) {
660
783
  mediaRetryCount = 0;
661
784
  errorCount = 0;
662
785
  errorWindowStart = 0;
786
+ lastLevelDetails = null;
787
+ lastLiveMetrics = null;
788
+ lastKnownTargetLatency = null;
789
+ if (api) resetLiveMetrics(api);
663
790
  };
664
791
  const buildHlsConfig = () => {
665
792
  const config2 = buildBaseHlsConfig();
@@ -671,27 +798,58 @@ function createHLSPluginWith(loader, variant, config) {
671
798
  }
672
799
  return config2;
673
800
  };
674
- const buildBaseHlsConfig = () => ({
675
- debug: mergedConfig.debug,
676
- autoStartLoad: mergedConfig.autoStartLoad,
677
- startPosition: mergedConfig.startPosition,
678
- startLevel: -1,
679
- // Auto quality selection (ABR)
680
- abrEwmaDefaultEstimate: getInitialBandwidthEstimate(mergedConfig.initialBandwidthEstimate),
681
- lowLatencyMode: mergedConfig.lowLatencyMode,
682
- maxBufferLength: mergedConfig.maxBufferLength,
683
- maxMaxBufferLength: mergedConfig.maxMaxBufferLength,
684
- backBufferLength: mergedConfig.backBufferLength,
685
- enableWorker: mergedConfig.enableWorker,
686
- capLevelToPlayerSize: mergedConfig.capLevelToPlayerSize,
687
- // Minimize hls.js internal retries - we handle retries ourselves
688
- fragLoadingMaxRetry: 1,
689
- manifestLoadingMaxRetry: 1,
690
- levelLoadingMaxRetry: 1,
691
- fragLoadingRetryDelay: 500,
692
- manifestLoadingRetryDelay: 500,
693
- levelLoadingRetryDelay: 500
694
- });
801
+ const buildLiveHlsConfig = () => {
802
+ const live = {};
803
+ const set = (key, value) => {
804
+ if (value !== void 0) live[key] = value;
805
+ };
806
+ const syncDuration = mergedConfig.liveSyncDuration;
807
+ const syncCount = mergedConfig.liveSyncDurationCount;
808
+ const maxDuration = mergedConfig.liveMaxLatencyDuration;
809
+ const maxCount = mergedConfig.liveMaxLatencyDurationCount;
810
+ const mixed = (syncDuration !== void 0 || maxDuration !== void 0) && (syncCount !== void 0 || maxCount !== void 0);
811
+ const dropCount = mixed && syncDuration !== void 0;
812
+ const dropDuration = mixed && !dropCount;
813
+ if (mixed) {
814
+ api?.logger.warn(
815
+ `Ignoring ${dropCount ? "liveSyncDurationCount/liveMaxLatencyDurationCount" : "liveSyncDuration/liveMaxLatencyDuration"}: hls.js rejects a config mixing seconds-based and count-based live latency options`
816
+ );
817
+ }
818
+ set("liveSyncDuration", dropDuration ? void 0 : syncDuration);
819
+ set("liveSyncDurationCount", dropCount ? void 0 : syncCount);
820
+ set("liveMaxLatencyDuration", dropDuration ? void 0 : maxDuration);
821
+ set("liveMaxLatencyDurationCount", dropCount ? void 0 : maxCount);
822
+ set("liveDurationInfinity", mergedConfig.liveDurationInfinity);
823
+ set(
824
+ "maxLiveSyncPlaybackRate",
825
+ mergedConfig.maxLiveSyncPlaybackRate ?? (mergedConfig.lowLatencyMode === true ? LL_CATCH_UP_PLAYBACK_RATE : void 0)
826
+ );
827
+ return live;
828
+ };
829
+ const buildBaseHlsConfig = () => {
830
+ return {
831
+ debug: mergedConfig.debug,
832
+ autoStartLoad: mergedConfig.autoStartLoad,
833
+ startPosition: mergedConfig.startPosition,
834
+ startLevel: -1,
835
+ // Auto quality selection (ABR)
836
+ abrEwmaDefaultEstimate: getInitialBandwidthEstimate(mergedConfig.initialBandwidthEstimate),
837
+ lowLatencyMode: mergedConfig.lowLatencyMode,
838
+ maxBufferLength: mergedConfig.maxBufferLength,
839
+ maxMaxBufferLength: mergedConfig.maxMaxBufferLength,
840
+ backBufferLength: mergedConfig.backBufferLength,
841
+ enableWorker: mergedConfig.enableWorker,
842
+ capLevelToPlayerSize: mergedConfig.capLevelToPlayerSize,
843
+ // Minimize hls.js internal retries - we handle retries ourselves
844
+ fragLoadingMaxRetry: 1,
845
+ manifestLoadingMaxRetry: 1,
846
+ levelLoadingMaxRetry: 1,
847
+ fragLoadingRetryDelay: 500,
848
+ manifestLoadingRetryDelay: 500,
849
+ levelLoadingRetryDelay: 500,
850
+ ...buildLiveHlsConfig()
851
+ };
852
+ };
695
853
  const getRetryDelay = (retryCount) => {
696
854
  const baseDelay = mergedConfig.retryDelayMs ?? 1e3;
697
855
  const backoffFactor = mergedConfig.retryBackoffFactor ?? 2;
@@ -888,7 +1046,7 @@ function createHLSPluginWith(loader, variant, config) {
888
1046
  const videoEl = getOrCreateVideo();
889
1047
  isNative = true;
890
1048
  if (api) {
891
- cleanupVideoEvents = setupVideoEventHandlers(videoEl, api);
1049
+ cleanupVideoEvents = setupVideoEventHandlers(videoEl, api, readLiveMetrics);
892
1050
  }
893
1051
  return new Promise((resolve, reject) => {
894
1052
  let watchdog = null;
@@ -981,7 +1139,7 @@ function createHLSPluginWith(loader, variant, config) {
981
1139
  isNative = false;
982
1140
  hls = loader.createHlsInstance(buildHlsConfig());
983
1141
  if (api) {
984
- cleanupVideoEvents = setupVideoEventHandlers(videoEl, api);
1142
+ cleanupVideoEvents = setupVideoEventHandlers(videoEl, api, readLiveMetrics);
985
1143
  }
986
1144
  return new Promise((resolve, reject) => {
987
1145
  if (!hls || !api) {
@@ -1023,6 +1181,12 @@ function createHLSPluginWith(loader, variant, config) {
1023
1181
  },
1024
1182
  onLevelSwitched: () => {
1025
1183
  },
1184
+ onLevelDetails: (details) => {
1185
+ if (session !== loadSession) return;
1186
+ lastLevelDetails = details;
1187
+ readLiveMetrics();
1188
+ },
1189
+ isLowLatencyRequested: () => mergedConfig.lowLatencyMode === true,
1026
1190
  onError: (error) => {
1027
1191
  if (session !== loadSession) return;
1028
1192
  const terminal = handleHlsError(error);
@@ -1460,25 +1624,45 @@ function createHLSPluginWith(loader, variant, config) {
1460
1624
  isNativeHLS() {
1461
1625
  return isNative;
1462
1626
  },
1627
+ /**
1628
+ * Report the live state of the stream.
1629
+ *
1630
+ * `latency` and `targetLatency` come from hls.js on the MSE path, where
1631
+ * they are measured against `EXT-X-PROGRAM-DATE-TIME` drift when the
1632
+ * manifest carries it. On the native path there is no latency API, so both
1633
+ * are approximations: latency is the distance to `seekable.end`, and the
1634
+ * target is whatever an earlier hls.js session on this source measured
1635
+ * (an AirPlay handoff) before it falls back to 3 seconds. Parking a viewer
1636
+ * of a 2-second-target stream 3 seconds back was the previous behaviour,
1637
+ * and it is a full target latency of drift.
1638
+ *
1639
+ * @returns Live info, or null for VOD and before a pipeline exists
1640
+ */
1463
1641
  getLiveInfo() {
1464
1642
  const live = api?.getState("live") || false;
1465
1643
  if (!live) return null;
1644
+ const metrics = readLiveMetrics();
1466
1645
  if (isNative) {
1646
+ const targetLatency2 = metrics?.targetLatency ?? DEFAULT_TARGET_LATENCY;
1647
+ const seekableEnd = video?.seekable?.length ? video.seekable.end(video.seekable.length - 1) : void 0;
1467
1648
  return {
1468
1649
  isLive: true,
1469
- latency: 0,
1470
- targetLatency: 3,
1650
+ latency: metrics?.latency ?? 0,
1651
+ targetLatency: targetLatency2,
1471
1652
  drift: 0,
1472
- liveSyncPosition: video?.seekable?.length ? Math.max(0, video.seekable.end(video.seekable.length - 1) - 3) : void 0
1653
+ liveSyncPosition: seekableEnd !== void 0 ? Math.max(0, seekableEnd - targetLatency2) : void 0,
1654
+ lowLatency: metrics?.lowLatency ?? false
1473
1655
  };
1474
1656
  }
1475
1657
  if (!hls) return null;
1658
+ const targetLatency = hls.targetLatency || metrics?.targetLatency || DEFAULT_TARGET_LATENCY;
1476
1659
  return {
1477
1660
  isLive: true,
1478
1661
  latency: hls.latency || 0,
1479
- targetLatency: hls.targetLatency || 3,
1662
+ targetLatency,
1480
1663
  drift: hls.drift || 0,
1481
- liveSyncPosition: hls.liveSyncPosition ?? (video?.seekable?.length ? Math.max(0, video.seekable.end(video.seekable.length - 1) - 3) : void 0)
1664
+ liveSyncPosition: hls.liveSyncPosition ?? (video?.seekable?.length ? Math.max(0, video.seekable.end(video.seekable.length - 1) - targetLatency) : void 0),
1665
+ lowLatency: metrics?.lowLatency ?? false
1482
1666
  };
1483
1667
  },
1484
1668
  /**
@@ -1503,10 +1687,12 @@ function createHLSPluginWith(loader, variant, config) {
1503
1687
  const wasPlaying = api?.getState("playing") || false;
1504
1688
  const currentTime = video?.currentTime || 0;
1505
1689
  const savedSrc = currentSrc;
1690
+ const savedTargetLatency = lastKnownTargetLatency;
1506
1691
  const session = ++loadSession;
1507
1692
  cancelReconnect();
1508
1693
  cleanup(new Error("HLS load cancelled: switching to native HLS"));
1509
1694
  currentSrc = savedSrc;
1695
+ lastKnownTargetLatency = savedTargetLatency;
1510
1696
  await loadNative(savedSrc);
1511
1697
  if (session !== loadSession) return;
1512
1698
  if (video && currentTime > 0) {
@@ -1542,10 +1728,12 @@ function createHLSPluginWith(loader, variant, config) {
1542
1728
  const wasPlaying = api?.getState("playing") || false;
1543
1729
  const currentTime = video?.currentTime || 0;
1544
1730
  const savedSrc = currentSrc;
1731
+ const savedTargetLatency = lastKnownTargetLatency;
1545
1732
  const session = ++loadSession;
1546
1733
  cancelReconnect();
1547
1734
  cleanup(new Error("HLS load cancelled: switching to hls.js"));
1548
1735
  currentSrc = savedSrc;
1736
+ lastKnownTargetLatency = savedTargetLatency;
1549
1737
  await loadWithHlsJs(savedSrc);
1550
1738
  if (session !== loadSession) return;
1551
1739
  if (video && currentTime > 0) {
@@ -1580,6 +1768,8 @@ function createHLSPlugin(config) {
1580
1768
  var light_default = createHLSPlugin;
1581
1769
  // Annotate the CommonJS export names for ESM import in node:
1582
1770
  0 && (module.exports = {
1771
+ DEFAULT_TARGET_LATENCY,
1772
+ computeLiveMetrics,
1583
1773
  createHLSPlugin,
1584
1774
  sanitizeUrl
1585
1775
  });
package/dist/light.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HLSPluginConfig, I as IHLSPlugin } from './types-DnvcTuSn.cjs';
2
- export { b as HLSError, c as HLSLiveInfo, a as HLSQualityLevel } from './types-DnvcTuSn.cjs';
1
+ import { H as HLSPluginConfig, I as IHLSPlugin } from './live-metrics-CoYkWhl5.cjs';
2
+ export { D as DEFAULT_TARGET_LATENCY, b as HLSError, c as HLSLiveInfo, a as HLSQualityLevel, f as HlsLevelDetails, L as LiveMetrics, e as LiveMetricsSource, d as computeLiveMetrics } from './live-metrics-CoYkWhl5.cjs';
3
3
  export { sanitizeUrl } from '@scarlett-player/core';
4
4
 
5
5
  /**
package/dist/light.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HLSPluginConfig, I as IHLSPlugin } from './types-DnvcTuSn.js';
2
- export { b as HLSError, c as HLSLiveInfo, a as HLSQualityLevel } from './types-DnvcTuSn.js';
1
+ import { H as HLSPluginConfig, I as IHLSPlugin } from './live-metrics-CoYkWhl5.js';
2
+ export { D as DEFAULT_TARGET_LATENCY, b as HLSError, c as HLSLiveInfo, a as HLSQualityLevel, f as HlsLevelDetails, L as LiveMetrics, e as LiveMetricsSource, d as computeLiveMetrics } from './live-metrics-CoYkWhl5.js';
3
3
  export { sanitizeUrl } from '@scarlett-player/core';
4
4
 
5
5
  /**
package/dist/light.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import {
2
+ DEFAULT_TARGET_LATENCY,
2
3
  __export,
4
+ computeLiveMetrics,
3
5
  createHLSPluginWith,
4
6
  sanitizeUrl
5
- } from "./chunk-NVPSLRJY.js";
7
+ } from "./chunk-47MU7IVX.js";
6
8
 
7
9
  // src/hls-loader-light.ts
8
10
  var hls_loader_light_exports = {};
@@ -85,6 +87,8 @@ function createHLSPlugin(config) {
85
87
  }
86
88
  var light_default = createHLSPlugin;
87
89
  export {
90
+ DEFAULT_TARGET_LATENCY,
91
+ computeLiveMetrics,
88
92
  createHLSPlugin,
89
93
  light_default as default,
90
94
  sanitizeUrl