Files
iptv/CONTRIBUTING.md
2026-06-21 05:39:39 +03:00

23 KiB

Contributing Guide

Introduction

iptv-org is more than just a repository for sharing currently available links in a playlist format. After years of commitment and moderation practices it has evolved into a knowledge base for streams, channels, program guide sources and the API for developers. And to keep all this data organized, we need to follow strict structural requirements and set certain standards for participants.

Contribution

Submitting a new stream

Before submitting a new stream make sure to acknowledge the Link Requirements section and follow the Stream Validation section of this Guide.

🤚 Requests that do not comply with those sections will be closed immediately!

You have several options:

  • Create a new request by manually filling this form and if approved, the link will automatically be added to the playlist on the next update.

  • Use https://iptv-org.github.io/ to submit a stream for appropriate feed of the channel. To do that find a channel and press the feed link. image

    Then press 3 dots over feed and choose Add Stream. image

    This will submit a filled form that will be reviewed the same way.

  • Add the link to the playlist directly using a pull request. Follow the Playlist Structure and Stream Description Scheme if you choose this method. If you're adding an alternative link please do not replace any other link that might be working for some.

Fixing descriptions

Most of the stream description (channel name, feed name, categories, languages, broadcast area, logo) is loaded from iptv-org/database using the stream ID.

First of all, make sure that the desired stream has the correct ID. A full list of all supported channels and their corresponding IDs can be found on iptv-org.github.io. To change the stream ID of any link in the playlist, just fill out this form.

If, however, you have found an error in the database itself, please refer to: How to edit a database entry?

Reporting broken streams

Fill out this form and we'll verify and remove it.

The only thing before publishing your report is to make sure that:

  • The link is still in our playlists. You can verify this by searching the repository.
  • The link really doesn't work and is not just geo-blocked. To double-check this, please follow our Stream Testing guidelines.

An issue without a valid link will be closed immediately.

Finding broken streams

Follow the Stream Testing guide. VLC media player outputs all errors to the log (Tools -> Messages) so you'll be able to determine pretty accurately why a link isn't working.

Another way to test links is to use the NPM script. To do this, first make sure you have Node.js installed on your system. Clone this repository, then go to the iptv folder using Console (or Terminal if you have macOS) and run the command:

npm run playlist:test path/to/playlist.m3u

This command will run an automatic check of all links in the playlist and display their status:

npm run playlist:test streams/fr.m3u

streams/fr.m3u
┌─────┬───────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────┬───────────────────────────┐
│     │ tvg-id                    │ url                                                                                                  │ label          │ status                    │
├─────┼───────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────┼───────────────────────────┤
│  0  │ 6ter.fr                   │ https://origin-caf900c010ea8046.live.6cloud.fr/out/v1/29c7a579af3348b48230f76cd75699a5/dash_short... │                │ LOADING...                │
│  1  │ 20MinutesTV.fr            │ https://lives.digiteka.com/stream/86d3e867-a272-496b-8412-f59aa0104771/index.m3u8                    │                │ FFMPEG_STREAMS_NOT_FOUND  │
│  2  │                           │ https://video1.getstreamhosting.com:1936/8420/8420/playlist.m3u8                                     │                │ OK                        │
│  3  │ ADNTVPlus.fr              │ https://samsunguk-adn-samsung-fre-qfrlc.amagi.tv/playlist/samsunguk-adn-samsung-fre/playlist.m3u8    │ Geo-blocked    │ HTTP_FORBIDDEN            │
│  4  │ Africa24.fr               │ https://edge12.vedge.infomaniak.com/livecast/ik:africa24/manifest.m3u8                               │                │ OK                        │
│  5  │ Africa24English.fr        │ https://edge17.vedge.infomaniak.com/livecast/ik:africa24sport/manifest.m3u8                          │                │ OK                        │
│  6  │ AfricanewsEnglish.fr      │ https://37c774660687468c821a51190046facf.mediatailor.us-east-1.amazonaws.com/v1/master/04fd913bb2... │                │ HTTP_GATEWAY_TIMEOUT      │
│  7  │ AlpedHuezTV.fr            │ https://edge.vedge.infomaniak.com/livecast/ik:adhtv/chunklist.m3u8                                   │ Not 24/7       │ HTTP_NOT_FOUND            │

Also, if you add the --fix option to the command, the script will automatically remove all broken streams it finds from your local copy of playlists:

npm run playlist:test streams/fr.m3u --- --fix

After that, all you need to do is report the broken streams you found via the form or create a pull request with updated playlists.

Removing infringing content

To request removal of a link to a channel from the repository, you need to fill out this form and wait for the request to be reviewed (this usually takes no more than 1 business day). And if the request is approved, links to the channel will be immediately removed from the repository.

The channel will also be added to our blocklist to avoid its appearance in our playlists in the future.

Please note that we only accept removal requests from channel owners and their official representatives, all other requests will be closed immediately.

Before submitting new streams you should verify the following:

  • Make sure the link has not been submitted into the repository before. This can be done by searching the repository or the website.

  • Each submitted stream link must have a registered Channel & Feed ID (eg: ChannelID@FeedID) in our database. A complete list of channels and feeds can be found at iptv-org.github.io. If it's not present, please follow the Database Contributing Guide to add it. Streams submitted by PRs without valid ID will not reach mainstream playlists targeting a category, language or broadcast area.

  • User-submitted links to stream URLs shall be intended to be publicly available by stream provider and the copyright holders.

  • Channels under DMCA takedown notices or broadcasting copyrighted content (such as the Champions League) at any time will not be accepted, see the blocklist for details.

  • The same applies to channels that are known to partially or fully broadcast NSFW content.

  • User-submitted links must not have any effective restrictions that limit viewers by authorization, by viewer count or by designated IP.

  • Test period links are not permitted.

  • User-submitted links must open in VLC media player (see the FAQ for more details).

  • If the host server requires a specific user-agent and/or a referer, is geo-blocked or may have downtimes, you should represent that in your contribution (see the Stream Description Scheme).

  • If possible please provide an adaptive link that covers every available resolution for a broadcast.

  • Follow the Playlist Structure in case of contributing by pull requests.

Stream Validation

How do I know if the stream is eligible?

Make sure you can find the origin of the broadcast using your favourite search engine or by following the domain of broadcast. If you used to see the channel under paywalls or subscription offers, it may likely involve a copyright infringement. If you see a service with a time trial or you have found a link having unreadable parts of it in someone else's playlist, it's likely to expire soon. We typically look for pages with publicly accessible video players, as these are more likely to host broadcasts intended for public viewing. However, even in such cases, the underlying stream URLs are often protected and may only be accessible within your authenticated session. Examples of valid streams are shown below.

Examples

Valid links usually have a format like so

  • https://cdn.domain.com.com/live?stream=channelname
  • http://10.113.179.1:port/udp/238.1.1.1:port
  • rtmp://10.113.179.1:port/prefix/channel
  • http://10.113.179.1:port/play/a16j

Links with expiring sessions may contain one or more arguments that will have a hash or random numeric value like so:

  • ?nimblesessionid=21683442
  • &authid=
  • &key=txiptv
  • &ip=10.113.179.1
  • &secret=f8z1l7gk
  • &e=1783194414
  • &st=Lz1QtjfblUmkawUbk1Mx6w
  • &token=9f192891-eca5-2435-b9cb-147f376cdc1e
  • &hmac=3295a8e67dcf75af313061a17c3dad11
  • wmsAuthSign=c2bWU9Ni8yMC8yMDIVydmVyX3Rp2IDc6MDk6MjAgUmFsaWRtaWE0maGFzaF92YWx1ZTE5SkNSQkhqUG5JZVRRPT0md51dGVzPTMwJmlkPTZhMzZlNT1lRzlsZG4rOXYwZTIzNDk

There might be notable examples when a session must be created but it doesn't impose any meaningful limits, eg. :

https://bl.rutube.ru/livestream/id/index.m3u8?e=2070278263&s=sessiontoken&scheme=https

where the only limitation is that the session will expire in 2035. You can check unix timestamps here.

Links from subscription based services often be in a form like so:

  • https://sketchydomain.xyz:port/username/password/channelID
  • http://cdn.domain.com/credentialhash/channelID/index.m3u8
  • http://cdn.domain.com/channelID/mpegts?token=CTkHfXdAqvPcwq

If changing channelID to almost any value within a range of hundreds or thousands of IDs results in a valid stream from a different channel, then it likely comes from a leaked account or a trial account.

Stream Testing

  • If it doesn't launch, try opening the link in your browser. Press F12, go to the "Network" tab, and filter requests for m3u or mpd.

  • Open VLC media player and make use of your link. image

    Switch to "Headers" tab, scroll down and copy the "User-Agent" and the "Referer". image

Next, open any text editor of your choice and paste the link with the parameters you found into it, like this:

#EXTM3U
#EXTINF:-1,Example TV
#EXTVLCOPT:http-referrer=https://example.com
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64)
https://example.com/playlist.m3u8
  • Watch the broadcast for at least a few minutes. Make sure playback is stable and does not stop abruptly at some point.
  • Try restarting the stream. Make sure it's not looping on a repeating segment and is still available.
  • Alternatively, you can use services like streamtest.in.
  • To check if the stream link is geo-blocked you can use services like check-host.net.

Stream Description Scheme

For a stream to be approved, its description must follow this template:

#EXTINF:-1 tvg-id="STREAM_ID",STREAM_TITLE (QUALITY) [LABEL]
STREAM_URL
Attribute Description Required Valid values
STREAM_ID Stream ID consisting of channel ID and feed ID. Full list of supported channels with corresponding ID can be found on iptv-org.github.io. Optional <channel_id> or <channel_id>@<feed_id>
STREAM_TITLE Stream title consisting of channel name and feed name. May contain any characters except: ,, [, ]. Required -
QUALITY Maximum stream quality. Optional 2160p, 1080p, 720p, 480p, 360p etc
LABEL Specified in cases where the broadcast for some reason may not be available to some users. Optional Geo-blocked or Not 24/7
STREAM_URL Stream URL. The following protocols are supported: HTTPS, HTTP, MMS, MMSH, RTSP, RTMP, SRT, RTP, UDP. Required -

Example:

#EXTINF:-1 tvg-id="ExampleTV.us@East",Example TV East (720p) [Geo-blocked]
https://example.com/playlist.m3u8

Also, if necessary, you can specify custom HTTP User-Agent and HTTP Referrer through #EXTVLCOPT directive:

#EXTINF:-1 tvg-id="ExampleTV.us",Example TV
#EXTVLCOPT:http-referrer=http://example.com/
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64)
http://example.com/stream.m3u8

Playlist Structure

There are two types of playlists that can be found in the streams/ directory:

  • Playlists by country of origin — indicate that the studio broadcasting the channel is headquartered in a particular country. This does not necessarily mean that the stream is intended for viewers in that same country.
  • Playlists by source - imply that all the containing streams comes from the same server or infrastructure and broadcast on behalf of the same provider. Please note that both playlist types are not intended for end users and are meant to remain that way for ease of maintenance. All links in playlists are sorted automatically according to the information used from our Database so there is no need to sort them manually. For more info, see Scripts.

Each playlist file must

  • Have an .m3u extension
  • Start with a #EXTM3U header
  • Strictly follow the Stream Description Scheme and pass linter checks from check workflow
  • Use CRLF file endings and use UTF-8 encoding without BOM

Project Structure

iptv/
├── .github/
│   ├── ISSUE_TEMPLATE/     # Templates for submitting issues/requests
│   ├── workflows/          # contains [GitHub actions](https://docs.github.com/en/actions/quickstart) workflows.
│   └── CODE_OF_CONDUCT.md  # Community guidelines and rules
├── .readme/
│   ├── config.json         # config for the `markdown-include` package, which is used to compile everything into one `PLAYLISTS.md` file.
│   ├── preview.png         # image displayed in the `README.md`.
│   └── template.md         # template for `PLAYLISTS.md`.
├── scripts/                # contains all scripts used in the repository.
├── streams/                # contains all streams broken down by country from which they are broadcasted.
├── tests/                  # contains tests to check the scripts.
├── CONTRIBUTING.md         # This contributor guide, the file you are currently reading.
├── PLAYLISTS.md            # Automatically generated index of all available playlists
└── README.md               # The primary landing page and project description

Scripts

These scripts are created to automate routine processes in the repository and make it a bit easier to maintain.

For scripts to work, you must have Node.js installed on your computer.

To run scripts use the npm run <script-name> command.

  • act:check: allows to run the check workflow locally. Depends on nektos/gh-act.
  • act:format: allows to test the format workflow locally. Depends on nektos/gh-act.
  • act:update: allows to test the update workflow locally. Depends on nektos/gh-act.
  • api:load: downloads the latest channel and stream data from the iptv-org/api.
  • playlist:format: formats internal playlists. The process includes URL normalization, duplicate removal, removing invalid ids and sorting links by channel name, quality, and label.
  • playlist:update: triggers an update of internal playlists. The process involves processing approved requests from issues.
  • playlist:generate: generates all public playlists.
  • playlist:validate: checks ids and links in internal playlists for errors.
  • playlist:lint: checks internal playlists for syntax errors.
  • playlist:test: tests links in internal playlists.
  • playlist:edit: utility for quick streams mapping.
  • playlist:export: creates a JSON file with all streams for the iptv-org/api repository.
  • readme:update: updates the list of playlists in README.md.
  • report:create: creates a report on current issues.
  • lint: checks the scripts for syntax errors.
  • test: runs a test of all the scripts described above.

Workflows

To automate the run of the scripts described above, we use the GitHub Actions workflows.

Each workflow includes its own set of scripts that can be run either manually or in response to an event.

  • check: sequentially runs the api:load, playlist:check and playlist:validate scripts when a new pull request appears, and blocks the merge if it detects an error.
  • format: sequentially runs api:load, playlist:format, playlist:lint and playlist:validate scripts.
  • update: every day at 0:00 UTC sequentially runs api:load, playlist:update, playlist:lint, playlist:validate, playlist:generate, playlist:export and readme:update scripts and deploys the output files if successful.