Skip to content

Commit 5c56175

Browse files
committed
feat: add self-hosted HLS test stream for integration tests
- Add tiny 4-second HLS stream to GitHub Pages (~40KB total) - Update integration tests to use local stream by default - Download test now completes in ~5 seconds instead of timing out The test stream is generated with: ffmpeg -f lavfi -i 'color=c=blue:s=320x240:d=4' ...
1 parent 0bd826c commit 5c56175

File tree

6 files changed

+39
-30
lines changed

6 files changed

+39
-30
lines changed

docs/test-stream/playlist.m3u8

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#EXTM3U
2+
#EXT-X-VERSION:6
3+
#EXT-X-TARGETDURATION:2
4+
#EXT-X-MEDIA-SEQUENCE:0
5+
#EXT-X-INDEPENDENT-SEGMENTS
6+
#EXTINF:1.920000,
7+
seg0.ts
8+
#EXTINF:0.960000,
9+
seg1.ts
10+
#EXTINF:0.960000,
11+
seg2.ts
12+
#EXTINF:0.160000,
13+
seg3.ts
14+
#EXT-X-ENDLIST

docs/test-stream/seg0.ts

19.6 KB
Binary file not shown.

docs/test-stream/seg1.ts

9.55 KB
Binary file not shown.

docs/test-stream/seg2.ts

9.73 KB
Binary file not shown.

docs/test-stream/seg3.ts

2.2 KB
Binary file not shown.

src/downloader/hlsDownloader.integration.test.ts

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* These tests require:
55
* - ffmpeg installed and in PATH
6-
* - Network access (for real HLS streams)
6+
* - Network access (for HLS streams)
77
* - Temp directory for output files
88
*
99
* Run with: npm run test:integration
@@ -15,16 +15,15 @@ import { join } from "node:path";
1515
import { afterAll, beforeAll, describe, expect, it } from "vitest";
1616
import { checkFfmpeg, downloadHLSVideo, fetchHLSQualities } from "./hlsDownloader.js";
1717

18-
// Test fixtures - public HLS streams for testing
18+
// Test fixtures - HLS streams for testing
1919
const TEST_STREAMS = {
20-
// Apple's bipbop master playlist (for quality detection)
20+
// Our own tiny test stream hosted on GitHub Pages (~40KB, 4 seconds)
21+
local: "https://sebastian-software.github.io/offcourse/test-stream/playlist.m3u8",
22+
// Apple's bipbop master playlist (for quality detection, has multiple qualities)
2123
bipbopMaster:
2224
"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8",
2325
};
2426

25-
// Full download tests are slow - skip in CI unless explicitly enabled
26-
const RUN_SLOW_TESTS = process.env.INTEGRATION_SLOW === "true";
27-
2827
describe("HLS Downloader Integration", () => {
2928
let tempDir: string;
3029

@@ -84,29 +83,25 @@ describe("HLS Downloader Integration", () => {
8483
expect(result.errorCode).toBeDefined();
8584
}, 15000);
8685

87-
// Full download test - only run when INTEGRATION_SLOW=true
88-
it.skipIf(!RUN_SLOW_TESTS)(
89-
"should download complete HLS stream (slow, set INTEGRATION_SLOW=true)",
90-
async () => {
91-
const outputPath = join(tempDir, "test-video.mp4");
92-
93-
const progressUpdates: number[] = [];
94-
const result = await downloadHLSVideo(TEST_STREAMS.bipbopMaster, outputPath, (progress) => {
95-
progressUpdates.push(progress.percent);
96-
});
97-
98-
expect(result.success).toBe(true);
99-
expect(result.outputPath).toBe(outputPath);
100-
expect(existsSync(outputPath)).toBe(true);
101-
102-
// Check file size is reasonable
103-
const stats = statSync(outputPath);
104-
expect(stats.size).toBeGreaterThan(100 * 1024);
105-
106-
// Should have received progress updates
107-
expect(progressUpdates.length).toBeGreaterThan(0);
108-
},
109-
300000 // 5 minute timeout
110-
);
86+
// Download test using our tiny hosted test stream (~40KB, 4 seconds)
87+
it("should download our test HLS stream", async () => {
88+
const outputPath = join(tempDir, "test-video.mp4");
89+
90+
const progressUpdates: number[] = [];
91+
const result = await downloadHLSVideo(TEST_STREAMS.local, outputPath, (progress) => {
92+
progressUpdates.push(progress.percent);
93+
});
94+
95+
expect(result.success).toBe(true);
96+
expect(result.outputPath).toBe(outputPath);
97+
expect(existsSync(outputPath)).toBe(true);
98+
99+
// Check file size is reasonable (our test stream is ~40KB)
100+
const stats = statSync(outputPath);
101+
expect(stats.size).toBeGreaterThan(10 * 1024);
102+
103+
// Should have received progress updates
104+
expect(progressUpdates.length).toBeGreaterThan(0);
105+
}, 30000); // 30 second timeout should be plenty for ~40KB
111106
});
112107
});

0 commit comments

Comments
 (0)