IPTV-API: a self-hosted pipeline that collects, checks and publishes IPTV playlists
⚡️ IPTV直播源自动更新工具:自动采集、校验、测速并生成可播放结果,支持 M3U/TXT/API 输出、自定义频道、IPv4/IPv6、Docker、GitHub Actions、CLI 与 GUI 多端部署
At a glance
- What is it?
- IPTV-API gathers live-stream sources, verifies them by speed and resolution, and writes M3U, TXT or API output. It suits people who want a generated playlist they control, not a subscription service.
- Who is it for?
- Adopt IPTV-API if you can run a container or a scheduled workflow and you want a playlist whose channels are re-checked on a schedule. Do not adopt it if you expect a service with a support contract, guaranteed channel availability or a stable upstream: the repository is a tool, not a provider, and the README's own disclaimer section exists for that reason.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap IPTV-API fills between raw source lists and a working player
A public M3U list is a snapshot. Streams disappear, a host rate-limits one region, an address starts returning a placeholder loop instead of a channel. Anyone who has imported a free playlist into a player knows the result: dozens of entries that fail on selection. IPTV-API is built around that decay. Its stated job is to collect sources, aggregate multiple origins, verify availability, filter by measured speed and emit a playlist in M3U, TXT or through an API endpoint that a player can consume directly.
The target user is technical but not necessarily a developer. The repository ships four deployment paths, and that list is the clearest statement of intent: a GitHub Actions workflow, a command line, a desktop GUI for Windows and macOS, and Docker. Someone who only wants a refreshed playlist can fork the repository and let the workflow publish the output. Someone who wants a local service can run the container. The README's feature table also lists channel renaming with 2,769 channels and 7,254 aliases (48 of them regular expressions), EPG retrieval, channel logos, playback screenshots and ad filtering. Those are curation features, not streaming features, which tells you where the project spends its effort. The repository topics reinforce the same emphasis: epg, iptv-m3u8, playlist, schedule, tvbox. Nothing in that list suggests the project wants to be a player.
It is worth being precise about what the tool is not, because the name invites confusion. "IPTV-API" sounds like a hosted service that answers requests for channels. It is not. It is a generator that runs on your infrastructure and writes files or serves those files. The API in the name refers to the output format, not to a remote endpoint you subscribe to.
How the collection, verification and output stages fit together
The pipeline has three visible stages. Collection pulls from local source files and from subscription sources; the README notes that subscription sources support a custom User-Agent and that invalid addresses are detected and automatically deactivated. That deactivation detail matters more than it looks: a source that starts returning errors does not have to be removed by hand, which keeps a long-running deployment from accumulating dead weight.
Verification is the second stage and the one with the most configuration surface. The project measures latency, bitrate, resolution and frame rate, drops interfaces that fail, and can stream results in real time. The optional screenshot feature captures a frame per channel so you can confirm that an address actually carries the channel it claims. Ad filtering targets looping placeholder sources that return a signal but no content, which is a distinct failure from a dead link and needs a different check.
The third stage writes output, and the repository layout shows what that means in practice: a config directory holds inputs, an output directory receives generated playlists, and the container exposes them over HTTP through nginx. The README also lists result management: classified storage, logs, unmatched channel records, statistics, and a freeze/unfreeze mechanism that parks a failing channel and later tests whether it has recovered.
The Dockerfile explains the runtime shape. It builds nginx 1.27.4 with the nginx-rtmp-module 1.2.2 and installs ffmpeg in the final image. That is why the feature table can promise push streaming and browser playback: the container is not just a Python process, it is a Python process behind a web server with an RTMP module and a transcoder. The application itself listens on APP_PORT 5180 inside the container, while nginx serves on NGINX_HTTP_PORT 8080. The compose file maps host port 80 to 8080 by default. If you plan to put this behind a reverse proxy, the layering matters more than the individual numbers, and the NGINX_HTTP_PORT variable is described in the compose file as an advanced compatibility setting that should normally stay unchanged.
Installing IPTV-API with Docker Compose and reading the first output
The repository ships a docker-compose.yml, which is the shortest path to a running instance. It uses the image guovern/iptv-api:latest and mounts two host paths, /iptv-api/config and /iptv-api/output. Create those directories before the first start, because the compose file references absolute paths.
mkdir -p /iptv-api/config /iptv-api/output
cd /path/to/iptv-api
docker compose up -dThe container restarts unless stopped and keeps stdin open. Two environment variables deserve attention before you expose anything: PUBLIC_DOMAIN defaults to 127.0.0.1 in the compose file, and PUBLIC_URL is empty by default. The comment in the file states that an unset or empty PUBLIC_URL keeps public_url from the mounted config, and recommends setting a complete external URL such as http://192.168.1.10. If you generate playlists that contain absolute addresses, that setting determines whether they work outside your own machine.
environment:
PUBLIC_SCHEME: "http"
PUBLIC_DOMAIN: "192.168.1.10"
PUBLIC_PORT: "80"
PUBLIC_URL: "http://192.168.1.10"
HTTP_PROXY: ""After the first run, the output directory should contain generated playlist files, and the web port should serve them. The README points to a documentation center and a tutorial under docs/ for configuration detail, so treat the compose defaults as a starting point rather than a finished setup. The GitHub Actions path is the alternative if you do not want to host anything: the workflow runs on a schedule and publishes results as releases, which is consistent with the release names in the repository, such as playlist-20260920-151608-utc-plus-0800. Note that the README states scheduled tasks in the GUI, CLI and Docker do not apply to GitHub Actions; scheduling there is handled by the workflow itself. If you run the container, the same README says the GUI, CLI and Docker paths can execute on a timer or an interval, which is the scheduling mechanism you would use instead.
Where IPTV-API breaks down or is simply the wrong tool
The project does not provide channels. It aggregates and filters sources you or its defaults supply, so if a channel is not present in any reachable source, no amount of speed testing will produce it. That is the central limitation, and the README's disclaimer section reflects it.
Verification is also a snapshot. A stream that passes a latency and bitrate check at generation time can fail an hour later, and the project's answer is regeneration on a schedule, not continuous monitoring of the playlist you already exported. The freeze and unfreeze mechanism softens this by retesting parked channels on later runs, but it still operates on the generation cycle. If you need a stream that stays up during a specific broadcast, this pipeline does not guarantee it.
The configuration surface is broad by design: speed thresholds, resolution preferences, blacklists and whitelists, region and ISP filters, ad filtering, screenshot capture. Each of those is a knob that can silently remove channels you wanted. A filter that is too aggressive produces a short, clean playlist; too loose and you get the failure mode you were trying to avoid. The README documents the parameters, but tuning them is your job, and the unmatched channel records in the result management features are where you find out what a filter cost you.
There is also a resource cost that is easy to underestimate. Verification opens connections to many candidate streams, and the container bundles ffmpeg for transcoding and screenshot work. Running this on a small always-on box is feasible, but the verification pass is the part that consumes bandwidth and CPU, not the file writing.
Finally, the licence. The repository's LICENSE file is present but the project is reported as NOASSERTION, meaning no standard licence identifier could be determined. Read the LICENSE file and the disclaimer before you build anything commercial on top of it.
How IPTV-API differs from a plain M3U aggregator or a paid provider
The obvious alternative is a static community playlist: a single M3U URL that someone else maintains. The difference is where the work happens. A static list is produced once by its maintainer and distributed as-is; IPTV-API produces the list on your machine or in your CI, from sources you configure, with a verification pass in between. You get freshness and control, and you take on the compute and the configuration. The static list also fails silently when its maintainer stops, whereas here a failed run is visible in the logs and the result management output.
The other alternative is a commercial IPTV subscription, which is what most of the related search phrases point at. That model sells access to streams and usually supplies an Xtream-style API endpoint and EPG as part of the service. IPTV-API does neither: it is a generator, and the README describes its outputs as M3U, TXT or an API interface for your own generated results. The EPG feature acquires programme data to attach to channels you already have, which is not the same as a provider supplying a lineup. If your actual requirement is a reliable channel lineup with someone accountable for uptime, a generator is the wrong category of tool, regardless of how well it performs.
A third comparison is a general-purpose playlist editor. Those assume you already have a list you trust and want to rearrange it. IPTV-API assumes the opposite: the list is untrustworthy and must be rebuilt and re-measured before it is worth editing. The custom template feature exists for the case where you want a specific channel menu, but it operates on the verified result, not on an imported file.
Maintenance, upgrade cost and licence implications
The repository is not archived, and the last push was on 2026-09-20, one day before this writing. Release activity follows the generation schedule rather than a version cadence: the most recent releases are named after their generation timestamps, and a playlist-latest tag exists separately. That means the release feed is not a reliable signal of code changes. Use CHANGELOG.md for that, and treat the playlist releases as output, not as software versions. One release in the recent list is explicitly marked test only, which is a further reason not to read the feed as a changelog.
The runtime is pinned in ways that create upgrade work. The Dockerfile builds on python:3.14-alpine, compiles nginx 1.27.4 from source and pulls nginx-rtmp-module v1.2.2 from GitHub. Python dependencies are installed through Pipenv with --deploy against Pipfile.lock. Upgrading the Python base image means rebuilding nginx and the RTMP module in the same image, so image rebuilds are heavier than for a pure Python service. The desktop GUI is a separate artifact with its own download counter in the README badges, which implies a second release track to follow if you use it.
On licensing, the repository contains a LICENSE file but is reported as NOASSERTION, so the terms are not machine-identifiable. That is not legal advice, and it is a reason to read the file directly before redistributing generated playlists or bundling the tool. The disclaimer section in the README is the other document to read, since it frames what the project claims responsibility for.
Operationally, the maintenance burden is mostly the schedule. A workflow run that stops working produces a stale playlist rather than an error you will notice, so the practical check is whether the output directory or the latest release is still advancing.
Deployment choices: workflow, CLI, GUI or container
The four paths are not equivalent. GitHub Actions costs nothing to run and needs no host, but the README states that scheduled tasks in the GUI, CLI and Docker do not apply there, so timing is controlled by the workflow definition and you depend on the runner's network position for source reachability. Docker gives you the full stack, including nginx and ffmpeg, which is what push streaming and browser playback require; it also gives you the HTTP_PROXY variable, which the compose file notes is used only for subscription sources and EPG data, not media speed tests. That distinction matters if you were hoping a proxy would change which streams pass verification. The CLI is the path for scripted runs on a machine you control, and the GUI adds pause and resume during an update, a feature the README lists only for the desktop client.
The container exposes only NGINX_HTTP_PORT in the Dockerfile, while NGINX_RTMP_PORT 1935 is defined as an environment variable. If you intend to use the push streaming feature, the RTMP port is the one to check in your compose override, because the shipped compose file does not publish it.
For most readers the decision comes down to where the network lives. A workflow runs from a datacenter address, which changes which sources respond. A container on your home network sees what your player will see. That difference affects the verification result more than any threshold setting.
Editorial conclusion
Adopt IPTV-API if you can run a container or a scheduled workflow and you want a playlist whose channels are re-checked on a schedule. Do not adopt it if you expect a service with a support contract, guaranteed channel availability or a stable upstream: the repository is a tool, not a provider, and the README's own disclaimer section exists for that reason. Before committing, verify two things on your own machine: that the mounted /iptv-api/config and /iptv-api/output directories are writable by the container, and that your network can reach the sources you intend to aggregate, since the compose file's HTTP_PROXY variable applies only to subscription sources and EPG data, not to media speed tests.
Frequently asked questions
Can I stream IPTV on GitHub?
IPTV-API's GitHub Actions workflow runs the collection and verification pipeline and publishes generated playlists as releases, so the repository hosts the generation process and its output rather than the streams themselves.
How do I get a URL for IPTV with IPTV-API?
The project outputs M3U, TXT or an API interface. In Docker, nginx serves the generated results over HTTP on NGINX_HTTP_PORT 8080 inside the container, mapped from host port 80 by the compose file, and PUBLIC_URL should be set to a complete external URL so generated addresses resolve.
Which server is best for IPTV?
No server is recommended here. What the repository does specify is that the Docker image is built for amd64, arm64 and arm v7 according to the feature table, and that the compose file mounts /iptv-api/config and /iptv-api/output as host paths.
Where can I find M3U IPTV files?
IPTV-API generates them rather than shipping a fixed list. It aggregates local source files and subscription sources, verifies them, and writes the results into the output directory or publishes them as playlist releases.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/guovin-iptv-api)