Compare commits

..

3 commits

Author SHA1 Message Date
VlastikYoutubeKo
78d5df5962
Update index.html 2025-08-15 12:29:18 +02:00
VlastikYoutubeKo
2623494ccd
Update aria.m3u 2025-08-15 12:28:07 +02:00
VlastikYoutubeKo
5f941659d2
Create index.html
Added a website that "should" work
2025-08-15 12:25:30 +02:00
2 changed files with 313 additions and 2 deletions

View file

@ -317,7 +317,7 @@ http://90.178.86.156:9981/stream/channelid/748255433?ticket=216B5B41838A2332296F
http://90.178.86.156:9981/stream/channelid/1183792288?ticket=6CE25AF67B8D74983939FCF3B123AD08A5B0BAE8&profile=pass http://90.178.86.156:9981/stream/channelid/1183792288?ticket=6CE25AF67B8D74983939FCF3B123AD08A5B0BAE8&profile=pass
#EXTINF:-1 group-title="Czechia" tvg-id="Óčko.STAR.cz",OCKO STAR #EXTINF:-1 group-title="Czechia" tvg-id="Óčko.STAR.cz",OCKO STAR
http://90.178.86.156:9981/stream/channelid/1340646702?ticket=6A7ED7E2087641A202EA744A9DE44B07A2EE2FAC&profile=pass http://90.178.86.156:9981/stream/channelid/1340646702?ticket=6A7ED7E2087641A202EA744A9DE44B07A2EE2FAC&profile=pass
#EXTINF:-1 group-title="Czechia" tvg-id="CNN.Prima.News.cz"CNN Prima News #EXTINF:-1 group-title="Czechia" tvg-id="CNN.Prima.News.cz",CNN Prima News
http://90.178.86.156:9981/stream/channelid/1443888704?ticket=B2AC43F9C197099EE2A723A8B5D26A8402094755&profile=pass http://90.178.86.156:9981/stream/channelid/1443888704?ticket=B2AC43F9C197099EE2A723A8B5D26A8402094755&profile=pass
#EXTINF:-1 group-title="Czechia" tvg-id="TV.Barrandov.cz",TV Barrandov #EXTINF:-1 group-title="Czechia" tvg-id="TV.Barrandov.cz",TV Barrandov
http://90.178.86.156:9981/stream/channelid/1149773228?ticket=56A407B3D9D49568B131C27B70C4B903FD070FE5&profile=pass http://90.178.86.156:9981/stream/channelid/1149773228?ticket=56A407B3D9D49568B131C27B70C4B903FD070FE5&profile=pass
@ -331,7 +331,7 @@ http://tvh.cyn.cz/stream/channelid/1693764695?profile=pass
http://185.236.230.212:9981/play/a0bb http://185.236.230.212:9981/play/a0bb
#EXTINF:-1 group-title="Czechia" tvg-id="Auto.Motor.Sport.cz",AUTOMOTORSPORT HD #EXTINF:-1 group-title="Czechia" tvg-id="Auto.Motor.Sport.cz",AUTOMOTORSPORT HD
https://webstream.odjezdy.online/EU/AMSTV/video.m3u8 https://webstream.odjezdy.online/EU/AMSTV/video.m3u8
#EXTINF:-1 group-title="Czechia"CANAL+ ACTION HD #EXTINF:-1 group-title="Czechia",CANAL+ ACTION HD
http://185.236.230.212:9981/play/a0bw http://185.236.230.212:9981/play/a0bw
#EXTINF:-1 group-title="Czechia",CANAL+ SPORT #EXTINF:-1 group-title="Czechia",CANAL+ SPORT
http://185.236.230.212:9981/play/a0bu http://185.236.230.212:9981/play/a0bu

311
index.html Normal file
View file

