Merge pull request #41064 from iptv-org/update-contributing-md

Update CONTRIBUTING.md
This commit is contained in:
Alstruit
2026-06-28 16:28:23 -05:00
committed by GitHub
8 changed files with 352 additions and 152 deletions
+13
View File
@@ -0,0 +1,13 @@
# Playlist Structure
All links in the repository are stored in the [streams/](../../streams) folder as [M3U](https://en.wikipedia.org/wiki/M3U) playlists, grouped by the sources from which they are broadcast. They are arranged this way solely for the convenience of moderating links and are not intended for use by end users.
All links undergo automatic filtering and are sorted according to data in our [database](https://github.com/iptv-org/database), so there is no need to sort anything manually. For more info, see [Scripts](./scripts.md).
In order for the scripts to process these files correctly, you must follow a strict structure:
- All files must have the `.m3u` extension
- The playlist must begin with the header `#EXTM3U`
- Each link must comply with the [Stream Description Scheme](./stream-description-scheme.md)
- Lines must end with [CRLF](https://developer.mozilla.org/en-US/docs/Glossary/CRLF)
- The file encoding must be UTF-8 without BOM
+191
View File
@@ -0,0 +1,191 @@
# Scripts
The repository contains a few scripts created to automate routine processes and make it a bit easier to maintain.
For the scripts to work, you must have [Node.js](https://nodejs.org/en) installed on your computer.
- [act:check](#actcheck)
- [act:format](#actformat)
- [act:update](#actupdate)
- [api:load](#apiload)
- [playlist:format](#playlistformat)
- [playlist:update](#playlistupdate)
- [playlist:generate](#playlistgenerate)
- [playlist:validate](#playlistvalidate)
- [playlist:lint](#playlistlint)
- [playlist:test](#playlisttest)
- [playlist:edit](#playlistedit)
- [playlist:export](#playlistexport)
- [readme:update](#readmeupdate)
- [report:create](#reportcreate)
- [lint](#lint)
- [test](#test)
## act:check
Runs the [check](./workflows.md#check) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
```sh
npm run act:check
```
## act:format
Runs the [format](./workflows.md#format) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
```sh
npm run act:format
```
## act:update
Runs the [update](./workflows.md#update) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
```sh
npm run act:update
```
## api:load
Downloads the latest channel and stream data from the [iptv-org/api](https://github.com/iptv-org/api) repository.
```sh
npm run api:load
```
## playlist:format
Formats internal playlists. The process includes [URL normalization](https://en.wikipedia.org/wiki/URI_normalization), duplicate removal, removing invalid IDs, and sorting links by channel name, quality, and label.
```sh
# format all playlists in the streams/ directory
npm run playlist:format
# format a specific playlist
npm run playlist:format path/to/playlist.m3u
```
## playlist:update
Triggers an update of internal playlists. The process involves processing approved requests from issues.
```sh
npm run playlist:update
```
## playlist:generate
Generates all public playlists.
```sh
npm run playlist:generate
```
## playlist:validate
Checks IDs and links in internal playlists for errors.
```sh
# check all playlists in the streams/ directory
npm run playlist:validate
# check a specific playlist
npm run playlist:validate path/to/playlist.m3u
```
## playlist:lint
Checks internal playlists for syntax errors.
```sh
# check all playlists in the streams/ directory
npm run playlist:lint
# check a specific playlist
npm run playlist:lint path/to/playlist.m3u
```
## playlist:test
Tests links in internal playlists.
```sh
# check all playlists in the streams/ directory
npm run playlist:test
# check a specific playlist
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:
```sh
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 the playlists:
```sh
npm run playlist:test streams/fr.m3u -- --fix
```
## playlist:edit
A utility for quick streams mapping.
```sh
npm run playlist:edit path/to/playlist.m3u
```
## playlist:export
Creates a JSON file with all streams for the [iptv-org/api](https://github.com/iptv-org/api) repository.
```sh
npm run playlist:export
```
## readme:update
Updates the configuration and list of available streams in [PLAYLISTS.md](PLAYLISTS.md).
```sh
npm run readme:update
```
## report:create
Creates a report on current issues.
```sh
npm run report:create
```
## lint
Checks the utility scripts themselves for syntax errors.
```sh
npm run lint
```
## test
Runs a test of all the scripts described above.
```sh
npm test
```
+32
View File
@@ -0,0 +1,32 @@
# Stream Description Scheme
For a stream to be approved, its description must follow this template:
```m3u
#EXTINF:-1 tvg-id="STREAM_ID",STREAM_TITLE (QUALITY) [LABEL]
STREAM_URL
```
| Attribute | Description | Required | Valid values |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- |
| `STREAM_ID` | Stream ID consisting of a channel ID and a feed ID. A full list of supported channels with corresponding IDs can be found on [iptv-org.github.io](https://iptv-org.github.io/). | Optional | `<channel_id>` or `<channel_id>@<feed_id>` |
| `STREAM_TITLE` | Stream title consisting of a channel name and a feed name. May contain any characters except `,`, `[`, or `]`. | 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:
```m3u
#EXTINF:-1 tvg-id="ExampleTV.us@East",Example TV East (720p) [Geo-blocked]
https://example.com/playlist.m3u8
```
Also, if necessary, you can specify a custom [HTTP User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) and [HTTP Referrer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) through the `#EXTVLCOPT` directive:
```m3u
#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
```
+34
View File
@@ -0,0 +1,34 @@
# Stream Testing
To make sure a stream link is working properly, just follow these simple steps:
1. Open it in a media player that supports [HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming) or [DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) streams. In the examples below, we will use [VLC media player](https://www.videolan.org/vlc/index.html).
2. Watch the broadcast for at least a minute. Make sure playback is stable and doesn't stop abruptly (some test streams cut off after 1530 seconds).
3. Try restarting the stream. Make sure it isn't looping on a repeating segment and remains available.
4. Make sure the stream works for others too. You can verify this by using services like [check-host.net](https://check-host.net/) or a [VPN](https://en.wikipedia.org/wiki/Virtual_private_network).
If the stream isn't playing, try opening the player's error log. You can usually find the exact cause there. In VLC, it is located under `Tools -> Messages`.
If the stream won't play in your media player but works fine in a web browser, the issue is likely missing [HTTP User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) and/or [HTTP Referrer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) headers.
In this case, open the stream in your browser. Press `F12`, go to the **Network** tab, and filter the requests for `m3u` or `mpd`:
<img width="338" height="256" alt="image" src="https://github.com/user-attachments/assets/2eec24df-21a4-4a77-8a96-4f967baf2548" />
Then switch to the **Headers** tab, scroll down, and copy the `User-Agent` and `Referer` values:
<img width="660" height="425" alt="image" src="https://github.com/user-attachments/assets/6e0c4453-3e56-4ad3-86a7-c9430c33c188" />
Next, open any text editor and paste the link along with the parameters you found, formatted like this:
```m3u
#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
```
Save the file with `.m3u` extension, then open it in your media player. In most cases, it should work immediately.
To test links that are already in the repository, you can simply run the [playlist:test](./scripts.md#playlisttest) script.
+15
View File
@@ -0,0 +1,15 @@
# Tokenized Links
Tokenized links are personalized hyperlinks that contain a unique, machine-generated string of characters (a token) to grant access to an IPTV stream.
Examples:
- `https://example.com/index.m3u8?token=9f192891-eca5-2435-b9cb-147f376cdc1e`
- `https://example.com/index.m3u8?s=aWE0maGFzaF92YWx1`
- `https://example.com/index.m3u8?wmsAuthSign=c2bWU9Ni8yMC8yMDIVydmVyX3Rp2IDc6MDk6MjAgUmFsaWRtaWE0maGFzaF92YWx1ZTE5SkNSQkhqUG5JZVRRPT0md51dGVzPTMwJmlkPTZhMzZlNT1lRzlsZG4rOXYwZTIzNDk`
The tokens in these links are periodically updated by the provider, causing the link to stop working shortly after.
In some cases, the link also includes an expiration date in [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) format, which indicates exactly when the link will stop working:
`https://example.com/index.m3u8?token=2IDc6MDk6MjAgUmF&e=1813661332` _(`1813661332` => `2027-06-22T10:48:52.000Z`)_
+17
View File
@@ -0,0 +1,17 @@
# Workflows
To automate running the [scripts](./scripts.md), we use [GitHub Actions workflows](https://docs.github.com/en/actions/using-workflows).
Each workflow includes its own set of scripts that can be run either manually or in response to a repository event.
## check
Sequentially runs the `api:load`, `playlist:lint`, and `playlist:validate` scripts whenever a new pull request is opened, blocking the merge if it detects any errors.
## format
Sequentially runs the `api:load`, `playlist:format`, `playlist:lint`, and `playlist:validate` scripts.
## update
Runs every day at 0:00 UTC. It sequentially executes the `api:load`, `playlist:update`, `playlist:lint`, `playlist:validate`, `playlist:generate`, `playlist:export`, and `readme:update` scripts, then automatically deploys the updated files if successful.
+11
View File
@@ -0,0 +1,11 @@
### Xtream Codes
Most Xtream Codes stream links look like this:
`http(s)://{hostname}:{port}/{username}/{password}/{channelID}` _(the port is often `25461`)_
To make sure a link leads to an Xtream Codes server, copy the `hostname`, `port`, `username`, and `password` into the URL format below and try opening it in your browser:
`http(s)://{hostname}:{port}/panel_api.php?username={username}&password={password}`
If the page loads a response, it confirms you are dealing with an Xtream Codes server.
+39 -152
View File
@@ -1,10 +1,12 @@
# Contributing Guide
- [Introduction](#introduction)
- [How to?](#how-to)
- [Stream Description Scheme](#stream-description-scheme)
- [Project Structure](#project-structure)
- [Scripts](#scripts)
- [Workflows](#workflows)
## Introduction
**iptv-org** is more than just a repository for sharing links to live streams. After years of commitment and moderation practices, it has evolved into a knowledge base for [channels](https://github.com/iptv-org/database), [streams](https://github.com/iptv-org/iptv), and [program guides](https://github.com/iptv-org/epg). To keep all this data organized, we must follow strict structural requirements and set certain standards for participants.
## How to?
@@ -12,43 +14,33 @@
You have several options:
1. Create a new request using this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams:add&projects=&template=1_streams_add.yml&title=Add%3A+) and if approved, the link will automatically be added to the playlist on the next update.
1. Create a new request using this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams:add&projects=&template=1_streams_add.yml&title=Add%3A+) and, if approved, the link will automatically be added to the playlist on the next update.
2. Add the link to the playlist directly using a [pull request](https://github.com/iptv-org/iptv/pulls). See [Playlist Structure](./.github/docs/playlist-structure.md).
2. Add the link to the playlist directly using a [pull request](https://github.com/iptv-org/iptv/pulls).
Regardless of which option you choose, please perform the following checks before posting your request:
Regardless of which option you choose, before posting your request please do the following:
- Make sure the link is not already in the playlist by [searching](https://github.com/search?q=repo%3Aiptv-org%2Fiptv+http%3A%2F%2Fexample.com&type=code) the repository.
- Make sure the link you want to add is stable and works properly. See [Stream Testing](./.github/docs/stream-testing.md).
- Make sure the link does not lead to a [Xtream Codes](./.github/docs/xtream-codes.md) server. [Why don't you accept links to Xtream Codes servers?](./FAQ.md#why-dont-you-accept-links-to-xtream-codes-servers).
- Make sure the link is not [tokenized](./.github/docs/tokenized-links.md).
- Make sure the link leads directly to the broadcast without unnecessary redirects.
- Make sure the channel is in our database. This can be verified through [iptv-org.github.io](https://iptv-org.github.io/). If your desired channel is not on the list, you first must add it via a [request](https://github.com/iptv-org/database/issues/new?template=01_channels_add.yml).
- Make sure the channel isn't on our blocklist. This can also be verified through [iptv-org.github.io](https://iptv-org.github.io/).
- Make sure the link you want to add is stable, and works properly. To check this, open it in one of your usual players (for example, [VLC media player](https://www.videolan.org/vlc/index.html)) and watch the broadcast for at least a minute (some test streams are interrupted after 15-30 seconds).
- Make sure the link is not already in the playlist. This can be done by [searching](https://github.com/search?q=repo%3Aiptv-org%2Fiptv+http%3A%2F%2Fexample.com&type=code) the repository.
- Make sure the link does not lead to a Xtream Codes server. [Why don't you accept links to Xtream Codes servers?](FAQ.md#why-dont-you-accept-links-to-xtream-codes-servers). If you're unsure, please check [How to distinguish a link to an Xtream Codes server from a regular one?](#how-to-distinguish-a-link-to-an-xtream-codes-server-from-a-regular-one)
- Make sure that the link leads directly to the broadcast, without unnecessary redirects.
- Find the ID of the channel you want on [iptv-org.github.io](https://iptv-org.github.io/). If your desired channel is not on the list, you must add it via a request [here](https://github.com/iptv-org/database/issues/new/choose).
- Make sure the channel is not blacklisted. It can also be done through [iptv-org.github.io](https://iptv-org.github.io/).
- If you know that the broadcast only works in certain countries or it is periodically interrupted, do not forget to indicate this in the request.
If the broadcast only works in certain countries or is periodically interrupted, please indicate this in your request.
A request without a valid stream ID or working link to the stream will be closed immediately.
Note all links in playlists are sorted automatically by scripts so there is no need to sort them manually. For more info, see [Scripts](#scripts).
**IMPORTANT:** A request without a valid stream ID or a working stream link will be closed immediately.
### How to fix the stream description?
Most of the stream description (channel name, feed name, categories, languages, broadcast area, logo) is loaded from [iptv-org/database](https://github.com/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](https://iptv-org.github.io/). To change the stream ID of any link in the playlist, just fill out this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams%3Aedit&projects=&template=2_streams_edit.yml&title=Edit%3A+).
So there are usually only two reasons for an incorrect description:
If, however, you have found an error in the database itself, please refer to: [How to edit channel description?](https://github.com/iptv-org/database/blob/master/CONTRIBUTING.md#how-to-edit-channel-description)
- **The stream has an incorrect ID:** In that case, all you need is to update the stream ID in the playlist using this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams%3Aedit&projects=&template=2_streams_edit.yml&title=Edit%3A+). A full list of all supported channels and their corresponding IDs can be found on [iptv-org.github.io](https://iptv-org.github.io/).
- **Our database contains incorrect channel information:** You can verify this on [iptv-org.github.io](https://iptv-org.github.io/). If this is the case, please refer to: [How to edit a database entry?](https://github.com/iptv-org/database/blob/master/CONTRIBUTING.md#how-to-edit-a-database-entry).
### How to distinguish a link to an Xtream Codes server from a regular one?
Most of them have this form:
`http(s)://{hostname}:{port}/{username}/{password}/{channelID}` (port is often `25461`)
To make sure that the link leads to the Xtream Codes server, copy the `hostname`, `port`, `username` and `password` into the link below and try to open it in a browser:
`http(s)://{hostname}:{port}/panel_api.php?username={username}&password={password}`
If the link answers, you're with an Xtream Codes server.
Once the changes are approved, the stream description will automatically update across all repositories.
### How to report a broken stream?
@@ -57,136 +49,31 @@ Fill out this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labe
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](https://github.com/search?q=repo%3Aiptv-org%2Fiptv+http%3A%2F%2Fexample.com&type=code) the repository.
- The link really doesn't work and is not just [geo-blocked](https://en.wikipedia.org/wiki/Geo-blocking). To check this, you can either use a [VPN](https://en.wikipedia.org/wiki/Virtual_private_network) or services such as [streamtest.in](https://streamtest.in/).
- The link is completely broken and is not just [geo-blocked](https://en.wikipedia.org/wiki/Geo-blocking). See [Stream Testing](./.github/docs/stream-testing.md).
An issue without a valid link will be closed immediately.
**IMPORTANT:** An issue without a valid stream link will be closed immediately.
### How to find a broken stream?
### How to remove my channel from the playlist?
For starters, you can just try to open the playlist in [VLC media player](https://www.videolan.org/vlc/). The player outputs all errors to the log (Tools -> Messages) so you'll be able to determine pretty accurately why a link isn't working.
To request the removal of a channel link from the repository, please fill out this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=removal+request&projects=&template=6_copyright-claim.yml&title=Remove%3A+) and wait for the request to be reviewed (this usually takes less than 1 business day). If approved, links to the channel will be immediately removed from the repository.
Another way to test links is to use the NPM script. To do this, first make sure you have [Node.js](https://nodejs.org/en) installed on your system. Then go to the `iptv` folder using [Console](https://en.wikipedia.org/wiki/Windows_Console) (or [Terminal](<https://en.wikipedia.org/wiki/Terminal_(macOS)>) if you have macOS) and run the command:
The channel will also be added to our [blocklist](https://github.com/iptv-org/database/blob/master/data/blocklist.csv) to prevent it from reappearing in our playlists in the future.
```sh
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:
```sh
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:
```sh
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](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams:remove&projects=&template=3_streams_report.yml&title=Broken%3A+) or create a [pull request](https://github.com/iptv-org/iptv/pulls) with updated playlists.
### How to remove my channel from playlist?
To request removal of a link to a channel from the repository, you need to fill out this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=removal+request&projects=&template=6_copyright-claim.yml&title=Remove%3A+) 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](https://github.com/iptv-org/database/blob/master/data/blocklist.csv) 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.
## 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 could be found on [iptv-org.github.io](https://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:
```xml
#EXTINF:-1 tvg-id="ExampleTV.us@East",Example TV East (720p) [Not 24/7]
https://example.com/playlist.m3u8
```
Also, if necessary, you can specify custom [HTTP User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) and [HTTP Referrer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) through `#EXTVLCOPT` directive:
```xml
#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
```
**IMPORTANT:** We only accept removal requests from channel owners and their official representatives. All other requests will be closed immediately.
## Project Structure
- `.github/`
- `ISSUE_TEMPLATE/`: issue templates for the repository.
- `workflows`: contains [GitHub actions](https://docs.github.com/en/actions/quickstart) workflows.
- `CODE_OF_CONDUCT.md`: rules you shouldn't break if you don't want to get banned.
- `DISCUSSION_TEMPLATE/`: Contains discussion templates for the repository.
- `ISSUE_TEMPLATE/`: Contains issue templates for the repository.
- `workflows/`: Contains [GitHub Actions](https://docs.github.com/en/actions/quickstart) workflows. See [Workflows](./.github/docs/workflows.md).
- `CODE_OF_CONDUCT.md`: Rules you shouldn't break if you don't want to get banned.
- `.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`: file you are currently reading.
- `PLAYLISTS.md`: auto-updated list of available playlists.
- `README.md`: 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](https://nodejs.org/en) installed on your computer.
To run scripts use the `npm run <script-name>` command.
- `act:check`: allows to run the [check](https://github.com/iptv-org/iptv/blob/master/.github/workflows/check.yml) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
- `act:format`: allows to test the [format](https://github.com/iptv-org/iptv/blob/master/.github/workflows/update.yml) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
- `act:update`: allows to test the [update](https://github.com/iptv-org/iptv/blob/master/.github/workflows/update.yml) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
- `api:load`: downloads the latest channel and stream data from the [iptv-org/api](https://github.com/iptv-org/api).
- `playlist:format`: formats internal playlists. The process includes [URL normalization](https://en.wikipedia.org/wiki/URI_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`: сhecks ids and links in internal playlists for errors.
- `playlist:lint`: сhecks 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](https://github.com/iptv-org/api) repository.
- `readme:update`: updates the list of playlists in [README.md](README.md).
- `report:create`: creates a report on current issues.
- `lint`: сhecks 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](https://docs.github.com/en/actions/using-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 in it.
- `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.
- `preview.png`: Image displayed in the `README.md`.
- `template.md`: Template configuration for `PLAYLISTS.md`.
- `scripts/`: Contains internal utility scripts used in the repository. See [Scripts](./.github/docs/scripts.md).
- `streams/`: Contains internal playlists with all streams. See [Playlist Structure](./.github/docs/playlist-structure.md).
- `tests/`: Contains test suites to validate project scripts.
- `CONTRIBUTING.md`: The file you are currently reading.
- `PLAYLISTS.md`: Automatically updated list of available playlists.
- `README.md`: Project description and documentation overview.