@torrent-tv/proxy 2.107.31 → 2.107.32

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.31",
3
+ "version": "2.107.32",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -134,7 +134,8 @@ export class RateTrend {
134
134
  * @param {Array<{ id: string, serviceKey?: string, complete: boolean, fileOffset?: number,
135
135
  * fileLength?: number, bytesPerMediaSecond?: number, pieceLength?: number, downloadRateReadings?: object,
136
136
  * downloadForecast?: { ranges: Array<{ start: number, end: number, availableAt: number | null }> } }>} input.sources
137
- * @param {Array<{ id: string, sourceIds: string[], processedSeconds: number,
137
+ * @param {Array<{ id: string, sourceIds: string[], processedSeconds: number, durationSeconds?: number,
138
+ * segmentCount?: number,
138
139
  * bitsPerMediaSecond: number, readings: Array<{ at: number, value: number }>,
139
140
  * clockOffsetSeconds?: number, clientRanges?: Array<{ start: number, end: number }>,
140
141
  * segments: Array<{ index: number, startSeconds: number, endSeconds: number,
@@ -244,6 +245,25 @@ export function predictPlaybackReadiness(input = {}) {
244
245
  for (const state of trackState) {
245
246
  state.trackEndSeconds = Math.min(duration, state.durationSeconds + state.clockSeconds);
246
247
  }
248
+ // A file can declare a duration longer than its last packet. The HLS VOD
249
+ // playlist still has a final numbered piece, but its made fragment ends at
250
+ // the output's actual last frame. Waiting for the declaration then asks the
251
+ // source for media after EOF. The final piece and the browser's contiguous
252
+ // held range together are positive evidence of the terminal output: require
253
+ // both on every track the viewer must play.
254
+ const finishedOutputHeld = measured && trackState.slice(0, requiredTracks).every((state, index) => {
255
+ const count = Number(state.track.segmentCount);
256
+ if (!Number.isSafeInteger(count) || count <= 0 || !state.ready.has(count - 1)) return false;
257
+ const last = state.segments.find(segment => segment.index === count - 1);
258
+ if (!Array.isArray(last?.ranges) || last.ranges.length === 0) return false;
259
+ const heldEnd = contiguousEnd(measuredRanges[index], at);
260
+ if (!heldEnd) return false;
261
+ const outputEnd = latest(...last.ranges.map(range => range.end));
262
+ return compare(heldEnd, outputEnd) >= 0;
263
+ });
264
+ if (finishedOutputHeld) {
265
+ return result(true, 0, buffered, reserve, 0, "client-buffer-covers-end", 0);
266
+ }
247
267
  if (trackState.some(({ segments }) => segments.length === 0)) {
248
268
  return result(false, null, buffered, reserve, null, "timeline-unavailable", 0);
249
269
  }