@torrent-tv/proxy 2.107.9 → 2.107.11

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.9",
3
+ "version": "2.107.11",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -41,8 +41,11 @@ export function buildAdmittedCommand({ admittedInput, timeline, output, segmentF
41
41
  }
42
42
  else video.push("-vf", trim);
43
43
  }
44
+ const audioTrack = admittedInput.tracks?.find(input => input.track.type === "audio")?.track;
45
+ const audioSampleRate = [audioTrack?.samplingFrequency, audioTrack?.codecParameters?.sampleRate]
46
+ .find(sampleRate => Number.isSafeInteger(sampleRate) && sampleRate > 0) ?? 48000;
44
47
  const audio = transcodeAudio ? ["-c:a", "aac", "-ac", "2", "-b:a", `${AUDIO_TRANSCODE_KBPS}k`,
45
- "-af", `atrim=start=${ffmpegSeconds(relativeStart)}:end=${ffmpegSeconds(relativeEnd)}`] : ["-c:a", "copy"];
48
+ "-af", `atrim=start=${ffmpegSeconds(relativeStart)}:end=${ffmpegSeconds(relativeEnd)},aresample=async=1:first_pts=${Math.round(relativeStart * audioSampleRate)}`] : ["-c:a", "copy"];
46
49
  if (audioOnly) args.push("-vn", "-map", "0:a:0", ...audio);
47
50
  else if (audioSeparate) args.push("-an", "-map", "0:v:0", ...video);
48
51
  else args.push("-map", "0:v:0", "-map", "0:a:0?", ...video, ...audio);
@@ -14,6 +14,7 @@ const LANGUAGES = "7c4346a9efe0fc4bb229393ede415c85";
14
14
  const AUDIO = "409e69f84d5bcf11a8fd00805f5c442b";
15
15
  const VIDEO = "c0ef19bc4d5bcf11a8fd00805f5c442b";
16
16
  const ENCRYPTION = new Set(["fbb3112223bdd211b4b700a0c955fc6e", "14e68a292226174cb935dae07e9e28c9"]);
17
+ const VIDEO_CODECS_WITHOUT_COPYABLE_BROWSER_OUTPUT = new Set(["WMV1", "WMV2", "WMV3", "WMVA", "WMVP", "WVC1"]);
17
18
  const AUDIO_CODECS = new Map([[1, "pcm_s16le"], [0x55, "mp3"], [0xff, "aac"],
18
19
  [0x160, "wmav1"], [0x161, "wmav2"], [0x162, "wmapro"], [0x163, "wmalossless"], [0x2000, "ac3"]]);
19
20
 
@@ -198,9 +199,18 @@ export class AsfContainer extends Container {
198
199
  return this.#info;
199
200
  }
200
201
  async parseKeyframeIndex() {
201
- const index = await this.readPacketIndex();
202
+ await this.#readHeader();
202
203
  const track = this.#tracks.find(track => track.type === "video");
203
- return track ? { times: index.keyframesOf(track.trackNumber), tolerance: 0 } : null;
204
+ if (!track) return null;
205
+ // These ASF picture codecs require re-encoding for browser playback. A
206
+ // packet walk cannot help that output, and retaining every packet until the
207
+ // whole file has been scanned competes with the bounded reads that produce
208
+ // its first segments. The output path already places its own keyframes.
209
+ if (VIDEO_CODECS_WITHOUT_COPYABLE_BROWSER_OUTPUT.has(track.codecId.toUpperCase())) {
210
+ return { times: [], tolerance: 0, copyable: false };
211
+ }
212
+ const index = await this.readPacketIndex();
213
+ return { times: index.keyframesOf(track.trackNumber), tolerance: 0 };
204
214
  }
205
215
  async readPacketIndex(interval) {
206
216
  await this.#readHeader();