iptv-stream-validator
A small Python package for validating IPTV stream endpoints and parsing M3U / M3U8 playlists. It uses only the Python standard library, has no runtime dependencies, and supports Python 3.9+.
What the package does
- Parses M3U / M3U8 playlists — extended playlists with
#EXTINFmetadata (title, duration,tvg-id,group-title, and otherkey="value"attributes) as well as plain URL-only lists. - Checks stream endpoints over HTTP(S) — one lightweight request per URL that stops after the response status line and headers, without downloading the media body.
- Records HTTP status and response time for every check.
- Applies configurable timeouts so dead endpoints cannot stall a validation run.
- Reports failures as data — every check returns a
ValidationResult, so DNS errors, refused connections, timeouts, and HTTP errors are results, not exceptions. - Produces JSON-ready output — results and playlist entries serialize to plain dictionaries, and
summarize_results()aggregates a whole run into counts, failed URLs, and median/average response times.
Installation
The distribution name is iptv-stream-validator. Once published on PyPI:
pip install iptv-stream-validator
To install from a checkout of this repository (the package is pure Python, standard library only):
pip install .
There are no runtime dependencies.
Basic Python usage
from iptv_stream_validator import StreamValidator, summarize_results
validator = StreamValidator(timeout=5)
results = validator.validate_many(
[
"https://example.com/streams/news.m3u8",
"http://example.com:8080/live/sports.ts",
]
)
for result in results:
print(result.to_json())
print(summarize_results(results))
StreamValidator sends a GET request by default (many streaming servers reject HEAD) but never reads the response body — the connection is closed as soon as the status line and headers arrive. Pass method="HEAD" if you prefer HEAD requests.
M3U playlist validation example
Parse a playlist and check the syntactic validity of its URLs before doing any network I/O:
from iptv_stream_validator import parse_m3u, is_valid_stream_url
playlist_text = """#EXTM3U
#EXTINF:-1 tvg-id="cnn.us" group-title="News",CNN
https://example.com/streams/cnn.m3u8
#EXTINF:-1 tvg-id="bbc.uk",BBC One
https://example.com/streams/bbc.m3u8
"""
entries = parse_m3u(playlist_text)
for entry in entries:
print(entry.title, entry.attributes, entry.url)
print(" URL looks valid:", is_valid_stream_url(entry.url))
Output:
CNN {'tvg-id': 'cnn.us', 'group-title': 'News'} https://example.com/streams/cnn.m3u8
URL looks valid: True
BBC One {'tvg-id': 'bbc.uk'} https://example.com/streams/bbc.m3u8
URL looks valid: True
Playlists can also be read straight from a file with parse_m3u_file(path), and extract_urls(text) returns just the URL list. A playlist whose text contains no URL lines raises PlaylistError.
Stream endpoint validation example
Combining the two modules — parse a playlist, then validate every endpoint it contains:
from iptv_stream_validator import StreamValidator, parse_m3u, summarize_results
with open("playlist.m3u", "r", encoding="utf-8") as handle:
entries = parse_m3u(handle.read())
validator = StreamValidator(timeout=5)
results = validator.validate_many(entry.url for entry in entries)
for entry, result in zip(entries, results):
state = "OK" if result.ok else "FAIL"
print(f"{state} {entry.title or entry.url} {result.error or result.status}")
summary = summarize_results(results)
print(f"{summary['ok']}/{summary['total']} endpoints responded")
print(f"median response time: {summary['median_response_time']}s")
Timeout and error handling
- The timeout (default 10 seconds, configurable via
StreamValidator(timeout=...)) covers DNS resolution, connection setup, and waiting for the response status line. validate()catches network-level problems (URLError, DNS failures, refused connections, socket timeouts) and HTTP error statuses, and returns them inside theValidationResult— it does not raise for a broken endpoint.- HTTP
4xx/5xxresponses are reported as failures with their status code, since the endpoint answered but the URL is not usable as a stream. - Redirects are followed by default; if the final URL differs from the requested one it is recorded in
result.final_url. - Invalid constructor arguments (unknown method, non-numeric timeout, empty user agent) raise
ValueError/TypeErrorimmediately.
result = validator.validate("https://example.com/streams/down.m3u8")
if not result.ok:
print(result.error) # e.g. "timed out after 5s" or "HTTP 404 Not Found"
Example output
A single result (result.to_json()):
{
"url": "https://example.com/streams/news.m3u8",
"ok": true,
"status": 200,
"response_time": 0.184371,
"error": null,
"final_url": null
}
A failed check:
{
"url": "https://example.com/streams/down.m3u8",
"ok": false,
"status": null,
"response_time": 5.001293,
"error": "timed out after 5s",
"final_url": null
}
A run summary (summarize_results(results)):
{
"total": 3,
"ok": 2,
"failed": 1,
"failed_urls": ["https://example.com/streams/down.m3u8"],
"median_response_time": 0.211054,
"average_response_time": 0.197713,
}
Limitations
- Checks are sequential; validating thousands of URLs takes correspondingly long. Run multiple processes or threads yourself if you need concurrency.
- A successful HTTP response does not prove the payload is playable media — the content is not inspected or decoded. Some servers accept any request path with a 200 response; treat results as a first-pass filter, not a guarantee.
- Endpoints that require specific headers (cookies, referers, unusual user agents) can be configured via
user_agent, but anything more elaborate needs custom code on top of this package. is_valid_stream_url()is a syntactic check only (HTTP/HTTPS scheme, non-empty host); it performs no network requests.- The parser covers the common
#EXTINF-based IPTV playlist layout. Other directives (#EXTVLCOPT,#EXTGRP,#KODIPROP, ...) are ignored rather than interpreted. - No M3U variant-specific handling beyond
#EXTINFmetadata: no XMLTV merging, no EPG lookup, no deduplication of streams.
License
MIT — see LICENSE.
Additional IPTV playlist / player resources
- IPTV2Live — IPTV playlist and player reference site; this project's homepage and documentation are hosted there.
- HLS (HTTP Live Streaming), RFC 8216 — the specification behind
.m3u8media playlists. - VideoLAN VLC — a widely used player for M3U playlists and network streams.
- FFmpeg — the standard toolkit for inspecting and re-streaming media (e.g.
ffprobefor checking whether a URL yields playable media). - iptv-org/iptv — a large, publicly maintained collection of M3U playlists, useful as realistic test input.
Metadata
Release files for iptv-stream-validator 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| iptv_stream_validator-0.1.0.tar.gz | 16.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| iptv_stream_validator-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.3 kB
Release files / iptv_stream_validator-0.1.0.tar.gz
| Download URL | iptv_stream_validator-0.1.0.tar.gz |
|---|---|
| Size | 16.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ff57d8e1fbd841c1145451983b8003b59d402e607c8dbb9e21eab0f9145f2f1c
|
|
BLAKE2b-256 checksum How to use checksums |
a7687ac834db28fcad0d54dd25247654d9a4170ee2920551a822800f41e9e1ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / iptv_stream_validator-0.1.0-py3-none-any.whl
| Download URL | iptv_stream_validator-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c1eb1316a2c7414db9f25e318f3ae0dc6c76dcbda958fece8aa8dd2d8c5e7112
|
|
BLAKE2b-256 checksum How to use checksums |
0fd349d06e130553dae6cf5f69e7bb58816d40681f68b8030ffd70343103648e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for iptv-stream-validator 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.