mirror of
https://github.com/theariatv/theariatv.github.io.git
synced 2025-09-08 00:16:12 +02:00
Compare commits
6 commits
c9bbfc145e
...
48a30a47d4
Author | SHA1 | Date | |
---|---|---|---|
|
48a30a47d4 | ||
|
3595a0f11f | ||
|
0c4d741c6d | ||
|
dfeebe56a2 | ||
|
da742bdfef | ||
|
1d2a2735bd |
3 changed files with 623 additions and 78 deletions
14
aria+.m3u
14
aria+.m3u
|
@ -199,13 +199,13 @@ http://portal5458.com:8080/live/Y18QnUSTwM/52775199980/40741.ts
|
|||
#EXTINF:-1 group-title="Canada" tvg-id="CP24.(CablePulse.24).ca" tvg-logo="https://media.starlite.best/cp24.cablepulse.24.ca.png",CP24
|
||||
http://portal5458.com:8080/live/Y18QnUSTwM/52775199980/40740.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="Crave1.-.East.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/crave-1-ca.png",Crave 1
|
||||
https://starlite.best/api/stream/smart/smart/livetv.epg/crave1.east.ca.m3u8
|
||||
http://portal5458.com:8080/live/Y18QnUSTwM/52775199980/40656.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="Crave2.-.East.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/crave-2-ca.png",Crave 2
|
||||
https://starlite.best/api/stream/smart/smart/livetv.epg/crave2.east.ca.m3u8
|
||||
http://portal5458.com:8080/live/Y18QnUSTwM/52775199980/40655.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="Crave3.-.East.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/crave-3-ca.png",Crave 3
|
||||
https://starlite.best/api/stream/smart/smart/livetv.epg/crave3.east.ca.m3u8
|
||||
https://theariatv.github.io/channeldead.mp4
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="Crave4.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/crave-4-ca.png",Crave 4
|
||||
https://starlite.best/api/stream/smart/smart/livetv.epg/crave4.east.ca.m3u8
|
||||
http://portal5458.com:8080/live/Y18QnUSTwM/52775199980/40653.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="Crime.+.Investigation.Canada.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/crime-and-investigation-ca.png",Crime + Investigation
|
||||
http://jabawalkies.club:8080/live/K1uWWBmaxJ/Xa1TFucw91/112731.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="CTV.News.Channel.ca" tvg-logo="https://media.starlite.best/ctv.news.channel.ca.png",CTV News
|
||||
|
@ -217,9 +217,9 @@ http://38.143.48.212:9981/stream/channelid/133843306?profile=pass
|
|||
#EXTINF:-1 group-title="Canada" tvg-id="CTV.Life.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/main/countries/canada/ctv-life-channel-ca.png",CTV Life
|
||||
http://jabawalkies.club:8080/live/K1uWWBmaxJ/Xa1TFucw91/5216.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="CTV.Nature.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/main/countries/canada/ctv-nature-channel-ca.png",CTV Nature
|
||||
https://starlite.best/api/stream/smart/smart/livetv.epg/discovery.science.canada.ca.m3u8
|
||||
https://theariatv.github.io/channeldead.mp4
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="CTV.Speed.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/main/countries/canada/ctv-speed-channel-ca.png",CTV Speed
|
||||
https://starlite.best/api/stream/smart/smart/livetv.epg/discovery.velocity.ca.m3u8
|
||||
https://theariatv.github.io/channeldead.mp4
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="CTV.Sci-Fi.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/main/countries/canada/ctv-sci-fi-channel-ca.png",CTV Sci Fi
|
||||
http://38.143.48.212:9981/stream/channelid/191789153?profile=pass
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="CTV.Wild.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/main/countries/canada/ctv-wild-channel-ca.png",CTV Wild
|
||||
|
@ -331,7 +331,7 @@ http://portal5458.com:8080/live/Y18QnUSTwM/52775199980/40640.ts
|
|||
#EXTINF:-1 group-title="Canada" tvg-id="One.Soccer.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/one-soccer-ca.png",One Soccer
|
||||
http://jabawalkies.club:8080/live/K1uWWBmaxJ/Xa1TFucw91/123909.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="ONE.TV.ca" tvg-logo="https://cdn.tvpassport.com/image/station/240x135/v2/s26777_h15_ac.png",One TV
|
||||
https://theariatv.github.io/aria.mp4
|
||||
https://theariatv.github.io/channeldead.mp4
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="outtv.ca" tvg-logo="https://play-lh.googleusercontent.com/jsVXFQfgTUMbNvWmk3Ccy4eVFSysQMI0vTEiTzgbLddzIGnPfsFLJ6OK29BRwGYhaPw",OUTtv
|
||||
http://jabawalkies.club:8080/live/K1uWWBmaxJ/Xa1TFucw91/112813.ts
|
||||
#EXTINF:-1 group-title="Canada" tvg-id="Oxygen.True.Crime.ca" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/canada/oxygen-ca.png",Oxygen True Crimes
|
||||
|
|
76
aria.m3u
76
aria.m3u
|
@ -1115,40 +1115,72 @@ https://a1xs.vip/700034
|
|||
https://a1xs.vip/700035
|
||||
#EXTINF:-1 group-title="New Zealand",Sky Sport 6
|
||||
https://a1xs.vip/700036
|
||||
#EXTINF:-1 group-title="Philippines" tvg-logo="https://upload.wikimedia.org/wikipedia/en/thumb/c/c0/GMA_Network_Logo_Vector.svg/1200px-GMA_Network_Logo_Vector.svg.png",GMA
|
||||
https://ott.m3u8.nathcreqtives.com/gma/manifest.m3u8
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Telewizja_Polska_-_TVP1_logo_2003.svg/1200px-Telewizja_Polska_-_TVP1_logo_2003.svg.png",TVP 1
|
||||
http://46.171.186.177:9981/stream/channelid/738470772?ticket=E0083AC1C68CF88F3281425748E50C074C5C4AC2&profile=pass
|
||||
https://tvh.cyn.cz/stream/channelid/1133911016?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8c/Telewizja_Polska_-_TVP2_logo_2003.svg/1200px-Telewizja_Polska_-_TVP2_logo_2003.svg.png",TVP 2
|
||||
http://46.171.186.177:9981/stream/channelid/304081769?ticket=3D4B83075993874103DBE6A91186CD031CD81511&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Telewizja_Polska_-_TVP3_logo_2016.svg/1200px-Telewizja_Polska_-_TVP3_logo_2016.svg.png",TVP 3
|
||||
http://46.171.186.177:9981/stream/channelid/577335142?ticket=9AF35D8F0006BC6A4F4908CD494333E261CA623A&profile=pass
|
||||
https://tvh.cyn.cz/stream/channelid/691987635?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-hd-pl.png",TVP HD
|
||||
https://tvh.cyn.cz/stream/channelid/21392183?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-info-pl.png",TVP Info
|
||||
https://tvh.cyn.cz/stream/channelid/1182692606?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-rozrywka-pl.png",TVP Rozrywka
|
||||
https://tvh.cyn.cz/stream/channelid/1626775820?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/d/d7/Logo_TVP_Sport.jpg",TVP Sport
|
||||
http://46.171.186.177:9981/stream/channelid/388291292?ticket=86CCDE044FD64D97D2331808EB4A0E8ADF3D3A8C&profile=pass
|
||||
https://tvh.cyn.cz/stream/channelid/682431392?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://static.wikia.nocookie.net/logopedia/images/e/e9/TVP_Seriale_2010.svg/revision/latest/scale-to-width-down/300?cb=20250205155101",TVP Seriale
|
||||
http://46.171.186.177:9981/stream/channelid/77275677?ticket=CB174F8D04542D654601B3AC1A1A4F04DF7DA618&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-historia-pl.png",TVP Historia
|
||||
https://tvh.cyn.cz/stream/channelid/636863764?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-kultura-pl.png",TVP Kultura
|
||||
https://tvh.cyn.cz/stream/channelid/1849809109?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-dokument-pl.png",TVP Dokument
|
||||
https://tvh.cyn.cz/stream/channelid/1984451512?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/2/26/TVN_logo_2024.svg.png",TVN
|
||||
http://46.171.186.177:9981/stream/channelid/354745704?ticket=040322A1E54CB7BBF80119A49E87FC6901F51733&profile=pass
|
||||
https://tvh.cyn.cz/stream/channelid/1616667038?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/2/23/TVN7_logo_2021.svg/250px-TVN7_logo_2021.svg.png",TVN 7
|
||||
http://46.171.186.177:9981/stream/channelid/15969849?ticket=C1900A4DCB289C29D41BD7C627F657E634283B67&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/TVN_Fabu%C5%82a.svg/1200px-TVN_Fabu%C5%82a.svg.png",TVN Fabuła
|
||||
http://46.171.186.177:9981/stream/channelid/554085826?ticket=3456AA46EB192A0232597E50EB913B5801D0D03A&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvn-turbo-pl.png",TVN Turbo
|
||||
https://tvh.cyn.cz/stream/channelid/683341512?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/polsat-pl.png",Polsat
|
||||
https://tvh.cyn.cz/stream/channelid/75536366?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/polsat-2-pl.png",Polsat 2
|
||||
https://tvh.cyn.cz/stream/channelid/1337325095?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/polsat-cafe-pl.png",Polsat Café
|
||||
https://tvh.cyn.cz/stream/channelid/2115654101?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/polsat-news-pl.png",Polsat News
|
||||
https://tvh.cyn.cz/stream/channelid/867587422?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/polsat-games-pl.png",Polsat Games
|
||||
https://tvh.cyn.cz/stream/channelid/525809616?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/FX_Logo_2023.svg/1200px-FX_Logo_2023.svg.png",FX
|
||||
http://46.171.186.177:9981/stream/channelid/1034428301?ticket=A93CA4F1692ECD149E0818680C207F14E26F5228&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/FX_Comedy_Logo_2023.svg/250px-FX_Comedy_Logo_2023.svg.png",FX Comedy
|
||||
http://46.171.186.177:9981/stream/channelid/1974576155?ticket=12AD2CAD84315860624033BE30548C0113D3528C&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/MTV_2021_%28brand_version%29.svg/1200px-MTV_2021_%28brand_version%29.svg.png",MTV
|
||||
http://46.171.186.177:9981/stream/channelid/674259884?ticket=87774F71F795C04BADA67945EFC2DADA56AD8C6D&profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/tvp-abc-pl.png",TVP ABC
|
||||
https://tvh.cyn.cz/stream/channelid/1516372603?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/poland/polsat-jimjam-pl.png",Polsat JimJam
|
||||
https://tvh.cyn.cz/stream/channelid/1590799748?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/united-states/nickelodeon-us.png",Nickelodeon
|
||||
https://d17lsiabqrlwa2.cloudfront.net/pl_138/207480-6545130-1/playlist.m3u8
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/united-states/nick-jr-us.png",Nick Jr.
|
||||
https://pltv.uzis-room.ch/play/213
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/united-states/nick-toons-us.png",Nicktoons
|
||||
https://pltv.uzis-room.ch/play/214
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/united-states/teen-nick-us.png",TeenNick
|
||||
https://tvh.cyn.cz/stream/channelid/349164676?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/poland/disney-channel-pl.png",Disney Channel
|
||||
https://pltv.uzis-room.ch/play/208
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/united-states/disney-jr-us.png",Disney Jr.
|
||||
https://pltv.uzis-room.ch/play/209
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/united-states/disney-xd-us.png",Disney XD
|
||||
https://pltv.uzis-room.ch/play/210
|
||||
https://tvh.cyn.cz/stream/channelid/366863693?profile=pass
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/united-kingdom/cartoonito-uk.png",Cartoonito
|
||||
https://pltv.uzis-room.ch/play/207
|
||||
#EXTINF:-1 group-title="Poland" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/heads/main/countries/poland/minimini-plus-pl.png",Minimini+
|
||||
|
@ -1243,28 +1275,42 @@ http://210.126.10.17:5004/auto/v5027
|
|||
http://210.126.10.17:5004/auto/v5045
|
||||
#EXTINF:-1 group-title="South Korea" tvg-logo="https://upload.wikimedia.org/wikipedia/commons/9/95/Mnet.png",Mnet
|
||||
http://210.126.10.17:5004/auto/v5042
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/tve-1-es.png" group-title="Spain",La 1 HD
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/tve-1-es.png" group-title="Spain",La 1
|
||||
http://83.63.50.226:9981/stream/channelid/1467144271?ticket=6FB05E46F799FD4EE5AB0C60B783879682C69252&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/tve-2-es.png" group-title="Spain",La 2 HD
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/tve-2-es.png" group-title="Spain",La 2
|
||||
http://83.63.50.226:9981/stream/channelid/1429257344?ticket=10D846B10884BD4009FFB8E353E0B9CDC1C57B6B&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/antena-3-es.png" group-title="Spain",Antena 3 HD
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/antena-3-es.png" group-title="Spain",Antena 3
|
||||
http://185.189.225.150:85/Antena3HD/index.m3u8
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/cuatro-es.png" group-title="Spain",Cuatro HD
|
||||
http://185.189.225.150:85/CuatroHD/index.m3u8
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/telecinco-es.png" group-title="Spain",TeleCinco HD
|
||||
http://185.189.225.150:85/TeleCincoHD/index.m3u8
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/la-sexta-es.png" group-title="Spain",La Sexta SD
|
||||
http://185.189.225.150:85/LaSexta/index.m3u8
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/moviestar-plus-es.png" group-title="Spain",Movistar Plus SD
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/cuatro-es.png" group-title="Spain",Cuatro
|
||||
http://213.97.163.175:4022/udp/239.10.20.20:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/telecinco-es.png" group-title="Spain",TeleCinco
|
||||
http://213.97.163.175:4022/udp/239.10.20.19:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/la-sexta-es.png" group-title="Spain",La Sexta
|
||||
http://185.189.225.150:85/LaSexta/index.m3u8
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/veo7-es.png" group-title="Spain",Veo7
|
||||
http://213.97.163.175:4022/udp/239.10.20.54:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/ten-es.png" group-title="Spain",TEN
|
||||
http://83.63.50.226:9981/stream/channelid/132024166?ticket=9B96EC565FFBB929E7493D847E5EDB5FBFD403BA&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/mega-es.png" group-title="Spain",MEGA
|
||||
http://83.63.50.226:9981/stream/channelid/2046120540?ticket=7F9FA9B92C26D493DC9511BDA0794FC329E84A4C&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/dmax-es.png" group-title="Spain",DMAX
|
||||
http://213.97.163.175:4022/udp/239.10.20.53:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/tv3-es.png" group-title="Spain",TV3
|
||||
http://213.97.163.175:4022/udp/239.10.20.100:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/3-24-es.png" group-title="Spain",3/24
|
||||
http://213.97.163.175:4022/udp/239.10.20.101:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/esport3-es.png" group-title="Spain",Esport3
|
||||
http://213.97.163.175:4022/udp/239.10.20.103:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/paramount-network-es.png" group-title="Spain",Paramount Network
|
||||
http://213.97.163.175:4022/udp/239.10.20.52:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/squirrel-es.png" group-title="Spain",Squirrel
|
||||
http://83.63.50.226:9981/stream/channelid/173171682?ticket=AF1192F50CFAF1F33D7538C82570559AEDD71D75&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/clan-es.png" group-title="Spain",Clan
|
||||
http://83.63.50.226:9981/stream/channelid/1627097868?ticket=BB72E0652E81C33B7D75D8E5321E04B19AF7163E&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/boing-es.png" group-title="Spain",Boing
|
||||
http://213.97.163.175:4022/udp/239.10.20.50:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/sx3-es.png" group-title="Spain",SX3
|
||||
http://213.97.163.175:4022/udp/239.10.20.102:1234
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/24h-es.png" group-title="Spain",24h
|
||||
http://83.63.50.226:9981/stream/channelid/1006422367?ticket=F6D4FDAB47AE62921087BEE75F3946CD30DE553F&profile=pass
|
||||
#EXTINF:-1 tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/refs/heads/main/countries/spain/tdp-es.png" group-title="Spain",Teledeporte (TDP)
|
||||
|
|
611
index.html
611
index.html
|
@ -14,6 +14,9 @@
|
|||
--accent-color: #0d6efd;
|
||||
--header-bg: #ffffff;
|
||||
--danger-color: #dc3545;
|
||||
--success-color: #198754;
|
||||
--warning-color: #ffc107;
|
||||
--secondary-bg: #f1f3f4;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
@ -25,21 +28,35 @@
|
|||
--accent-color: #4dabf7;
|
||||
--header-bg: #1e1e1e;
|
||||
--danger-color: #f06571;
|
||||
--success-color: #51cf66;
|
||||
--warning-color: #ffd43b;
|
||||
--secondary-bg: #2d2d2d;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
|
@ -47,19 +64,49 @@
|
|||
margin-bottom: 3rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 1.5rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 3rem;
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
margin: 0;
|
||||
background: linear-gradient(45deg, var(--accent-color), #6f42c1);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.stats-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
margin-top: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted-text-color);
|
||||
}
|
||||
|
||||
.project-info {
|
||||
background-color: var(--header-bg);
|
||||
background: linear-gradient(135deg, var(--header-bg) 0%, var(--secondary-bg) 100%);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.project-info h2, .project-info h3 {
|
||||
|
@ -70,36 +117,130 @@
|
|||
color: var(--accent-color);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.project-info a:hover {
|
||||
text-decoration: underline;
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.playlist-links p {
|
||||
margin: 0.5rem 0;
|
||||
.playlist-links {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.playlist-link {
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
background-color: var(--secondary-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.playlist-link:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
.controls-bar {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
flex: 1;
|
||||
min-width: 250px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
padding: 0.75rem 1rem 0.75rem 2.5rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 25px;
|
||||
border: 2px solid var(--border-color);
|
||||
background-color: var(--header-bg);
|
||||
color: var(--text-color);
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
#search-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-color);
|
||||
box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 0.75rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--muted-text-color);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.view-toggle {
|
||||
display: flex;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.view-button {
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--header-bg);
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.view-button.active {
|
||||
background: var(--accent-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.expand-collapse-buttons {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
background: var(--header-bg);
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.action-button:hover {
|
||||
background: var(--accent-color);
|
||||
color: white;
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.category-folder {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 1rem;
|
||||
background-color: var(--header-bg);
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.category-folder:hover {
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.category-header {
|
||||
|
@ -109,9 +250,39 @@
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
background: linear-gradient(90deg, var(--header-bg) 0%, var(--secondary-bg) 100%);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.category-header:hover {
|
||||
background: var(--secondary-bg);
|
||||
}
|
||||
|
||||
.category-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.channel-count {
|
||||
background: var(--accent-color);
|
||||
color: white;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 12px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.expand-icon {
|
||||
transition: transform 0.3s ease;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.expand-icon.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.channel-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
@ -128,37 +299,199 @@
|
|||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted-text-color);
|
||||
background-color: var(--secondary-bg);
|
||||
}
|
||||
|
||||
.channel-table tr:hover {
|
||||
background-color: var(--secondary-bg);
|
||||
}
|
||||
|
||||
.channel-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.channel-logo {
|
||||
width: 32px;
|
||||
height: 24px;
|
||||
object-fit: contain;
|
||||
border-radius: 4px;
|
||||
background-color: var(--secondary-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.logo-fallback {
|
||||
width: 32px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(45deg, var(--accent-color), #6f42c1);
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.channel-table a {
|
||||
color: var(--accent-color);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.channel-table a:hover {
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.status-stable {
|
||||
background-color: var(--success-color);
|
||||
}
|
||||
|
||||
.status-unstable {
|
||||
background-color: var(--warning-color);
|
||||
}
|
||||
|
||||
.unstable-icon {
|
||||
color: #ffc107;
|
||||
color: var(--warning-color);
|
||||
font-weight: bold;
|
||||
margin-left: 8px;
|
||||
cursor: help;
|
||||
font-size: 1.2rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.report-button {
|
||||
font-size: 0.8rem;
|
||||
padding: 4px 8px;
|
||||
border-radius: 5px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--danger-color);
|
||||
background: transparent;
|
||||
color: var(--danger-color);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.report-button:hover {
|
||||
background: var(--danger-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 3rem;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid var(--border-color);
|
||||
border-top: 4px solid var(--accent-color);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.no-results {
|
||||
text-align: center;
|
||||
padding: 3rem;
|
||||
color: var(--muted-text-color);
|
||||
}
|
||||
|
||||
.grid-view {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.grid-category {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
background: var(--header-bg);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.grid-category h3 {
|
||||
margin-top: 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.grid-channels {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grid-channel {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.grid-channel-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grid-channel-logo {
|
||||
width: 20px;
|
||||
height: 15px;
|
||||
object-fit: contain;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.grid-logo-fallback {
|
||||
width: 20px;
|
||||
height: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(45deg, var(--accent-color), #6f42c1);
|
||||
border-radius: 2px;
|
||||
color: white;
|
||||
font-size: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.controls-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.channel-table th:nth-child(n+3),
|
||||
.channel-table td:nth-child(n+3) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.stats-bar {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.playlist-links {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -171,7 +504,7 @@
|
|||
<div id="root"></div>
|
||||
|
||||
<script type="text/babel">
|
||||
const { useState, useEffect } = React;
|
||||
const { useState, useEffect, useMemo } = React;
|
||||
|
||||
const parseM3U = (m3uContent, isStable) => {
|
||||
const lines = m3uContent.split('\n');
|
||||
|
@ -192,18 +525,61 @@
|
|||
const channelName = line.split(',').pop().trim();
|
||||
const streamUrl = nextLine.trim();
|
||||
|
||||
// Extract tvg-logo if present
|
||||
const logoMatch = line.match(/tvg-logo="([^"]+)"/);
|
||||
const logoUrl = logoMatch ? logoMatch[1] : null;
|
||||
|
||||
if (!channels[country]) channels[country] = {};
|
||||
|
||||
if (!channels[country][channelName]) {
|
||||
channels[country][channelName] = { name: channelName, stable: isStable, url: streamUrl };
|
||||
channels[country][channelName] = {
|
||||
name: channelName,
|
||||
stable: isStable,
|
||||
url: streamUrl,
|
||||
country: country,
|
||||
logo: logoUrl
|
||||
};
|
||||
}
|
||||
} catch (e) { console.error("Error parsing line:", line, e); }
|
||||
}
|
||||
}
|
||||
return channels;
|
||||
};
|
||||
|
||||
// Generate logo URL from channel name using multiple sources
|
||||
const generateLogoUrl = (channelName, country) => {
|
||||
// This function is no longer needed since logos come from playlists
|
||||
return null;
|
||||
};
|
||||
|
||||
const ChannelLogo = ({ channel, className = "channel-logo" }) => {
|
||||
const [logoError, setLogoError] = useState(false);
|
||||
|
||||
const handleLogoError = () => {
|
||||
setLogoError(true);
|
||||
};
|
||||
|
||||
// If no logo URL or error occurred, show fallback
|
||||
if (!channel.logo || logoError) {
|
||||
const initials = channel.name.split(' ').map(word => word[0]).join('').substring(0, 2);
|
||||
return (
|
||||
<div className={className === "channel-logo" ? "logo-fallback" : "grid-logo-fallback"}>
|
||||
{initials}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
src={channel.logo}
|
||||
alt={`${channel.name} logo`}
|
||||
className={className}
|
||||
onError={handleLogoError}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Category = ({ country, channels, forceOpen }) => {
|
||||
const Category = ({ country, channels, forceOpen, viewMode }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -224,18 +600,51 @@
|
|||
return `${repoUrl}?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`;
|
||||
};
|
||||
|
||||
if (viewMode === 'grid') {
|
||||
return (
|
||||
<div className="grid-category">
|
||||
<h3>
|
||||
<span className="category-title">
|
||||
{country}
|
||||
<span className="channel-count">{channels.length}</span>
|
||||
</span>
|
||||
</h3>
|
||||
<div className="grid-channels">
|
||||
{channels.slice(0, 5).map(channel => (
|
||||
<div key={channel.name} className="grid-channel">
|
||||
<div className="grid-channel-info">
|
||||
<ChannelLogo channel={channel} className="grid-channel-logo" />
|
||||
<span className={`status-indicator ${channel.stable ? 'status-stable' : 'status-unstable'}`}></span>
|
||||
{channel.name}
|
||||
</div>
|
||||
<a href={channel.url} target="_blank" rel="noopener noreferrer">▶</a>
|
||||
</div>
|
||||
))}
|
||||
{channels.length > 5 && (
|
||||
<div style={{textAlign: 'center', color: 'var(--muted-text-color)', fontSize: '0.9rem'}}>
|
||||
+{channels.length - 5} more channels
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="category-folder">
|
||||
<div className="category-header" onClick={() => setIsOpen(!isOpen)}>
|
||||
<span>{country}</span>
|
||||
<span>{isOpen ? '−' : '+'}</span>
|
||||
<div className="category-title">
|
||||
<span>{country}</span>
|
||||
<span className="channel-count">{channels.length}</span>
|
||||
</div>
|
||||
<span className={`expand-icon ${isOpen ? 'expanded' : ''}`}>▼</span>
|
||||
</div>
|
||||
{isOpen && (
|
||||
<table className="channel-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Channel</th>
|
||||
<th>Stream Link</th>
|
||||
<th>Stream</th>
|
||||
<th>Report</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -244,14 +653,21 @@
|
|||
<tr key={channel.name}>
|
||||
<td>
|
||||
<div className="channel-name">
|
||||
{channel.name}
|
||||
{!channel.stable &&
|
||||
<span className="unstable-icon" title="Potentially unstable stream from aria+.m3u">!</span>
|
||||
}
|
||||
<ChannelLogo channel={channel} />
|
||||
<div>
|
||||
<div style={{fontWeight: '500'}}>{channel.name}</div>
|
||||
<div style={{fontSize: '0.8rem', color: 'var(--muted-text-color)'}}>
|
||||
<span className={`status-indicator ${channel.stable ? 'status-stable' : 'status-unstable'}`}></span>
|
||||
{channel.stable ? 'Stable' : 'Unstable'}
|
||||
{!channel.stable &&
|
||||
<span className="unstable-icon" title="Potentially unstable stream from aria+.m3u"> ⚠</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href={channel.url} target="_blank" rel="noopener noreferrer">Link</a>
|
||||
<a href={channel.url} target="_blank" rel="noopener noreferrer">Play</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href={createReportURL(channel)} target="_blank" rel="noopener noreferrer" className="report-button">Report</a>
|
||||
|
@ -270,12 +686,29 @@
|
|||
const [filteredData, setFilteredData] = useState([]);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [viewMode, setViewMode] = useState('list');
|
||||
const [allExpanded, setAllExpanded] = useState(false);
|
||||
|
||||
const stats = useMemo(() => {
|
||||
const totalChannels = allChannelData.reduce((sum, cat) => sum + cat.channels.length, 0);
|
||||
const stableChannels = allChannelData.reduce((sum, cat) =>
|
||||
sum + cat.channels.filter(ch => ch.stable).length, 0);
|
||||
const countries = allChannelData.length;
|
||||
|
||||
return { totalChannels, stableChannels, countries };
|
||||
}, [allChannelData]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchAndParseData = async () => {
|
||||
try {
|
||||
const [ariaRes, ariaPlusRes] = await Promise.all([ fetch('aria.m3u'), fetch('aria+.m3u') ]);
|
||||
const [ariaText, ariaPlusText] = await Promise.all([ ariaRes.text(), ariaPlusRes.text() ]);
|
||||
const [ariaRes, ariaPlusRes] = await Promise.all([
|
||||
fetch('aria.m3u'),
|
||||
fetch('aria+.m3u')
|
||||
]);
|
||||
const [ariaText, ariaPlusText] = await Promise.all([
|
||||
ariaRes.text(),
|
||||
ariaPlusRes.text()
|
||||
]);
|
||||
|
||||
const stableChannels = parseM3U(ariaText, true);
|
||||
const unstableChannels = parseM3U(ariaPlusText, false);
|
||||
|
@ -297,8 +730,11 @@
|
|||
|
||||
setAllChannelData(formattedData);
|
||||
setFilteredData(formattedData);
|
||||
} catch (error) { console.error("Could not load channel data:", error); }
|
||||
finally { setLoading(false); }
|
||||
} catch (error) {
|
||||
console.error("Could not load channel data:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
fetchAndParseData();
|
||||
}, []);
|
||||
|
@ -312,18 +748,37 @@
|
|||
const filtered = allChannelData
|
||||
.map(category => ({
|
||||
...category,
|
||||
channels: category.channels.filter(channel => channel.name.toLowerCase().includes(lowercasedFilter))
|
||||
channels: category.channels.filter(channel =>
|
||||
channel.name.toLowerCase().includes(lowercasedFilter) ||
|
||||
channel.country.toLowerCase().includes(lowercasedFilter)
|
||||
)
|
||||
}))
|
||||
.filter(category => category.channels.length > 0);
|
||||
setFilteredData(filtered);
|
||||
}, [searchTerm, allChannelData]);
|
||||
|
||||
const expandAll = () => setAllExpanded(true);
|
||||
const collapseAll = () => setAllExpanded(false);
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<header>
|
||||
<h1>Aria</h1>
|
||||
<p>A curated collection of IPTV channels from around the world.</p>
|
||||
<div className="stats-bar">
|
||||
<div className="stat-item">
|
||||
<div className="stat-number">{stats.totalChannels}</div>
|
||||
<div className="stat-label">Total Channels</div>
|
||||
</div>
|
||||
<div className="stat-item">
|
||||
<div className="stat-number">{stats.stableChannels}</div>
|
||||
<div className="stat-label">Stable</div>
|
||||
</div>
|
||||
<div className="stat-item">
|
||||
<div className="stat-number">{stats.countries}</div>
|
||||
<div className="stat-label">Countries</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div className="project-info">
|
||||
|
@ -333,8 +788,14 @@
|
|||
</p>
|
||||
<div className="playlist-links">
|
||||
<h3>Playlist Files</h3>
|
||||
<p><a href="./aria.m3u" download>Download aria.m3u</a> (Stable Streams)</p>
|
||||
<p><a href="./aria+.m3u" download>Download aria+.m3u</a> (Potentially Unstable Streams)</p>
|
||||
<a href="./aria.m3u" download className="playlist-link">
|
||||
<strong>Download aria.m3u</strong><br />
|
||||
<small>Stable Streams</small>
|
||||
</a>
|
||||
<a href="./aria+.m3u" download className="playlist-link">
|
||||
<strong>Download aria+.m3u</strong><br />
|
||||
<small>Potentially Unstable Streams</small>
|
||||
</a>
|
||||
</div>
|
||||
<h3>Want to help us?</h3>
|
||||
<p>
|
||||
|
@ -343,26 +804,64 @@
|
|||
</div>
|
||||
|
||||
<h2>Channel List</h2>
|
||||
<div className="search-container">
|
||||
<input
|
||||
id="search-input"
|
||||
type="search"
|
||||
placeholder="Search for a channel..."
|
||||
value={searchTerm}
|
||||
onChange={e => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
{loading ? (
|
||||
<p>Loading channels...</p>
|
||||
) : (
|
||||
filteredData.map(category => (
|
||||
<Category
|
||||
key={category.country}
|
||||
country={category.country}
|
||||
channels={category.channels}
|
||||
forceOpen={searchTerm.length > 0}
|
||||
<div className="controls-bar">
|
||||
<div className="search-container">
|
||||
<span className="search-icon">🔍</span>
|
||||
<input
|
||||
id="search-input"
|
||||
type="search"
|
||||
placeholder="Search for channel or country..."
|
||||
value={searchTerm}
|
||||
onChange={e => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
))
|
||||
</div>
|
||||
<div className="view-toggle">
|
||||
<button
|
||||
className={`view-button ${viewMode === 'list' ? 'active' : ''}`}
|
||||
onClick={() => setViewMode('list')}
|
||||
>
|
||||
List
|
||||
</button>
|
||||
<button
|
||||
className={`view-button ${viewMode === 'grid' ? 'active' : ''}`}
|
||||
onClick={() => setViewMode('grid')}
|
||||
>
|
||||
Grid
|
||||
</button>
|
||||
</div>
|
||||
{viewMode === 'list' && (
|
||||
<div className="expand-collapse-buttons">
|
||||
<button className="action-button" onClick={expandAll}>
|
||||
Expand All
|
||||
</button>
|
||||
<button className="action-button" onClick={collapseAll}>
|
||||
Collapse All
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="loading-spinner">
|
||||
<div className="spinner"></div>
|
||||
</div>
|
||||
) : filteredData.length === 0 ? (
|
||||
<div className="no-results">
|
||||
<h3>No Results Found</h3>
|
||||
<p>No channels were found for your search term "{searchTerm}".</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className={viewMode === 'grid' ? 'grid-view' : ''}>
|
||||
{filteredData.map(category => (
|
||||
<Category
|
||||
key={category.country}
|
||||
country={category.country}
|
||||
channels={category.channels}
|
||||
forceOpen={searchTerm.length > 0 || allExpanded}
|
||||
viewMode={viewMode}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue