@torrent-tv/proxy 2.107.18 → 2.107.19

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.18",
3
+ "version": "2.107.19",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -301,7 +301,7 @@ export function predictPlaybackReadiness(input = {}) {
301
301
  return result(false, null, buffered, reserve, null, "link-rate-unavailable", 0);
302
302
  }
303
303
 
304
- const preparedSegments = trackState.reduce((sum, { ready, segments, tail }) =>
304
+ let preparedSegments = trackState.reduce((sum, { ready, segments, tail }) =>
305
305
  sum + segments.filter((segment) => ready.has(segment.index)).length +
306
306
  tail.filter((segment) => ready.has(segment.index)).length, 0);
307
307
  const jobs = [];
@@ -309,6 +309,7 @@ export function predictPlaybackReadiness(input = {}) {
309
309
  for (let trackIndex = 0; trackIndex < trackState.length; trackIndex += 1) {
310
310
  const state = trackState[trackIndex];
311
311
  const { track, segments } = state;
312
+ const safeThrough = position + finiteNonNegative(input.bufferedAheadSeconds) + reserve;
312
313
  const processingCoverage = numericCoverage((Array.isArray(track.processingRanges) ? track.processingRanges : [])
313
314
  .filter(range => Number.isFinite(range?.start) && Number.isFinite(range?.end) && range.end > range.start));
314
315
  const measuredBitsPerMediaSecond = state.bitsPerMediaSecond;
@@ -344,6 +345,7 @@ export function predictPlaybackReadiness(input = {}) {
344
345
  const encodeWork = produced ? 0 : remainingProcessing.reduce((sum, part) => sum + part.end - part.start, 0);
345
346
 
346
347
  let sourceByteIntervals = NO_SOURCE_BYTES;
348
+ let deferredAtBoundary = false;
347
349
  if (!produced && encodeWork > 0) {
348
350
  // Each source the piece reads, in order and once: the track's own, then
349
351
  // those its inputs name. Gathered with loops and no copies, because
@@ -362,6 +364,15 @@ export function predictPlaybackReadiness(input = {}) {
362
364
  } else if (source.source.complete !== true) {
363
365
  const ranges = exactInputs ? inputRangesOf(exactInputs, sourceId) : null;
364
366
  if (ranges === null) {
367
+ if (segment.startSeconds + state.clockSeconds > safeThrough) {
368
+ // Its source ranges lie beyond the browser's held buffer and
369
+ // reserve. The playback map will request them as the viewer
370
+ // advances; continuing to demand them here prevents startup.
371
+ state.segments = state.segments.slice(0, state.segments.indexOf(segment));
372
+ state.tail = [];
373
+ deferredAtBoundary = true;
374
+ break;
375
+ }
365
376
  if (unknownReason === null) {
366
377
  unknownReason = "source-input-ranges-unavailable";
367
378
  unavailableSource = { sourceId, trackId: track.id, segmentIndex: segment.index, phase: "near" };
@@ -373,6 +384,7 @@ export function predictPlaybackReadiness(input = {}) {
373
384
  }
374
385
  }
375
386
  }
387
+ if (deferredAtBoundary) break;
376
388
  if (!produced && encodeWork > 0 && !state.curve) {
377
389
  unknownReason ??= "encode-rate-unavailable";
378
390
  }
@@ -389,6 +401,10 @@ export function predictPlaybackReadiness(input = {}) {
389
401
  }
390
402
  }
391
403
 
404
+ preparedSegments = trackState.reduce((sum, { ready, segments, tail }) =>
405
+ sum + segments.filter((segment) => ready.has(segment.index)).length +
406
+ tail.filter((segment) => ready.has(segment.index)).length, 0);
407
+
392
408
  if (unknownReason) {
393
409
  return { ...result(false, null, buffered, reserve, null, unknownReason, preparedSegments),
394
410
  ...(unavailableSource ? { unavailableSource } : {}) };