How to Debug Failed IPTV Stream Tests: A Complete Guide
To debug failed IPTV stream tests, run npm run playlist:test, inspect the live status table for error codes like TIMEOUT or HTTP_404_NOT_FOUND, and use NODE_ENV=test with mock data for deterministic reproduction.
The iptv-org/iptv repository uses an automated testing suite to validate thousands of stream URLs across its playlist files. When the playlist:test command flags streams as failed, understanding the underlying error classification system and debugging tools will help you identify whether a link is temporarily down, permanently moved, or malformed.
Understanding the IPTV Stream Test Architecture
The testing pipeline relies on three core components working sequentially: network requests via axios, media analysis via mediainfo.js, and error normalization in the StreamTester class.
Core Testing Components
In scripts/core/streamTester.ts, the test() method orchestrates the validation:
- Network Request: Fetches the stream URL with configurable timeouts and proxy support.
- Media Analysis: Passes the response buffer to
mediainfo.jsto detect video tracks. - Result Classification: Returns a
StreamTesterResultobject containing anokboolean and a specific error code.
Error Classification System
The scripts/commands/playlist/test.ts file defines errorStatusCodes, an array that determines which failures constitute critical errors versus warnings:
const errorStatusCodes = [
'ECONNREFUSED',
'ENOTFOUND',
'ENETUNREACH',
'EPROTO',
'HTTP_404_',
'HTTP_404_NOT_FOUND',
'HTTP_404_UNKNOWN_ERROR',
'HTTP_410_GONE'
];
Streams matching these codes without a label property increment the error counter; labeled streams generate warnings instead.
Running the Test and Interpreting Results
Execute the validation against specific playlist files using the npm script defined in package.json:
cross-env DATA_DIR=tests/__data__/input/data ROOT_DIR=tests/__data__/output \
npm run playlist:test streams/ag.m3u
The command renders a live table that updates every few seconds with the following columns:
- tvg-id: The stream identifier from the playlist.
- url: The truncated stream URL.
- label: Optional human-readable metadata.
- status: The result code (
OK,TIMEOUT,HTTP_404_NOT_FOUND,NO_VIDEO, etc.).
Upon completion, the CLI outputs a summary such as 2 problems (1 errors, 1 warnings). Red entries in the table indicate streams that triggered the failure.
Identifying Common Failure Reasons
Network and HTTP Errors
In scripts/core/streamTester.ts (lines 96-107), the error handler normalizes axios exceptions into predictable codes:
TIMEOUT: Triggered when a request exceeds the configured timeout or is explicitly canceled.HTTP_<status>_<text>: Derived fromerror.response.statusandstatusText(e.g.,HTTP_404_NOT_FOUND).AXIOS_<code>: Captures low-level network errors likeECONNREFUSEDorENOTFOUNDwhen no response is received.
Media Analysis Failures
Even when a URL responds successfully, the stream must contain valid video tracks. The mediainfo.js analysis (lines 78-91) returns:
OK: At least one video track detected.NO_VIDEO: The response parsed successfully but contained no video streams (common for radio streams or corrupted playlists).
Debugging Techniques for Failed Streams
Using Verbose Logging and Isolation
To inspect the raw StreamTesterResult for a specific stream, temporarily add logging to the runTest function in scripts/commands/playlist/test.ts:
async function runTest(stream: Stream) {
const result = await tester.test(stream);
console.log(`URL: ${stream.url}, Result:`, result);
// ...existing logic...
}
For easier reading, limit parallelism to one stream at a time:
npm run playlist:test streams/ag.m3u -- --parallel 1
Testing Mode with Mock Data
Set NODE_ENV=test to bypass network requests and use deterministic mock data from tests/__data__/input/playlist_test/results.js:
cross-env NODE_ENV=test DATA_DIR=tests/__data__/input/data \
npm run playlist:test streams/ag.m3u
In this mode, scripts/core/streamTester.ts (line 58) imports the mock map:
if (TESTING) {
const results = (await import('../../tests/__data__/input/playlist_test/results.js')).default;
return results[stream.url as keyof typeof results];
}
Edit results.js to simulate specific error conditions without external dependencies:
export default {
"https://example.com/broken.m3u8": { status: { ok: false, code: "HTTP_404_NOT_FOUND" } },
"https://example.com/good.m3u8": { status: { ok: true, code: "OK" } }
};
Automatic Cleanup with --fix Flag
Once you have confirmed which streams are permanently broken, use the --fix flag to automatically remove them:
npm run playlist:test streams/ag.m3u -- --fix
This invokes removeBrokenLinks() (lines 55-64 in scripts/commands/playlist/test.ts), which:
- Groups streams by their source playlist file.
- Filters out streams where
isBroken(stream)returnstrue. - Overwrites the original playlist files with the cleaned entries.
The isBroken() function (lines 12-18) applies the same logic as the error counter, ensuring only unlabeled streams with critical error codes are purged.
Summary
- Run tests with
npm run playlist:test <playlist>to generate a live status table showingOK,TIMEOUT,HTTP_404_NOT_FOUND, and other codes. - Interpret failures by comparing status codes against the
errorStatusCodesarray inscripts/commands/playlist/test.tsto distinguish critical errors from warnings. - Debug efficiently by adding temporary logging to
runTest(), using--parallel 1for serial output, or settingNODE_ENV=testto use mock data fromtests/__data__/input/playlist_test/results.js. - Clean playlists automatically with the
--fixflag, which triggersremoveBrokenLinks()to purge streams that return codes likeHTTP_410_GONEorECONNREFUSED.
Frequently Asked Questions
Why does a stream show HTTP_404_NOT_FOUND when it works in my browser?
The HTTP_404_NOT_FOUND code indicates the server returned a 404 status to the axios request in scripts/core/streamTester.ts. This often happens when the server blocks automated requests by checking for specific headers or user-agents that the test client does not send. Try comparing the headers your browser sends with the default axios configuration, or check if the stream requires a referer or specific cookie that the test environment lacks.
How do I debug a specific stream without running the entire playlist?
Set NODE_ENV=test and edit the tests/__data__/input/playlist_test/results.js file to include only the URL you want to debug. Then run the test command with --parallel 1 to process streams serially. This isolates the output for your target stream without network variability, allowing you to verify how the CLI handles specific error codes like NO_VIDEO or TIMEOUT.
What is the difference between an error and a warning in the test output?
Errors are counted when a stream returns a code listed in errorStatusCodes (such as HTTP_404_NOT_FOUND or ECONNREFUSED) and has no label property. Warnings are generated for the same error codes if the stream has a label, or for non-critical issues. The --fix flag only removes streams classified as errors, preserving labeled streams even if they fail, according to the logic in isBroken() within scripts/commands/playlist/test.ts.
Can I use a proxy to debug geo-blocked streams?
Yes, pass the -x or --proxy flag followed by your proxy URL when running the test command. The StreamTester class passes this option to the axios client in scripts/core/streamTester.ts, routing all requests through the specified proxy. If all streams suddenly return TIMEOUT after adding the flag, verify the proxy is running and accessible from your environment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →