mirror of
https://github.com/iptv-org/iptv
synced 2026-04-03 09:41:35 -04:00
Merge pull request #29894 from iptv-org/patch-2025.12.1
Patch 2025.12.1
This commit is contained in:
7
.github/ISSUE_TEMPLATE/1_streams_add.yml
vendored
7
.github/ISSUE_TEMPLATE/1_streams_add.yml
vendored
@@ -60,13 +60,6 @@ body:
|
||||
label: HTTP Referrer
|
||||
placeholder: 'https://example.com/'
|
||||
|
||||
- type: textarea
|
||||
id: directives
|
||||
attributes:
|
||||
label: Directives
|
||||
description: 'List of directives telling players how to play the stream. Supported `#KODIPROP` and `#EXTVLCOPT`.'
|
||||
placeholder: '#KODIPROP:inputstream=inputstream.adaptive'
|
||||
|
||||
- type: textarea
|
||||
id: notes
|
||||
attributes:
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/2_streams_edit.yml
vendored
14
.github/ISSUE_TEMPLATE/2_streams_edit.yml
vendored
@@ -18,13 +18,6 @@ body:
|
||||
value: |
|
||||
What exactly needs to be changed? To delete an existing value without replacement use the `~` symbol.
|
||||
|
||||
- type: input
|
||||
id: new_stream_url
|
||||
attributes:
|
||||
label: New Stream URL
|
||||
description: New link to the stream
|
||||
placeholder: 'https://servilive.com:3126/live/tele2000live.m3u8'
|
||||
|
||||
- type: input
|
||||
id: stream_id
|
||||
attributes:
|
||||
@@ -72,13 +65,6 @@ body:
|
||||
label: HTTP Referrer
|
||||
placeholder: 'https://example.com/'
|
||||
|
||||
- type: textarea
|
||||
id: directives
|
||||
attributes:
|
||||
label: Directives
|
||||
description: 'List of directives telling players how to play the stream. Supported `#KODIPROP` and `#EXTVLCOPT`.'
|
||||
placeholder: '#KODIPROP:inputstream=inputstream.adaptive'
|
||||
|
||||
- type: textarea
|
||||
id: notes
|
||||
attributes:
|
||||
|
||||
10
.github/workflows/check.yml
vendored
10
.github/workflows/check.yml
vendored
@@ -6,8 +6,6 @@ on:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
packages: read
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -18,7 +16,7 @@ jobs:
|
||||
run: |
|
||||
git fetch origin master:master
|
||||
ANY_CHANGED=false
|
||||
ALL_CHANGED_FILES=$(git diff --name-only master -- streams/ | tr '\n' ' ')
|
||||
ALL_CHANGED_FILES=$(git diff --diff-filter=ACMRT --name-only master -- streams/ | tr '\n' ' ')
|
||||
if [ -n "${ALL_CHANGED_FILES}" ]; then
|
||||
ANY_CHANGED=true
|
||||
fi
|
||||
@@ -29,12 +27,6 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'npm'
|
||||
- name: Setup .npmrc for GitHub Packages
|
||||
if: steps.files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc
|
||||
echo "@iptv-org:registry=https://npm.pkg.github.com/" >> .npmrc
|
||||
echo "always-auth=true" >> .npmrc
|
||||
- name: Install dependencies
|
||||
if: steps.files.outputs.any_changed == 'true'
|
||||
run: npm install
|
||||
|
||||
9
.github/workflows/format.yml
vendored
9
.github/workflows/format.yml
vendored
@@ -3,8 +3,6 @@ on:
|
||||
workflow_dispatch:
|
||||
# schedule:
|
||||
# - cron: "0 12 * * *"
|
||||
permissions:
|
||||
packages: read
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -24,11 +22,6 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'npm'
|
||||
- name: Setup .npmrc for GitHub Packages
|
||||
run: |
|
||||
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc
|
||||
echo "@iptv-org:registry=https://npm.pkg.github.com/" >> .npmrc
|
||||
echo "always-auth=true" >> .npmrc
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Format internal playlists
|
||||
@@ -41,7 +34,7 @@ jobs:
|
||||
id: files_after
|
||||
run: |
|
||||
ANY_CHANGED=false
|
||||
ALL_CHANGED_FILES=$(git diff --name-only master -- streams/ | tr '\n' ' ')
|
||||
ALL_CHANGED_FILES=$(git diff --diff-filter=ACMRT --name-only master -- streams/ | tr '\n' ' ')
|
||||
if [ -n "${ALL_CHANGED_FILES}" ]; then
|
||||
ANY_CHANGED=true
|
||||
fi
|
||||
|
||||
11
.github/workflows/update.yml
vendored
11
.github/workflows/update.yml
vendored
@@ -3,8 +3,6 @@ on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
permissions:
|
||||
packages: read
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -24,11 +22,6 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
cache: 'npm'
|
||||
- name: Setup .npmrc for GitHub Packages
|
||||
run: |
|
||||
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc
|
||||
echo "@iptv-org:registry=https://npm.pkg.github.com/" >> .npmrc
|
||||
echo "always-auth=true" >> .npmrc
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Update internal playlists
|
||||
@@ -40,8 +33,8 @@ jobs:
|
||||
npm run playlist:validate
|
||||
- name: Generate public playlists
|
||||
run: npm run playlist:generate
|
||||
- name: Generate .api/streams.json
|
||||
run: npm run api:generate
|
||||
- name: Create .api/streams.json
|
||||
run: npm run playlist:export
|
||||
- name: Update readme
|
||||
run: npm run readme:update
|
||||
- name: Setup git
|
||||
|
||||
7
.prettierrc
Normal file
7
.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -20,9 +20,10 @@ Regardless of which option you choose, before posting your request please do the
|
||||
|
||||
- Make sure the link you want to add works stably. To check this, open it in one of the players (for example, [VLC 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 the Xtream Codes server. [Why don't you accept links to Xtream Codes server?](FAQ.md#why-dont-you-accept-links-to-xtream-codes-server)
|
||||
- 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 can leave a request to add it [here](https://github.com/iptv-org/database/issues/new/choose).
|
||||
- Make sure the channel is not blocklisted. It can also be done through [iptv-org.github.io](https://iptv-org.github.io/).
|
||||
- The link does not lead to the Xtream Codes server. [Why don't you accept links to Xtream Codes server?](FAQ.md#why-dont-you-accept-links-to-xtream-codes-server)
|
||||
- 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.
|
||||
|
||||
A requests without a valid stream ID or working link to the stream will be closed immediately.
|
||||
@@ -129,33 +130,15 @@ Example:
|
||||
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 additional attributes:
|
||||
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" http-referrer="http://example.com/" http-user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64)",Example TV
|
||||
http://example.com/stream.m3u8
|
||||
```
|
||||
|
||||
or use player-specific directives:
|
||||
|
||||
_VLC_
|
||||
|
||||
```xml
|
||||
#EXTINF:-1 tvg-id="ExampleTV.us@VLC",Example TV
|
||||
#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
|
||||
```
|
||||
|
||||
_Kodi_
|
||||
|
||||
```xml
|
||||
#EXTINF:-1 tvg-id="ExampleTV.us@Kodi",Example TV
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.stream_headers=Referer=http://example.com/&User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64)
|
||||
http://example.com/stream.m3u8
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `.github/`
|
||||
@@ -185,8 +168,6 @@ To run scripts use the `npm run <script-name>` command.
|
||||
- `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).
|
||||
- `api:generate`: generates a JSON file with all streams for the [iptv-org/api](https://github.com/iptv-org/api) repository.
|
||||
- `api:deploy`: allows to manually upload a JSON file created via `api:generate` to the [iptv-org/api](https://github.com/iptv-org/api) repository. To run the script you must provide your [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) with write access to the repository.
|
||||
- `playlist:format`: formats internal playlists. The process includes [URL normalization](https://en.wikipedia.org/wiki/URI_normalization), duplicate removal, removing invalid id's 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.
|
||||
@@ -194,13 +175,9 @@ To run scripts use the `npm run <script-name>` command.
|
||||
- `playlist:lint`: сhecks internal playlists for syntax errors.
|
||||
- `playlist:test`: tests links in internal playlists.
|
||||
- `playlist:edit`: utility for quick streams mapping.
|
||||
- `playlist:deploy`: allows to manually publish all generated via `playlist:generate` playlists. To run the script you must provide your [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) with write access to the repository.
|
||||
- `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.
|
||||
- `check`: (shorthand) sequentially runs the `playlist:lint` and `playlist:validate` scripts.
|
||||
- `format`: (shorthand) runs the `playlist:format` script.
|
||||
- `update`: (shorthand) sequentially runs the `playlist:generate`, `api:generate` and `readme:update` scripts.
|
||||
- `deploy`: (shorthand) sequentially runs the `playlist:deploy` and `api:deploy` scripts.
|
||||
- `lint`: сhecks the scripts for syntax errors.
|
||||
- `test`: runs a test of all the scripts described above.
|
||||
|
||||
@@ -212,4 +189,4 @@ Each workflow includes its own set of scripts that can be run either manually or
|
||||
|
||||
- `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`, `api:generate` and `readme:update` scripts and deploys the output files if successful.
|
||||
- `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.
|
||||
|
||||
@@ -50,7 +50,7 @@ Links to other useful IPTV-related resources can be found in the [iptv-org/aweso
|
||||
|
||||
## Discussions
|
||||
|
||||
If you need help finding a channel, have a question or idea, welcome to the [Discussions](https://github.com/orgs/iptv-org/discussions).
|
||||
If you have a question or idea, welcome to the [Discussions](https://github.com/orgs/iptv-org/discussions).
|
||||
|
||||
## FAQ
|
||||
|
||||
|
||||
87
package-lock.json
generated
87
package-lock.json
generated
@@ -15,7 +15,7 @@
|
||||
"@freearhey/search-js": "^0.1.2",
|
||||
"@freearhey/storage-js": "^0.1.0",
|
||||
"@inquirer/prompts": "^7.8.0",
|
||||
"@iptv-org/sdk": "^1.0.2",
|
||||
"@iptv-org/sdk": "^1.1.3",
|
||||
"@octokit/core": "^7.0.3",
|
||||
"@octokit/plugin-paginate-rest": "^13.1.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^16.0.0",
|
||||
@@ -1501,18 +1501,35 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@iptv-org/sdk": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://npm.pkg.github.com/download/@iptv-org/sdk/1.0.2/131e5145ff68ffb5e213eb02d26d43db91a8a5a3",
|
||||
"integrity": "sha512-Lpq+5vko9HkqOMDaXpeLBzKVgJikuKax7dJgBjr+XIgxRgMB1gucCjbvTNCR5AHhnORWvX+LFaodzy06jKukOA==",
|
||||
"license": "UNLICENSED",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@iptv-org/sdk/-/sdk-1.1.3.tgz",
|
||||
"integrity": "sha512-e2IQWPVpNdMJnCkJulnBpiU2Hn5hpaSKNTxo4bvOI4uMRRXR7R8hWbm9jtJnf5LYQ6xdN0xT52EjI0zi9dh5yg==",
|
||||
"dependencies": {
|
||||
"@freearhey/core": "^0.14.3",
|
||||
"@freearhey/core": "^0.15.1",
|
||||
"@freearhey/search-js": "^0.2.0",
|
||||
"@ntlab/sfetch": "^1.2.0",
|
||||
"axios": "^1.11.0",
|
||||
"dayjs": "^1.11.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@iptv-org/sdk/node_modules/@freearhey/core": {
|
||||
"version": "0.15.1",
|
||||
"resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.15.1.tgz",
|
||||
"integrity": "sha512-wYquasgTNGsLGDXPjHlPMvwfuoG9kgy9sEWsEc/i4Z2T2uKCfTboHYola9Ykh9X1lGlECypq8lL0IBAiOhKE/w==",
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.198",
|
||||
"@types/pako": "^2.0.3",
|
||||
"consola": "^3.4.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"glob": "^11.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"natural-orderby": "^5.0.0",
|
||||
"normalize-url": "^8.1.0",
|
||||
"object-treeify": "^2.1.1",
|
||||
"pako": "^2.1.0",
|
||||
"timer-node": "^5.0.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@iptv-org/sdk/node_modules/@freearhey/search-js": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@freearhey/search-js/-/search-js-0.2.0.tgz",
|
||||
@@ -1528,7 +1545,6 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
||||
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
@@ -1537,7 +1553,6 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
|
||||
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@isaacs/balanced-match": "^4.0.1"
|
||||
},
|
||||
@@ -1653,10 +1668,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"license": "MIT",
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
@@ -2007,10 +2021,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/reporters/node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"license": "ISC",
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
@@ -4829,14 +4842,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
|
||||
"integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
|
||||
"license": "ISC",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
|
||||
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.3.1",
|
||||
"jackspeak": "^4.1.1",
|
||||
"minimatch": "^10.0.3",
|
||||
"minimatch": "^10.1.1",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^2.0.0"
|
||||
@@ -4863,10 +4875,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/minimatch": {
|
||||
"version": "10.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
|
||||
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
|
||||
"license": "ISC",
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
|
||||
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
|
||||
"dependencies": {
|
||||
"@isaacs/brace-expansion": "^5.0.0"
|
||||
},
|
||||
@@ -5467,10 +5478,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-config/node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"license": "ISC",
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
@@ -5936,10 +5946,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-runtime/node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"license": "ISC",
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
@@ -6218,9 +6227,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
@@ -7707,9 +7716,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.15.0",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.0.tgz",
|
||||
"integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==",
|
||||
"version": "13.15.23",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz",
|
||||
"integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
|
||||
10
package.json
10
package.json
@@ -5,8 +5,6 @@
|
||||
"act:format": "gh act workflow_dispatch -W .github/workflows/format.yml",
|
||||
"act:update": "gh act workflow_dispatch -W .github/workflows/update.yml",
|
||||
"api:load": "tsx scripts/commands/api/load.ts",
|
||||
"api:generate": "tsx scripts/commands/api/generate.ts",
|
||||
"api:deploy": "npx gh-pages-clean && npx gh-pages -a -m \"Deploy to iptv-org/api\" -d .api -r https://$GITHUB_TOKEN@github.com/iptv-org/api.git",
|
||||
"playlist:format": "tsx scripts/commands/playlist/format.ts",
|
||||
"playlist:update": "tsx scripts/commands/playlist/update.ts",
|
||||
"playlist:generate": "tsx scripts/commands/playlist/generate.ts",
|
||||
@@ -14,13 +12,9 @@
|
||||
"playlist:lint": "npx m3u-linter -c m3u-linter.json",
|
||||
"playlist:test": "tsx scripts/commands/playlist/test.ts",
|
||||
"playlist:edit": "tsx scripts/commands/playlist/edit.ts",
|
||||
"playlist:deploy": "npx gh-pages-clean && npx gh-pages -m \"Deploy to GitHub Pages\" -d .gh-pages -r https://$GITHUB_TOKEN@github.com/iptv-org/iptv.git",
|
||||
"playlist:export": "tsx scripts/commands/playlist/export.ts",
|
||||
"readme:update": "tsx scripts/commands/readme/update.ts",
|
||||
"report:create": "tsx scripts/commands/report/create.ts",
|
||||
"check": "npm run playlist:lint && npm run playlist:validate",
|
||||
"format": "npm run playlist:format",
|
||||
"update": "npm run playlist:generate && npm run api:generate && npm run readme:update",
|
||||
"deploy": "npm run playlist:deploy && npm run api:deploy",
|
||||
"lint": "npx eslint \"scripts/**/*.{ts,js}\" \"tests/**/*.{ts,js}\"",
|
||||
"test": "jest --runInBand",
|
||||
"postinstall": "npm run api:load"
|
||||
@@ -45,7 +39,7 @@
|
||||
"@freearhey/search-js": "^0.1.2",
|
||||
"@freearhey/storage-js": "^0.1.0",
|
||||
"@inquirer/prompts": "^7.8.0",
|
||||
"@iptv-org/sdk": "^1.0.2",
|
||||
"@iptv-org/sdk": "^1.1.3",
|
||||
"@octokit/core": "^7.0.3",
|
||||
"@octokit/plugin-paginate-rest": "^13.1.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^16.0.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PlaylistParser, StreamTester, CliTable } from '../../core'
|
||||
import type { TestResult } from '../../core/streamTester'
|
||||
import type { StreamTesterResult } from '../../core/streamTester'
|
||||
import { ROOT_DIR, STREAMS_DIR } from '../../constants'
|
||||
import { Logger, Collection } from '@freearhey/core'
|
||||
import { program, OptionValues } from 'commander'
|
||||
@@ -92,10 +92,10 @@ async function runTest(stream: Stream) {
|
||||
const key = stream.getUniqKey()
|
||||
results[key] = chalk.white('LOADING...')
|
||||
|
||||
const result: TestResult = await tester.test(stream)
|
||||
const result: StreamTesterResult = await tester.test(stream)
|
||||
|
||||
let status = ''
|
||||
const errorStatusCodes = ['ENOTFOUND', 'HTTP_404_NOT_FOUND']
|
||||
const errorStatusCodes = ['ENOTFOUND', 'HTTP_404_NOT_FOUND', 'HTTP_404_UNKONWN_ERROR']
|
||||
if (result.status.ok) status = chalk.green('OK')
|
||||
else if (errorStatusCodes.includes(result.status.code)) {
|
||||
status = chalk.red(result.status.code)
|
||||
@@ -144,7 +144,7 @@ function drawTable() {
|
||||
}
|
||||
}
|
||||
|
||||
function onFinish(error: Error) {
|
||||
function onFinish(error: Error | null | undefined) {
|
||||
clearInterval(interval)
|
||||
|
||||
if (error) {
|
||||
|
||||
@@ -71,9 +71,9 @@ async function removeStreams({
|
||||
|
||||
requests.forEach((issue: Issue) => {
|
||||
const data = issue.data
|
||||
if (data.missing('streamUrl')) return
|
||||
if (data.missing('stream_url')) return
|
||||
|
||||
const streamUrls = data.getString('streamUrl') || ''
|
||||
const streamUrls = data.getString('stream_url') || ''
|
||||
|
||||
let changed = false
|
||||
streamUrls
|
||||
@@ -104,14 +104,14 @@ async function editStreams({
|
||||
requests.forEach((issue: Issue) => {
|
||||
const data = issue.data
|
||||
|
||||
if (data.missing('streamUrl')) return
|
||||
if (data.missing('stream_url')) return
|
||||
|
||||
const stream: Stream = streams.first(
|
||||
(_stream: Stream) => _stream.url === data.getString('streamUrl')
|
||||
(_stream: Stream) => _stream.url === data.getString('stream_url')
|
||||
)
|
||||
if (!stream) return
|
||||
|
||||
const streamId = data.getString('streamId') || ''
|
||||
const streamId = data.getString('stream_id') || ''
|
||||
const [channelId, feedId] = streamId.split('@')
|
||||
|
||||
if (channelId) {
|
||||
@@ -138,12 +138,12 @@ async function addStreams({
|
||||
)
|
||||
requests.forEach((issue: Issue) => {
|
||||
const data = issue.data
|
||||
if (data.missing('streamId') || data.missing('streamUrl')) return
|
||||
if (streams.includes((_stream: Stream) => _stream.url === data.getString('streamUrl'))) return
|
||||
const streamUrl = data.getString('streamUrl') || ''
|
||||
if (data.missing('stream_id') || data.missing('stream_url')) return
|
||||
if (streams.includes((_stream: Stream) => _stream.url === data.getString('stream_url'))) return
|
||||
const streamUrl = data.getString('stream_url') || ''
|
||||
if (!isURI(streamUrl)) return
|
||||
|
||||
const streamId = data.getString('streamId') || ''
|
||||
const streamId = data.getString('stream_id') || ''
|
||||
const [channelId, feedId] = streamId.split('@')
|
||||
|
||||
const channel: sdk.Models.Channel | undefined = apiData.channelsKeyById.get(channelId)
|
||||
@@ -151,9 +151,8 @@ async function addStreams({
|
||||
|
||||
const label = data.getString('label') || ''
|
||||
const quality = data.getString('quality') || null
|
||||
const httpUserAgent = data.getString('httpUserAgent') || null
|
||||
const httpReferrer = data.getString('httpReferrer') || null
|
||||
const directives = data.getArray('directives') || []
|
||||
const httpUserAgent = data.getString('http_user_agent') || null
|
||||
const httpReferrer = data.getString('http_referrer') || null
|
||||
|
||||
const stream = new Stream({
|
||||
channel: channelId,
|
||||
@@ -166,7 +165,7 @@ async function addStreams({
|
||||
})
|
||||
|
||||
stream.label = label
|
||||
stream.setDirectives(directives).updateTitle().updateFilepath()
|
||||
stream.updateTitle().updateFilepath()
|
||||
|
||||
streams.add(stream)
|
||||
processedIssues.add(issue.number)
|
||||
|
||||
@@ -31,8 +31,8 @@ async function main() {
|
||||
const streams = await parser.parse(files)
|
||||
logger.info(`found ${streams.count()} streams`)
|
||||
|
||||
let errors = new Collection()
|
||||
let warnings = new Collection()
|
||||
const errors = new Collection()
|
||||
const warnings = new Collection()
|
||||
const streamsGroupedByFilepath = streams.groupBy((stream: Stream) => stream.getFilepath())
|
||||
for (const filepath of streamsGroupedByFilepath.keys()) {
|
||||
const streams = streamsGroupedByFilepath.get(filepath)
|
||||
@@ -97,8 +97,10 @@ async function main() {
|
||||
console.log(` ${chalk.gray(position)}${status}${logItem.message}`)
|
||||
})
|
||||
|
||||
errors = errors.concat(log.filter((logItem: LogItem) => logItem.type === 'error'))
|
||||
warnings = warnings.concat(log.filter((logItem: LogItem) => logItem.type === 'warning'))
|
||||
log.forEach((logItem: LogItem) => {
|
||||
if (logItem.type === 'error') errors.add(logItem)
|
||||
else if (logItem.type === 'warning') warnings.add(logItem)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ async function main() {
|
||||
issue.labels.find((label: string) => label === 'streams:remove')
|
||||
)
|
||||
removeRequests.forEach((issue: Issue) => {
|
||||
const streamUrls = issue.data.getArray('streamUrl') || []
|
||||
const streamUrls = issue.data.getArray('stream_url') || []
|
||||
|
||||
if (!streamUrls.length) {
|
||||
const result = {
|
||||
@@ -82,8 +82,8 @@ async function main() {
|
||||
const addRequests = issues.filter(issue => issue.labels.includes('streams:add'))
|
||||
const addRequestsBuffer = new Dictionary()
|
||||
addRequests.forEach((issue: Issue) => {
|
||||
const streamId = issue.data.getString('streamId') || ''
|
||||
const streamUrl = issue.data.getString('streamUrl') || ''
|
||||
const streamId = issue.data.getString('stream_id') || ''
|
||||
const streamUrl = issue.data.getString('stream_url') || ''
|
||||
const [channelId] = streamId.split('@')
|
||||
|
||||
const result = {
|
||||
@@ -114,8 +114,8 @@ async function main() {
|
||||
issue.labels.find((label: string) => label === 'streams:edit')
|
||||
)
|
||||
editRequests.forEach((issue: Issue) => {
|
||||
const streamId = issue.data.getString('streamId') || ''
|
||||
const streamUrl = issue.data.getString('streamUrl') || ''
|
||||
const streamId = issue.data.getString('stream_id') || ''
|
||||
const streamUrl = issue.data.getString('stream_url') || ''
|
||||
const [channelId] = streamId.split('@')
|
||||
|
||||
const result = {
|
||||
@@ -140,7 +140,7 @@ async function main() {
|
||||
)
|
||||
const channelSearchRequestsBuffer = new Dictionary()
|
||||
channelSearchRequests.forEach((issue: Issue) => {
|
||||
const streamId = issue.data.getString('streamId') || issue.data.getString('channelId') || ''
|
||||
const streamId = issue.data.getString('stream_id') || issue.data.getString('channel_id') || ''
|
||||
const [channelId, feedId] = streamId.split('@')
|
||||
|
||||
const result = {
|
||||
|
||||
@@ -3,20 +3,18 @@ import { IssueData } from './issueData'
|
||||
import { Issue } from '../models'
|
||||
|
||||
const FIELDS = new Dictionary({
|
||||
'Stream ID': 'streamId',
|
||||
'Channel ID': 'channelId',
|
||||
'Feed ID': 'feedId',
|
||||
'Stream URL': 'streamUrl',
|
||||
'New Stream URL': 'newStreamUrl',
|
||||
'Stream ID': 'stream_id',
|
||||
'Channel ID': 'channel_id',
|
||||
'Feed ID': 'feed_id',
|
||||
'Stream URL': 'stream_url',
|
||||
Label: 'label',
|
||||
Quality: 'quality',
|
||||
'HTTP User-Agent': 'httpUserAgent',
|
||||
'HTTP User Agent': 'httpUserAgent',
|
||||
'HTTP Referrer': 'httpReferrer',
|
||||
'HTTP User-Agent': 'http_user_agent',
|
||||
'HTTP User Agent': 'http_user_agent',
|
||||
'HTTP Referrer': 'http_referrer',
|
||||
'What happened to the stream?': 'reason',
|
||||
Reason: 'reason',
|
||||
Notes: 'notes',
|
||||
Directives: 'directives'
|
||||
Notes: 'notes'
|
||||
})
|
||||
|
||||
export class IssueParser {
|
||||
|
||||
@@ -20,7 +20,9 @@ export class PlaylistParser {
|
||||
for (const filepath of files) {
|
||||
if (!this.storage.existsSync(filepath)) continue
|
||||
const _parsed: Collection<Stream> = await this.parseFile(filepath)
|
||||
parsed.concat(_parsed)
|
||||
_parsed.forEach((item: Stream) => {
|
||||
parsed.add(item)
|
||||
})
|
||||
}
|
||||
|
||||
return parsed
|
||||
|
||||
@@ -25,7 +25,9 @@ export class LanguagesGenerator implements Generator {
|
||||
|
||||
const languages = new Collection<sdk.Models.Language>()
|
||||
streams.forEach((stream: Stream) => {
|
||||
languages.concat(stream.getLanguages())
|
||||
stream.getLanguages().forEach((language: sdk.Models.Language) => {
|
||||
languages.add(language)
|
||||
})
|
||||
})
|
||||
|
||||
languages
|
||||
|
||||
@@ -7,7 +7,6 @@ import { data } from '../api'
|
||||
import path from 'node:path'
|
||||
|
||||
export class Stream extends sdk.Models.Stream {
|
||||
directives: Collection<string>
|
||||
filepath?: string
|
||||
line?: number
|
||||
groupTitle: string = 'Undefined'
|
||||
@@ -19,18 +18,14 @@ export class Stream extends sdk.Models.Stream {
|
||||
const data = {
|
||||
label: issueData.getString('label'),
|
||||
quality: issueData.getString('quality'),
|
||||
httpUserAgent: issueData.getString('httpUserAgent'),
|
||||
httpReferrer: issueData.getString('httpReferrer'),
|
||||
newStreamUrl: issueData.getString('newStreamUrl'),
|
||||
directives: issueData.getArray('directives')
|
||||
httpUserAgent: issueData.getString('http_user_agent'),
|
||||
httpReferrer: issueData.getString('http_referrer')
|
||||
}
|
||||
|
||||
if (data.label !== undefined) this.label = data.label
|
||||
if (data.quality !== undefined) this.quality = data.quality
|
||||
if (data.httpUserAgent !== undefined) this.user_agent = data.httpUserAgent
|
||||
if (data.httpReferrer !== undefined) this.referrer = data.httpReferrer
|
||||
if (data.newStreamUrl !== undefined) this.url = data.newStreamUrl
|
||||
if (data.directives !== undefined) this.setDirectives(data.directives)
|
||||
|
||||
return this
|
||||
}
|
||||
@@ -54,24 +49,6 @@ export class Stream extends sdk.Models.Stream {
|
||||
return { title, label, quality }
|
||||
}
|
||||
|
||||
function parseDirectives(string: string): Collection<string> {
|
||||
const directives = new Collection<string>()
|
||||
|
||||
if (!string) return directives
|
||||
|
||||
const supportedDirectives = ['#EXTVLCOPT', '#KODIPROP']
|
||||
const lines = string.split('\r\n')
|
||||
const regex = new RegExp(`^${supportedDirectives.join('|')}`, 'i')
|
||||
|
||||
lines.forEach((line: string) => {
|
||||
if (regex.test(line)) {
|
||||
directives.add(line.trim())
|
||||
}
|
||||
})
|
||||
|
||||
return directives
|
||||
}
|
||||
|
||||
if (!data.name) throw new Error('"name" property is required')
|
||||
if (!data.url) throw new Error('"url" property is required')
|
||||
|
||||
@@ -91,7 +68,6 @@ export class Stream extends sdk.Models.Stream {
|
||||
stream.tvgId = data.tvg.id
|
||||
stream.line = data.line
|
||||
stream.label = label || null
|
||||
stream.directives = parseDirectives(data.raw)
|
||||
|
||||
return stream
|
||||
}
|
||||
@@ -235,7 +211,9 @@ export class Stream extends sdk.Models.Stream {
|
||||
.intersects(new Collection<string>(region.countries))
|
||||
.isNotEmpty()
|
||||
)
|
||||
regions.concat(relatedRegions)
|
||||
relatedRegions.forEach(region => {
|
||||
regions.add(region)
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'country': {
|
||||
@@ -246,7 +224,9 @@ export class Stream extends sdk.Models.Stream {
|
||||
(code: string) => code === country.code
|
||||
)
|
||||
)
|
||||
regions.concat(countryRegions)
|
||||
countryRegions.forEach(region => {
|
||||
regions.add(region)
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'subdivision': {
|
||||
@@ -257,7 +237,9 @@ export class Stream extends sdk.Models.Stream {
|
||||
(code: string) => code === subdivision.country
|
||||
)
|
||||
)
|
||||
regions.concat(subdivisionRegions)
|
||||
subdivisionRegions.forEach(region => {
|
||||
regions.add(region)
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'city': {
|
||||
@@ -268,7 +250,9 @@ export class Stream extends sdk.Models.Stream {
|
||||
(code: string) => code === city.country
|
||||
)
|
||||
)
|
||||
regions.concat(cityRegions)
|
||||
cityRegions.forEach(region => {
|
||||
regions.add(region)
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -306,14 +290,6 @@ export class Stream extends sdk.Models.Stream {
|
||||
return !!found
|
||||
}
|
||||
|
||||
setDirectives(directives: string[]): this {
|
||||
this.directives = new Collection(directives).filter((directive: string) =>
|
||||
/^(#KODIPROP|#EXTVLCOPT)/.test(directive)
|
||||
)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
updateTvgId(): this {
|
||||
if (!this.channel) return this
|
||||
if (this.feed) {
|
||||
@@ -418,20 +394,16 @@ export class Stream extends sdk.Models.Stream {
|
||||
output += ` tvg-logo="${this.getTvgLogo()}" group-title="${this.groupTitle}"`
|
||||
}
|
||||
|
||||
output += `,${this.getFullTitle()}`
|
||||
|
||||
if (this.referrer) {
|
||||
output += ` http-referrer="${this.referrer}"`
|
||||
output += `\r\n#EXTVLCOPT:http-referrer=${this.referrer}`
|
||||
}
|
||||
|
||||
if (this.user_agent) {
|
||||
output += ` http-user-agent="${this.user_agent}"`
|
||||
output += `\r\n#EXTVLCOPT:http-user-agent=${this.user_agent}`
|
||||
}
|
||||
|
||||
output += `,${this.getFullTitle()}`
|
||||
|
||||
this.directives.forEach((prop: string) => {
|
||||
output += `\r\n${prop}`
|
||||
})
|
||||
|
||||
output += `\r\n${this.url}`
|
||||
|
||||
return output
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="" http-referrer="http://test.com" http-user-agent="Mozilla/5.0",Manorama News -2 [U3] (480p) [Geo-blocked] [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="",Manorama News -2 [U3] (480p) [Geo-blocked] [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://test.com
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0
|
||||
https://ythls.onrender.com/channel/UCP0uG-mcMImgKnJz-VjJZmQ.m3u8
|
||||
|
||||
@@ -3,13 +3,9 @@
|
||||
http://resolver.streaming.api.nos.nl/livestream?url=/live/npo/tvlive/npo1/npo1.isml/.m3u8
|
||||
#EXTINF:-1 tvg-id="NPO2.nl@SD",NPO 2 (342p)
|
||||
http://resolver.streaming.api.nos.nl/livestream?url=/live/npo/tvlive/npo2/npo2.isml/.m3u8
|
||||
#EXTINF:-1 tvg-id="NPO2.nl@SD" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",NPO 2 (302p) [Geo-blocked]
|
||||
#EXTINF:-1 tvg-id="NPO2.nl@SD",NPO 2 (302p) [Geo-blocked]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://stream.tvtap.net:8081/live/nl-npo2.stream/playlist.m3u8?|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0+(iPhone;+CPU+iPhone+OS+17_7+like+Mac+OS+X)+AppleWebKit/605.1.15+(KHTML,+like+Gecko)+Version/18.0+Mobile/15E148+Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="NPO2.nl@SD",NPO 2 [Geo-blocked]
|
||||
http://resolver.streaming.api.nos.nl/livestream?url=/live/npo/tvlive/npo2/npo22.isml/.m3u8
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
|
||||
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Undefined",ATV
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@HD" tvg-logo="https://i.imgur.com/CnhTn8i.png" group-title="Undefined",ATV HD
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv_hd
|
||||
|
||||
@@ -11,13 +11,9 @@ http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
|
||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
|
||||
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Undefined",ATV
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
|
||||
|
||||
@@ -15,13 +15,9 @@ http://146.59.85.40:89/dunaworld/index.m3u8
|
||||
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
|
||||
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="International",ЭлТР (480p) [Not 24/7]
|
||||
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@HD" tvg-logo="https://i.imgur.com/CnhTn8i.png" group-title="Undefined",ATV HD
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv_hd
|
||||
|
||||
@@ -7,13 +7,9 @@ http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
|
||||
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
|
||||
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
|
||||
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@HD" tvg-logo="https://i.imgur.com/CnhTn8i.png" group-title="Undefined",ATV HD
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv_hd
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
|
||||
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Undefined",ATV
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
|
||||
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="AndorraTV.ad@HD" tvg-logo="https://i.imgur.com/CnhTn8i.png" group-title="Undefined",ATV HD
|
||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv_hd
|
||||
|
||||
@@ -3,13 +3,9 @@
|
||||
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
|
||||
#EXTINF:-1 tvg-id="VisitXTV.nl" tvg-logo="https://i.imgur.com/RJ9wbNF.jpg" group-title="XXX",Visit-X TV
|
||||
https://stream.visit-x.tv/vxtv/ngrp:live_all/30fps.m3u8
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
|
||||
http://146.59.85.40:89/dunaworld/index.m3u8
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Andorra TV (720p) [Not 24/7]
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
|
||||
http://146.59.85.40:89/dunaworld/index.m3u8
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="TFX.fr@SD" http-referrer="https://pkpakiplay.xyz/" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",TFX
|
||||
#EXTINF:-1 tvg-id="TFX.fr@SD",TFX
|
||||
#EXTVLCOPT:http-referrer=https://pkpakiplay.xyz/
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1
|
||||
https://stitcher-ipv4.pluto.tv/v1/stitch/embed/hls/channel/64c109a4798def0008a6e03e/master.m3u8?advertisingId={PSID}&appVersion=unknown&deviceDNT={TARGETOPT}&deviceId={PSID}&deviceLat=0&deviceLon=0&deviceMake=samsung&deviceModel=samsung&deviceType=samsung-tvplus&deviceVersion=unknown&embedPartner=samsung-tvplus&profileFloor=&profileLimit=&samsung_app_domain={APP_DOMAIN}&samsung_app_name={APP_NAME}&us_privacy=1YNY
|
||||
|
||||
@@ -4,10 +4,4 @@ http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
|
||||
#EXTINF:-1 tvg-id="BBCNews.uk",BBC News HD (480p) [Geo-blocked]
|
||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/playlist.m3u8
|
||||
#EXTINF:-1 tvg-id="BeanoTV.uk@SD",Beano TV
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
https://a5b4bacecd47433dad06d3189fc7422e.mediatailor.us-east-1.amazonaws.com/v1/manifest/04fd913bb278d8775298c26fdca9d9841f37601f/RakutenTV-eu_BeanoTV/b1f233d5-847c-437d-aa4f-f73e67a85323/2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
#EXTM3U
|
||||
#EXTINF:-1 tvg-id="BBCAmerica.us@East" http-user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246",BBC America East (720p)
|
||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
||||
#KODIPROP:inputstream=inputstream.adaptive
|
||||
#KODIPROP:inputstream.adaptive.manifest_type=mpd
|
||||
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
|
||||
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
|
||||
https://xui-backend.energeek.cl/live/9/playlist.m3u8?username=ZZDemoIPTVGH&password=mdo96EuqMkTR|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
|
||||
#EXTINF:-1 tvg-id="BBCAmerica.us@East",BBC America East (720p)
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246
|
||||
https://servilive.com:3126/live/tele2000live.m3u8
|
||||
#EXTINF:-1 tvg-id="FastTV.us@SD",Fast TV
|
||||
https://3fa797d5.wurl.com/manifest/f36d25e7e52f1ba8d7e56eb859c636563214f541/T05PX01vdG9yVHJlbmRGYXN0VFZfSExT/b5e5e0e2-12b3-4312-93c9-c0a7c50b41ca/4.m3u8
|
||||
|
||||
@@ -3,20 +3,20 @@ import { execSync } from 'child_process'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
const ENV_VAR =
|
||||
'cross-env DATA_DIR=tests/__data__/input/data STREAMS_DIR=tests/__data__/input/api_generate API_DIR=tests/__data__/output/.api'
|
||||
'cross-env DATA_DIR=tests/__data__/input/data STREAMS_DIR=tests/__data__/input/playlist_export API_DIR=tests/__data__/output/.api'
|
||||
|
||||
beforeEach(() => {
|
||||
fs.emptyDirSync('tests/__data__/output')
|
||||
})
|
||||
|
||||
describe('api:generate', () => {
|
||||
describe('playlist:export', () => {
|
||||
it('can create streams.json', () => {
|
||||
const cmd = `${ENV_VAR} npm run api:generate`
|
||||
const cmd = `${ENV_VAR} npm run playlist:export`
|
||||
const stdout = execSync(cmd, { encoding: 'utf8' })
|
||||
if (process.env.DEBUG === 'true') console.log(cmd, stdout)
|
||||
|
||||
expect(content('tests/__data__/output/.api/streams.json')).toMatchObject(
|
||||
content('tests/__data__/expected/api_generate/.api/streams.json')
|
||||
content('tests/__data__/expected/playlist_export/.api/streams.json')
|
||||
)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user