├── .github └── workflows │ └── action.yml ├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── logo.png ├── package.json └── template ├── favicon.ico ├── index.css └── index.html /.github/workflows/action.yml: -------------------------------------------------------------------------------- 1 | name: "IPTV Channels Bot" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | schedule: 8 | - cron: 00 02 * * 0 9 | 10 | jobs: 11 | feed-processor: 12 | name: IPTV Channels fetch processor 13 | runs-on: ubuntu-18.04 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v2 17 | - name: Setup Node.js 18 | uses: actions/setup-node@main 19 | with: 20 | node-version: "14" 21 | - name: Install dependencies 22 | run: npm install 23 | - name: Build JSON 24 | run: node index.js 25 | - name: Deploy to GitHub Pages 26 | uses: JamesIves/github-pages-deploy-action@3.7.1 27 | with: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | BRANCH: gh-pages # The branch the action should deploy to. 30 | FOLDER: dist # The folder the action should deploy. 31 | CLEAN: true # Automatically remove deleted files from the deploy branch 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eric Shen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

logo

2 |

:point_right: iptvlist.ml

3 |

4 | List of IPTV channels with the option to play them directly in the browser (10000+) .

5 | 6 |

7 | 8 | version 9 | license 10 | pv 11 | 12 |

13 | 14 | ## Features: 15 | 16 | - [x] Easy to search Channels by Category or Country. 17 | - [x] Easy to copy Channels' link 18 | - [x] Video player for Channels (Only for https link) 19 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fetch = require("node-fetch"); 2 | const fsPromises = require("fs").promises; 3 | 4 | async function main() { 5 | const response = await fetch("https://iptv-org.github.io/iptv/channels.json"); 6 | if (response.status < 200 || response.status >= 300) { 7 | throw new Error("wrong status code"); 8 | } 9 | const json = await response.json(); 10 | console.log(`successfully fetch iptv channels`); 11 | 12 | await fsPromises.rmdir("./dist", { recursive: true }); 13 | console.log(`successfully deleted ./dist`); 14 | 15 | await fsPromises.mkdir("./dist"); 16 | console.log(`successfully create ./dist`); 17 | 18 | await fsPromises.writeFile("./dist/channels.json", JSON.stringify(json)); 19 | console.log(`successfully write channels.json`); 20 | 21 | await fsPromises.copyFile("./template/index.html", `./dist/index.html`); 22 | await fsPromises.copyFile("./template/index.css", `./dist/index.css`); 23 | await fsPromises.copyFile("./template/favicon.ico", `./dist/favicon.ico`); 24 | console.log(`successfully copy asset files`); 25 | } 26 | 27 | main(); 28 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shen-yu/iptv-list/8d492e327cbd53f6a6bdf6087ba414703813b41a/logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iptv-list", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "node index.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Shen-Yu/iptv-list.git" 13 | }, 14 | "author": "Shen-Yu", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/Shen-Yu/iptv-list/issues" 18 | }, 19 | "homepage": "https://github.com/Shen-Yu/iptv-list#readme", 20 | "dependencies": { 21 | "node-fetch": "^2.6.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /template/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shen-yu/iptv-list/8d492e327cbd53f6a6bdf6087ba414703813b41a/template/favicon.ico -------------------------------------------------------------------------------- /template/index.css: -------------------------------------------------------------------------------- 1 | ul, 2 | li { 3 | list-style-type: none; 4 | } 5 | a { 6 | color: #00c4a7; 7 | } 8 | a:hover { 9 | color: #00d1b2; 10 | } 11 | 12 | tr td { 13 | user-select: all; 14 | } 15 | 16 | tr td img { 17 | width: 40px; 18 | height: 40px; 19 | } 20 | 21 | .title { 22 | text-align: center; 23 | margin: 40px auto !important; 24 | } 25 | .logo { 26 | width: 18%; 27 | } 28 | .is-spaced { 29 | margin-bottom: 20px; 30 | } 31 | .swal-button { 32 | background-color: #00d1b2; 33 | border: 1px solid #00d1b2; 34 | } 35 | 36 | .swal-button:not([disabled]):hover { 37 | background-color: #00c4a7; 38 | border: 1px solid #00c4a7; 39 | } 40 | 41 | .table-container { 42 | margin-top: 20px; 43 | } 44 | @media screen and (max-width: 768px) { 45 | * { 46 | font-size: 98%; 47 | } 48 | th.cate, 49 | td.cate { 50 | display: none; 51 | } 52 | th.url, 53 | td.url { 54 | max-width: 100px; 55 | } 56 | .btns button { 57 | transform: scale(0.8); 58 | } 59 | .logo { 60 | width: 60%; 61 | } 62 | } 63 | @media screen and (min-width: 768px) { 64 | td.cate { 65 | max-width: 125px; 66 | } 67 | th.url, 68 | td.url { 69 | max-width: 480px; 70 | } 71 | th.btns, 72 | td.btns { 73 | min-width: 180px; 74 | } 75 | .search-bar { 76 | margin-left: 10%; 77 | } 78 | .table-container { 79 | max-width: 80%; 80 | margin-left: 10%; 81 | } 82 | } 83 | td.url { 84 | overflow: hidden; 85 | text-overflow: ellipsis; 86 | white-space: nowrap; 87 | } 88 | 89 | .spinner { 90 | margin: 100px auto; 91 | width: 50px; 92 | height: 60px; 93 | text-align: center; 94 | font-size: 10px; 95 | } 96 | 97 | .spinner > div { 98 | background-color: #00d1b2; 99 | height: 100%; 100 | width: 6px; 101 | display: inline-block; 102 | -webkit-animation: stretchDelay 1.2s infinite ease-in-out; 103 | animation: stretchDelay 1.2s infinite ease-in-out; 104 | } 105 | 106 | .spinner .rect2 { 107 | -webkit-animation-delay: -1.1s; 108 | animation-delay: -1.1s; 109 | } 110 | 111 | .spinner .rect3 { 112 | -webkit-animation-delay: -1s; 113 | animation-delay: -1s; 114 | } 115 | 116 | .spinner .rect4 { 117 | -webkit-animation-delay: -0.9s; 118 | animation-delay: -0.9s; 119 | } 120 | 121 | .spinner .rect5 { 122 | -webkit-animation-delay: -0.8s; 123 | animation-delay: -0.8s; 124 | } 125 | 126 | @-webkit-keyframes stretchDelay { 127 | 0%, 128 | 40%, 129 | 100% { 130 | -webkit-transform: scaleY(0.4); 131 | } 132 | 20% { 133 | -webkit-transform: scaleY(1); 134 | } 135 | } 136 | 137 | @keyframes stretchDelay { 138 | 0%, 139 | 40%, 140 | 100% { 141 | transform: scaleY(0.4); 142 | -webkit-transform: scaleY(0.4); 143 | } 144 | 20% { 145 | transform: scaleY(1); 146 | -webkit-transform: scaleY(1); 147 | } 148 | } 149 | 150 | .github-fork-ribbon.right-top:before { 151 | background-color: #f80; 152 | } 153 | -------------------------------------------------------------------------------- /template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | Free IPTV Playlist 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 30 | 31 | 33 | 34 | 38 | 47 | 48 | 49 | 50 | Fork me on GitHub 58 |
59 |

60 | 61 |

62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | 97 |
98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 116 | 117 | 130 | 131 | 132 |
ChannelCategoryUrlAction
{{i.name}} 109 | {{item.name}} 115 | {{i.url}} 118 | 126 | 129 |
133 |
134 |
135 |
136 | 147 |
148 | 149 | 160 | 165 |
166 |
167 | 169 | 175 | 178 | 179 | 287 | --------------------------------------------------------------------------------