@ -0,0 +1,311 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aria | Curated IPTV Channels</title>
<style>
:root {
--bg-color: #f8f9fa;
--text-color: #212529;
--muted-text-color: #6c757d;
--border-color: #dee2e6;
--accent-color: #0d6efd;
--header-bg: #ffffff;
}
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #121212;
--text-color: #e9ecef;
--muted-text-color: #adb5bd;
--border-color: #343a40;
--accent-color: #4dabf7;
--header-bg: #1e1e1e;
}
}
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;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 2rem;
}
header {
text-align: center;
margin-bottom: 3rem;
border-bottom: 1px solid var(--border-color);
padding-bottom: 1.5rem;
}
header h1 {
font-size: 3rem;
margin: 0;
}
.project-info {
background-color: var(--header-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 2rem;
}
.project-info h2, .project-info h3 {
margin-top: 0;
}
.project-info a {
color: var(--accent-color);
text-decoration: none;
font-weight: 500;
}
.project-info a:hover {
text-decoration: underline;
}
.playlist-links p {
margin: 0.5rem 0;
}
.category-folder {
border: 1px solid var(--border-color);
border-radius: 8px;
margin-bottom: 1rem;
background-color: var(--header-bg);
}
.category-header {
padding: 1rem 1.5rem;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.2rem;
font-weight: 500;
}
.channel-table {
width: 100%;
border-collapse: collapse;
}
.channel-table th, .channel-table td {
padding: 0.75rem 1.5rem;
border-top: 1px solid var(--border-color);
text-align: left;
}
.channel-table th {
font-weight: 600;
font-size: 0.9rem;
color: var(--muted-text-color);
}
.channel-name {
display: flex;
align-items: center;
}
.channel-table a {
color: var(--accent-color);
text-decoration: none;
font-weight: 500;
}
.unstable-icon {
color: #ffc107;
font-weight: bold;
margin-left: 8px;
cursor: help;
font-size: 1.2rem;
}
</style>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const { useState, useEffect } = React;
// --- Funkce pro parsování .m3u souborů ---
const parseM3U = (m3uContent, isStable) => {
const lines = m3uContent.split('\n');
const channels = {};
const regex = /group-title="([^"]+)"/;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.startsWith('#EXTINF:-1')) {
try {
const nextLine = lines[i + 1];
if (!nextLine || nextLine.startsWith('#')) continue;
const countryMatch = line.match(regex);
if (!countryMatch) continue;
const country = countryMatch[1].trim();
const channelName = line.split(',').pop().trim();
const streamUrl = nextLine.trim();
if (!channels[country]) {
channels[country] = {};
}
if (!channels[country][channelName]) {
channels[country][channelName] = { name: channelName, stable: isStable, url: streamUrl };
}
} catch (e) {
console.error("Chyba při parsování řádku:", line, e);
}
}
}
return channels;
};
// --- Komponenty ---
const Category = ({ country, channels }) => {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="category-folder">
<div className="category-header" onClick={() => setIsOpen(!isOpen)}>
<span>{country}</span>
<span>{isOpen ? '' : '+'}</span>
</div>
{isOpen && (
<table className="channel-table">
<thead>
<tr>
<th>Channel</th>
<th>Stream Link</th>
</tr>
</thead>
<tbody>
{channels.map(channel => (
<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>
}
</div>
</td>
<td>
<a href={channel.url} target="_blank" rel="noopener noreferrer">Link</a>
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
);
};
const App = () => {
const [channelData, setChannelData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchAndParseData = async () => {
try {
const [ariaRes, ariaPlusRes] = await Promise.all([
fetch('aria.m3u'),
fetch('aria+.m3u')
]);
const ariaText = await ariaRes.text();
const ariaPlusText = await ariaPlusRes.text();
const stableChannels = parseM3U(ariaText, true);
const unstableChannels = parseM3U(ariaPlusText, false);
const allChannels = { ...stableChannels };
for (const country in unstableChannels) {
if (!allChannels[country]) allChannels[country] = {};
for (const channelName in unstableChannels[country]) {
if (!allChannels[country][channelName]) {
allChannels[country][channelName] = unstableChannels[country][channelName];
}
}
}
const formattedData = Object.keys(allChannels).sort().map(country => ({
country,
channels: Object.values(allChannels[country]).sort((a, b) => a.name.localeCompare(b.name))
}));
setChannelData(formattedData);
} catch (error) {
console.error("Nepodařilo se načíst data kanálů:", error);
} finally {
setLoading(false);
}
};
fetchAndParseData();
}, []);
return (
<div className="container">
<header>
<h1>Aria</h1>
<p>A curated collection of IPTV channels from around the world.</p>
</header>
<main>
<div className="project-info">
<h2>About Aria</h2>
<p>
Aria provides a curated collection of IPTV channels from around the world. The channels are organized by their countries. Unlike our predecessor Mystique, this git is only using official streams, tvheadends, astra control panel among others.
</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>
</div>
<h3>Want to help us?</h3>
<p>
You can go to the <a href="https://github.com/theariatv/theariatv.github.io/issues" target="_blank" rel="noopener noreferrer">Issues tab</a> on GitHub to request a channel-specific action.
</p>
</div>
<h2>Channel List</h2>
{loading ? (
<p>Loading channels...</p>
) : (
channelData.map(category => (
<Category
key={category.country}
country={category.country}
channels={category.channels}
/>
))
)}
</main>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
</script>
</body>
</html>