mirror of
https://github.com/iptv-org/iptv
synced 2026-09-08 21:07:48 -04:00
Patch 2026.09.2 (#50642)
* Move docs/ to root directory * Fix file name * Update scripts.md * Delete playlist-structure.md * Create playlists.md * Update stream-testing.md * Create geo-blocking.md * Create stream-id.md * Update CONTRIBUTING.md
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# Geo-blocking
|
||||
|
||||
Sometimes providers block streams from being played in certain countries or regions.
|
||||
|
||||
To avoid confusing these links with broken ones, we mark them with the label `Geo-blocked`:
|
||||
|
||||
```m3u
|
||||
#EXTINF:-1 tvg-id="ExampleTV.us@SD",Example TV (720p) [Geo-blocked]
|
||||
https://example.com/playlist.m3u8
|
||||
```
|
||||
|
||||
The easiest way to make sure the stream works outside your country is to use services like [check-host.net](https://check-host.net/check-http) or a [VPN](https://en.wikipedia.org/wiki/Virtual_private_network).
|
||||
@@ -0,0 +1,51 @@
|
||||
# Playlists
|
||||
|
||||
The repository uses two types of playlists: internal and public.
|
||||
|
||||
## Internal
|
||||
|
||||
These playlists are located in the [streams/](../streams) folder and contain all links currently available in the repository.
|
||||
|
||||
The links in these playlists are grouped by country and by the service from which the stream is broadcast. They are arranged this way solely for the convenience of moderating links.
|
||||
|
||||
In its simplest form, an internal playlist looks like this:
|
||||
|
||||
```
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="ExampleTV.us@SD",Example TV (720p)
|
||||
https://example.com/playlist.m3u8
|
||||
```
|
||||
|
||||
If there is a guide for one of the channels in the playlist in our [EPG](https://github.com/iptv-org/epg/blob/master/GUIDES.md) repository, the header will also include a link to it:
|
||||
|
||||
```
|
||||
#EXTM3U x-tvg-url="https://example.com/guide.xml"
|
||||
```
|
||||
|
||||
Since these playlists are processed primarily using scripts, we need to follow a few rules when editing them:
|
||||
|
||||
- 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
|
||||
|
||||
## Public
|
||||
|
||||
Unlike internal playlists, these playlists are created specifically for regular users.
|
||||
|
||||
They are generated automatically using the [playlist:generate](./scripts.md#playlistgenerate) script every day at 00:00 UTC and then placed in a separate branch of [gh-pages](https://github.com/iptv-org/iptv/tree/gh-pages).
|
||||
|
||||
The links in these playlists are organized solely based on the channel's description in our [database](https://github.com/iptv-org/database). For example, if a channel's broadcast area is listed as `c/IT`, the link to its stream will automatically be placed in the `countries/it.m3u` file.
|
||||
|
||||
Another difference from internal playlists is that public playlists include only the best available option for each channel, based on stream quality and labels. The exception is playlists in the `raw/` folder.
|
||||
|
||||
Additionally, if the link includes a valid [stream ID](./stream-id.md), the channel logo, category, broadcast country and language will be added to the description. For example:
|
||||
|
||||
```
|
||||
#EXTM3U x-tvg-url="https://example.com/guide.xml”
|
||||
#EXTINF:-1 tvg-id="ExampleTV.us@SD” tvg-logo="https://example.com/logo.png” group-title="Movies”,Example TV (720p)
|
||||
https://example.com/playlist.m3u8
|
||||
```
|
||||
|
||||
A complete list of public playlists can always be found in [PLAYLISTS.md](../PLAYLISTS.md).
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
# 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)
|
||||
- [act:validate_issue](#actvalidate_issue)
|
||||
- [act:validate_label](#actvalidate_label)
|
||||
- [api:load](#apiload)
|
||||
- [issue:validate](#issuevalidate)
|
||||
- [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
|
||||
```
|
||||
|
||||
## act:validate_issue
|
||||
|
||||
Runs the [validate_issue](./workflows.md#validate_issue) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
|
||||
|
||||
```sh
|
||||
npm run act:validate_issue -- -e .github/mocks/events/issue_opened.json
|
||||
```
|
||||
|
||||
## act:validate_label
|
||||
|
||||
Runs the [validate_label](./workflows.md#validate_label) workflow locally. Depends on [nektos/gh-act](https://github.com/nektos/gh-act).
|
||||
|
||||
```sh
|
||||
npm run act:validate_label -- -e .github/mocks/events/issue_approved.json --actor Bob
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
## issue:validate
|
||||
|
||||
Checks the request for errors and, if any are found, saves a list of them to the file `temp/logs/errors.txt`
|
||||
|
||||
```sh
|
||||
npm run issue:validate --body="### Stream URL..." --labels="streams:add"
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
@@ -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
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
# Stream ID
|
||||
|
||||
A stream ID is a unique identifier for a stream that consists of a channel ID and a feed ID separated by the `@` symbol.
|
||||
|
||||
```
|
||||
ExampleTV.us@HD
|
||||
```
|
||||
|
||||
## Channel ID
|
||||
|
||||
This is a unique channel ID that consists of the channel name (without spaces or special characters) followed by the country code, separated by a period.
|
||||
|
||||
```
|
||||
ExampleTV.us
|
||||
```
|
||||
|
||||
## Feed ID
|
||||
|
||||
The Feed ID is simply the name of the feed with all spaces and special characters removed.
|
||||
|
||||
It usually indicates the broadcast quality, time shift, source, or broadcast region. For example:
|
||||
|
||||
- HD
|
||||
- Plus1
|
||||
- Pluto
|
||||
- WGTQ
|
||||
- East
|
||||
- MENA
|
||||
|
||||
A complete list of all channel and feed IDs can always be found on [iptv-org.github.io](https://iptv-org.github.io/).
|
||||
|
||||
If a particular channel is not on the list, you can always add it using this [form](https://github.com/iptv-org/database/issues/new?template=01_channels_add.yml). Similarly, you can use this [form](https://github.com/iptv-org/database/issues/new?template=04_feeds_add.yml) to add a missing feed.
|
||||
@@ -0,0 +1,33 @@
|
||||
# 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 15–30 seconds).
|
||||
3. Try restarting the stream. Make sure it isn't looping on a repeating segment and remains available.
|
||||
|
||||
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.
|
||||
@@ -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`)_
|
||||
@@ -0,0 +1,25 @@
|
||||
# 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.
|
||||
|
||||
## validate_issue
|
||||
|
||||
Runs when an issue is opened or edited. It checks the requests for errors using `issue:validate` script and, if any are found, the bot posts them in the comments.
|
||||
|
||||
## validate_label
|
||||
|
||||
Triggers when a new label is added to an issue. It checks the label, and if it's incorrect, the bot deletes it and leaves a comment explaining why.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user