From 120cf4801c46660adabd840fc48eb45165f1d70f Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Mon, 22 Jun 2026 18:07:21 +0300 Subject: [PATCH] Create .github/docs --- .github/docs/playlist-structure.md | 13 ++ .github/docs/scripts.md | 191 ++++++++++++++++++++++ .github/docs/stream-description-scheme.md | 32 ++++ .github/docs/stream-testing.md | 34 ++++ .github/docs/tokenized-links.md | 15 ++ .github/docs/workflows.md | 17 ++ .github/docs/xtreme-codes.md | 11 ++ 7 files changed, 313 insertions(+) create mode 100644 .github/docs/playlist-structure.md create mode 100644 .github/docs/scripts.md create mode 100644 .github/docs/stream-description-scheme.md create mode 100644 .github/docs/stream-testing.md create mode 100644 .github/docs/tokenized-links.md create mode 100644 .github/docs/workflows.md create mode 100644 .github/docs/xtreme-codes.md diff --git a/.github/docs/playlist-structure.md b/.github/docs/playlist-structure.md new file mode 100644 index 0000000000..80a395a6ab --- /dev/null +++ b/.github/docs/playlist-structure.md @@ -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 diff --git a/.github/docs/scripts.md b/.github/docs/scripts.md new file mode 100644 index 0000000000..95068c86a7 --- /dev/null +++ b/.github/docs/scripts.md @@ -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 +``` diff --git a/.github/docs/stream-description-scheme.md b/.github/docs/stream-description-scheme.md new file mode 100644 index 0000000000..d28c704af1 --- /dev/null +++ b/.github/docs/stream-description-scheme.md @@ -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 | `` or `@` | +| `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 +``` diff --git a/.github/docs/stream-testing.md b/.github/docs/stream-testing.md new file mode 100644 index 0000000000..6bfc5141cd --- /dev/null +++ b/.github/docs/stream-testing.md @@ -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 15–30 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`: + +image + +Then switch to the **Headers** tab, scroll down, and copy the `User-Agent` and `Referer` values: + +image + +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. diff --git a/.github/docs/tokenized-links.md b/.github/docs/tokenized-links.md new file mode 100644 index 0000000000..452630def0 --- /dev/null +++ b/.github/docs/tokenized-links.md @@ -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`)_ diff --git a/.github/docs/workflows.md b/.github/docs/workflows.md new file mode 100644 index 0000000000..4ca3d326d7 --- /dev/null +++ b/.github/docs/workflows.md @@ -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. diff --git a/.github/docs/xtreme-codes.md b/.github/docs/xtreme-codes.md new file mode 100644 index 0000000000..6173ec1601 --- /dev/null +++ b/.github/docs/xtreme-codes.md @@ -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.