@torrent-tv/proxy 2.59.1 → 2.59.3
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/CHANGELOG.md +12 -3
- package/package.json +1 -1
- package/services/ffmpeg-banner.js +48 -0
- package/services/hls-session-manager.js +9345 -9195
- package/test/ffmpeg-stream-counts.test.js +78 -0
- package/test/quality-variants.test.js +981 -862
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file What the source said it holds, read from ffmpeg's own banner.
|
|
3
|
+
*
|
|
4
|
+
* The reading exists for one failure: every `-map` this proxy builds ends in
|
|
5
|
+
* `?`, so ffmpeg drops a mapping for a stream that is not there and says
|
|
6
|
+
* nothing. Map every stream of a run away that way and the output has nothing
|
|
7
|
+
* in it — `Output file does not contain any stream`, exit 255. Three sessions
|
|
8
|
+
* died that way on 2026-08-26 and the log held only the code.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import test from "node:test";
|
|
13
|
+
|
|
14
|
+
import { parseFfmpegStreamCounts } from "../services/ffmpeg-banner.js";
|
|
15
|
+
|
|
16
|
+
const FIELD_BANNER = `
|
|
17
|
+
Input #0, matroska,webm, from 'http://127.0.0.1:9090/stream?sourceKey=b3f08efc':
|
|
18
|
+
Duration: 01:32:39.00, start: 0.000000, bitrate: 9354 kb/s
|
|
19
|
+
Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1080, 23.98 fps
|
|
20
|
+
Stream #0:1(rus): Audio: ac3, 48000 Hz, 5.1, fltp, 640 kb/s
|
|
21
|
+
Stream #0:2(eng): Audio: aac, 48000 Hz, stereo, fltp, 128 kb/s
|
|
22
|
+
Stream #0:3(rus): Subtitle: subrip
|
|
23
|
+
Stream #0:4(eng): Subtitle: hdmv_pgs_subtitle
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
test("each stream is counted under the type ffmpeg names it", () => {
|
|
27
|
+
assert.deepEqual(parseFfmpegStreamCounts(FIELD_BANNER), {
|
|
28
|
+
video: 1,
|
|
29
|
+
audio: 2,
|
|
30
|
+
subtitle: 2,
|
|
31
|
+
other: 0
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("a file with no audio is what makes an audio-only run produce nothing", () => {
|
|
36
|
+
// This is the shape the diagnostic is for: the rendition asks for `0:a:0?`,
|
|
37
|
+
// the file has no audio at all, the mapping is dropped in silence and the
|
|
38
|
+
// segment muxer is handed an output with no streams.
|
|
39
|
+
const counts = parseFfmpegStreamCounts(`
|
|
40
|
+
Stream #0:0: Video: hevc (Main 10), yuv420p10le, 3840x2160, 23.98 fps
|
|
41
|
+
`);
|
|
42
|
+
assert.equal(counts.audio, 0);
|
|
43
|
+
assert.equal(counts.video, 1);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("an audio index past the end of the list is OUR fault, and the counts say so", () => {
|
|
47
|
+
// A viewer picking the third dub on a file carrying one: `0:a:2?` drops, and
|
|
48
|
+
// the count is what separates that from a source that delivered nothing.
|
|
49
|
+
const counts = parseFfmpegStreamCounts(FIELD_BANNER);
|
|
50
|
+
const askedFor = 4;
|
|
51
|
+
assert.ok(askedFor >= counts.audio, "the request is outside what the file holds");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("an attached cover image is counted as video, because that is what would be mapped", () => {
|
|
55
|
+
const counts = parseFfmpegStreamCounts(`
|
|
56
|
+
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
|
|
57
|
+
Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc), 600x600 (attached pic)
|
|
58
|
+
`);
|
|
59
|
+
assert.equal(counts.video, 1);
|
|
60
|
+
assert.equal(counts.audio, 1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("a banner carrying no stream lines is not the same as a file with no streams", () => {
|
|
64
|
+
// Null says "not recorded"; zeroes would claim a measurement nobody took.
|
|
65
|
+
assert.equal(parseFfmpegStreamCounts("Duration: 00:10:00.00, start: 0.000000"), null);
|
|
66
|
+
assert.equal(parseFfmpegStreamCounts(""), null);
|
|
67
|
+
assert.equal(parseFfmpegStreamCounts(undefined), null);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("a stream carrying metadata in brackets is still read", () => {
|
|
71
|
+
// MP4 writes `Stream #0:1[0x2](eng)`, which the earlier shape of this regex
|
|
72
|
+
// would have skipped.
|
|
73
|
+
const counts = parseFfmpegStreamCounts(`
|
|
74
|
+
Stream #0:0[0x1](und): Video: h264 (avc1), yuv420p, 1280x720, 24 fps
|
|
75
|
+
Stream #0:1[0x2](eng): Audio: aac (mp4a), 48000 Hz, stereo, fltp
|
|
76
|
+
`);
|
|
77
|
+
assert.deepEqual(counts, { video: 1, audio: 1, subtitle: 0, other: 0 });
|
|
78
|
+
});
|