@torrent-tv/proxy 2.99.17 → 2.99.18

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.99.17",
3
+ "version": "2.99.18",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -834,6 +834,17 @@ export class MatroskaContainer extends Container {
834
834
  const declared = new Map([[id, track]]);
835
835
  const asked = interval ? { ...interval, trackIds: [id] } : null;
836
836
  const depth = track.type === "video" ? track.reorderDepth : 0;
837
+ // WHERE THE WALK WILL READ, as the Cues name it (`packetWalkRanges`):
838
+ // read a portion at a time across cluster boundaries too. Read a
839
+ // cluster's header and its contents apart, a soundtrack piece took
840
+ // about sixteen reads of the torrent thread, each waiting for its loop
841
+ // (0.5-0.8 s late on Home Assistant), and 7-12 s to prepare with every
842
+ // byte held (r56, torrent-tv/meta#178).
843
+ const walked = interval ? await this.packetWalkRanges(interval) : null;
844
+ const readsThrough = walked ? start => {
845
+ const range = walked.ranges.find(([from, to]) => from <= start && start <= to);
846
+ return range ? range[1] + 1 : null;
847
+ } : null;
837
848
  let current = null;
838
849
  const covered = () => {
839
850
  if (!asked) return false;
@@ -851,7 +862,7 @@ export class MatroskaContainer extends Container {
851
862
  const following = readings.find(reading => reading.startAt > current.startAt);
852
863
  const outcome = await walkMatroskaPackets({ readRange: this.readRange, fileSize: this.fileSize,
853
864
  portionBytes: this.portionBytes, layout, tracks, trackIds: [id], interval, packetMemory: this.packetMemory,
854
- state: current, until: following?.startAt ?? null, isCovered: covered });
865
+ state: current, until: following?.startAt ?? null, isCovered: covered, readsThrough });
855
866
  if (outcome !== "until") break;
856
867
  current.next = following;
857
868
  }
@@ -40,9 +40,13 @@ function recordedTracks(tracks, trackIds) {
40
40
  * Only the named tracks are recorded: a soundtrack read on its own kept the
41
41
  * picture's table as well, half of 37.9 MB on r47's order (torrent-tv/meta#178).
42
42
  *
43
+ * `readsThrough(start)` is one past the last byte the walk will read from
44
+ * `start` on, where the caller knows it: those are read a portion at a time
45
+ * across clusters too.
46
+ *
43
47
  * @returns {Promise<"covered" | "until" | "end">}
44
48
  */
45
- export async function walkMatroskaPackets({ readRange, fileSize, portionBytes, layout, tracks, trackIds, interval, packetMemory, state, until = null, isCovered = null }) {
49
+ export async function walkMatroskaPackets({ readRange, fileSize, portionBytes, layout, tracks, trackIds, interval, packetMemory, state, until = null, isCovered = null, readsThrough = null }) {
46
50
  // INSIDE A CLUSTER EVERY BLOCK HEADER IS READ, so its bytes are read a
47
51
  // portion at a time up to the cluster's end, and never past it. Read a
48
52
  // header at a time, each a read of a few bytes from the torrent thread, the
@@ -55,7 +59,7 @@ export async function walkMatroskaPackets({ readRange, fileSize, portionBytes, l
55
59
  // Between clusters only their headers are read.
56
60
  let readableUntil = null;
57
61
  const reader = new ElementReader({ read: readRange, fileSize, portionBytes, prefetch: true,
58
- readableUntil: start => readableUntil ?? start });
62
+ readableUntil: start => Math.max(readableUntil ?? start, readsThrough?.(start) ?? start) });
59
63
  const declared = recordedTracks(tracks, trackIds);
60
64
  if (!state.packets) {
61
65
  state.packets = new Map([...declared.keys()].map(id => [id, new PacketRecords(packetMemory)]));