@torrent-tv/proxy 2.107.22 → 2.107.23

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.107.22",
3
+ "version": "2.107.23",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -552,7 +552,9 @@ export function predictPlaybackReadiness(input = {}) {
552
552
  let after = contiguousEnd(delivered, at);
553
553
  for (const completion of completions.filter((item) => item.trackIndex === trackIndex)) {
554
554
  const before = after;
555
- for (const range of completion.segment.ranges) addMediaRange(delivered, range);
555
+ const ranges = compare(before, at) === 0
556
+ ? withSeekStartTolerance(completion.segment.ranges, at, unit) : completion.segment.ranges;
557
+ for (const range of ranges) addMediaRange(delivered, range);
556
558
  after = contiguousEnd(delivered, at);
557
559
  const ahead = secondsAhead(earliest(before, trackEnd), at);
558
560
  constrain(completion.at - ahead, "delivery", trackIndex, completion.segment.index, completion.at, ahead, false,
@@ -581,7 +583,9 @@ export function predictPlaybackReadiness(input = {}) {
581
583
  }
582
584
  for (const production of productions.filter((item) => item.trackIndex === trackIndex)) {
583
585
  const before = contiguousEnd(prepared, at);
584
- for (const range of production.segment.ranges) addMediaRange(prepared, range);
586
+ const ranges = compare(before, at) === 0
587
+ ? withSeekStartTolerance(production.segment.ranges, at, unit) : production.segment.ranges;
588
+ for (const range of ranges) addMediaRange(prepared, range);
585
589
  // Supply interruption coverage is stock held by the proxy as well as
586
590
  // the browser. It is not a browser buffer-size admission rule.
587
591
  // The reserve is bounded by what is left of the track, not of the window.
@@ -851,6 +855,25 @@ function heldRanges(ranges, segments, unit, position) {
851
855
  return held;
852
856
  }
853
857
 
858
+ /**
859
+ * Include the first arriving range when its start is within the media
860
+ * element's allowance for a seek target. This does not bridge later gaps.
861
+ *
862
+ * @param {import("./media-time.js").MediaRange[]} ranges
863
+ * @param {import("./media-time.js").MediaTime} position
864
+ * @param {bigint} unit
865
+ * @returns {import("./media-time.js").MediaRange[]}
866
+ */
867
+ function withSeekStartTolerance(ranges, position, unit) {
868
+ const first = ranges.reduce((earliestRange, range) =>
869
+ !earliestRange || compare(range.start, earliestRange.start) < 0 ? range : earliestRange, null);
870
+ const toleranceEnd = add(position, rescale(fromSeconds(CLIENT_RANGE_START_TOLERANCE_SECONDS), unit));
871
+ if (!first || compare(first.start, position) <= 0 || compare(first.start, toleranceEnd) > 0) {
872
+ return ranges;
873
+ }
874
+ return ranges.map((range) => range === first ? { ...range, start: position } : range);
875
+ }
876
+
854
877
  /**
855
878
  * The pieces of a track this forecast places in exact time: those still to
856
879
  * play (ending after `position`) that start before `horizonEnd`, the first