348
Subscribers
-124 hours
-47 days
+630 days
Data loading in progress...
Similar Channels
No data
Any problems? Please refresh the page or contact our support manager.
Tags Cloud
Incoming and Outgoing Mentions
---
---
---
---
---
---
Attracting Subscribers
May '26
May '26
+11
in 0 channels
April '26
+23
in 0 channels
Get PRO
March '26
+21
in 0 channels
Get PRO
February '26
+17
in 0 channels
Get PRO
January '26
+29
in 0 channels
Get PRO
December '25
+23
in 0 channels
Get PRO
November '25
+6
in 0 channels
Get PRO
October '25
+8
in 0 channels
Get PRO
September '25
+1
in 0 channels
Get PRO
August '25
+18
in 0 channels
Get PRO
July '25
+50
in 0 channels
Get PRO
June '25
+300
in 0 channels
| Date | Subscriber Growth | Mentions | Channels | |
| 19 May | 0 | |||
| 18 May | 0 | |||
| 17 May | 0 | |||
| 16 May | 0 | |||
| 15 May | 0 | |||
| 14 May | 0 | |||
| 13 May | 0 | |||
| 12 May | 0 | |||
| 11 May | 0 | |||
| 10 May | +2 | |||
| 09 May | 0 | |||
| 08 May | 0 | |||
| 07 May | +1 | |||
| 06 May | 0 | |||
| 05 May | +1 | |||
| 04 May | 0 | |||
| 03 May | +3 | |||
| 02 May | +4 | |||
| 01 May | 0 |
Channel Posts
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 37mustafa783
🔐 Şifre: 92musyafabey2
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 16.08.2026 17:22
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=37mustafa783&password=92musyafabey2&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 382500
🔐 Şifre: 38250000
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 04.09.2026 20:49
🔗 Bağlantı: 0 / 2
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=382500&password=38250000&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 4mcy9FJKnH
🔐 Şifre: qARTVvMSrf
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 10.06.2026 12:02
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=4mcy9FJKnH&password=qARTVvMSrf&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 4W3dCNBZnV
🔐 Şifre: y6bfxPU5jy
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 18.07.2026 14:41
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=4W3dCNBZnV&password=y6bfxPU5jy&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 4rQTFAzYBz
🔐 Şifre: Fc9EeMgPv8
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 29.04.2027 21:19
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=4rQTFAzYBz&password=Fc9EeMgPv8&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
| 2 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 024yunus
🔐 Şifre: hande2424
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 26.04.2028 17:08
🔗 Bağlantı: 1 / 2
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=024yunus&password=hande2424&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 052ismetates1907
🔐 Şifre: 1907ismet052
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 24.04.2027 18:15
🔗 Bağlantı: 0 / 2
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=052ismetates1907&password=1907ismet052&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 05536409272
🔐 Şifre: QazWsx3428
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 24.05.2026 16:45
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=05536409272&password=QazWsx3428&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 055samet88
🔐 Şifre: 1903samet88
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 08.07.2026 19:48
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=055samet88&password=1903samet88&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 06an6420
🔐 Şifre: 2404-1705
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 25.04.2027 12:15
🔗 Bağlantı: 1 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=06an6420&password=2404-1705&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 07012025komsu
🔐 Şifre: pAdTCsXJcJ
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 06.01.2027 16:58
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=07012025komsu&password=pAdTCsXJcJ&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 13344
🔐 Şifre: 13344
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 12.11.2026 14:34
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=13344&password=13344&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 16veysel837
🔐 Şifre: 937dagin3626
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 04.07.2026 17:43
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=16veysel837&password=937dagin3626&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 1903omeryusuf55
🔐 Şifre: 55omeryusuf1903
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 19.02.2027 15:35
🔗 Bağlantı: 0 / 2
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=1903omeryusuf55&password=55omeryusuf1903&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 1905birol034
🔐 Şifre: 02052022arnavut
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 30.06.2026 00:00
🔗 Bağlantı: 0 / 2
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=1905birol034&password=02052022arnavut&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 2307tembd123
🔐 Şifre: JDsaQTrhHL
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 25.07.2026 15:27
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=2307tembd123&password=JDsaQTrhHL&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
👤 Kullanıcı / MAC: 2qQRFPLfd8
🔐 Şifre: RWJKywTAgY
👨💼 Oluşturan: DeaTHLesS
📅 Bitiş Tarihi: 21.02.2035 17:45
🔗 Bağlantı: 0 / 1
🌐 Host: http://keyiftv55.shop:8080
📺 M3U Link: http://keyiftv55.shop:8080/get.php?username=2qQRFPLfd8&password=RWJKywTAgY&type=m3u_plus
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | 10 |
| 3 | Pomak_since.m3u | 1 |
| 4 | Rexzxlad.m3u | 1 |
| 5 | if (currentChannelIndex >= 0 && channels[currentChannelIndex]) {
handlePlaybackError(); // yeniden bağlan
}
});
// Kanal listesinde hızlı kaydırma için zaten overflow-auto ve yeterli yükseklik.
// Uzun kanal listesi için max-height ayarı yok, %100.
</script>
<!-- HLS.js desteği için ek kütüphane (eğer native destek yoksa) -->
<script src="https://cdn.jsdelivr.net/npm/hls.js@1.5.7/dist/hls.min.js"></script>
</body>
</html> | 72 |
| 6 | div.setAttribute('data-index', idx);
div.setAttribute('tabindex', '0');
div.innerText = ch.name;
div.addEventListener('click', (e) => {
e.stopPropagation();
// linke basarken otomatik asansör gibi aç (hızlı kanal geçişi)
loadChannel(idx, true);
// odak kaydırma (hızlı liste içinde)
div.focus();
});
// klavye ve kumanda desteği için Enter tuşu
div.addEventListener('keydown', (e) => {
if (e.key === 'Enter' e.key === ' ' e.key === 'Select') {
e.preventDefault();
loadChannel(idx, true);
div.focus();
}
});
channelListDiv.appendChild(div);
});
if (channels.length === 0) {
channelListDiv.innerHTML = '<div style="padding:20px;color:#aaa;">Kanal bulunamadı</div>';
}
}
// KUMANDA VE KLavye desteği: Yukarı / Aşağı ile kanal listesinde hızlı gezinme,
// ayrıca video oynatıcıda focus yönetimi.
document.addEventListener('keydown', (e) => {
const key = e.key;
// yukarı/aşağı ok tuşları (kumanda ve klavye)
if (key === 'ArrowUp') {
e.preventDefault();
if (currentChannelIndex > 0) {
loadChannel(currentChannelIndex - 1, true);
// otomatik kaydırma asansör efekti
const newActiveItem = document.querySelector(.channel-item[data-index='${currentChannelIndex}']);
if (newActiveItem) newActiveItem.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
} else if (key === 'ArrowDown') {
e.preventDefault();
if (currentChannelIndex < channels.length - 1) {
loadChannel(currentChannelIndex + 1, true);
const newActiveItem = document.querySelector(.channel-item[data-index='${currentChannelIndex}']);
if (newActiveItem) newActiveItem.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
} else if (key === 'Enter' || key === 'Select') {
// eğer odak kanal listesinde değilse, aktif kanalı yeniden yüklemeyi deneme
if (document.activeElement && !document.activeElement.classList?.contains('channel-item')) {
if (currentChannelIndex >= 0) {
e.preventDefault();
loadChannel(currentChannelIndex, true);
}
}
} else if (key === 'Escape' && document.fullscreenElement) {
document.exitFullscreen();
} else if (key === 'f' || key === 'F') {
toggleFullscreen();
}
});
// Kanal listesi odağını yakala ve yukarı/aşağı daha hızlı geçiş için liste içinde scrolling
// Ayrıca mouse tekerleği ile hızlı inip çıkma zaten overflow sayesinde olacak.
// "Hızlı inme çıkma" için scroll hızı yüksek
// CSS ile scroll-behavior smooth ancak fare tekerleği ile hızlı gezinme destekleniyor
// Otomatik açılır asansör efekti: link tıklama anında video anında değişir (tamponsuz)
// Bu mevcut loadChannel ile oluyor.
// Zayıf internet için donma önlemi: video etiketine preload=none + buffer limit + hata yönetimi
// Ayrıca sayfa yüklendiğinde m3u çekilecek.
// Mobil / dokunmatik için video tıklama tam ekran (isteğe bağlı) ekstra
videoElement.addEventListener('dblclick', () => {
toggleFullscreen();
});
// Başlat
fetchAndParseM3U();
// Ek olarak, ağ bağlantısı izleme: tekrar denemelerde kullanıcıya bildirim
window.addEventListener('online', () => {
console.log("Bağlantı yeniden sağlandı, mevcut kanal yeniden yükleniyor..."); | 66 |
| 7 | loadChannel(sameIndex, true);
} else {
hideLoading();
isLoadingVideo = false;
}
}, 800);
}
function showLoading(show) {
if (show) {
loadingIndicator.style.display = 'flex';
} else {
loadingIndicator.style.display = 'none';
}
}
function hideLoading() {
loadingIndicator.style.display = 'none';
}
// M3U dosyasını çek ve ayrıştır
async function fetchAndParseM3U() {
try {
const response = await fetch(M3U_URL);
if (!response.ok) throw new Error(HTTP ${response.status});
const m3uText = await response.text();
parseM3U(m3uText);
} catch (err) {
console.error("M3U yüklenemedi:", err);
channelListDiv.innerHTML = <div style="padding:20px; color:red;">M3U listesi alınamadı. İnterneti kontrol edin.<br>Hata: ${err.message}</div>;
// Demo yedek kanal ekle (gösteri amaçlı test)
addDummyChannels();
}
}
function parseM3U(data) {
const lines = data.split(/\r?\n/);
let newChannels = [];
let currentName = "";
for (let i = 0; i < lines.length; i++) {
let line = lines[i].trim();
if (line.startsWith("#EXTINF:")) {
// #EXTINF:-1 tvg-name="..." group-title="..." , KANAL ADI
const nameMatch = line.match(/,(.*)$/);
if (nameMatch && nameMatch[1]) {
currentName = nameMatch[1].trim();
} else {
currentName = "İsimsiz Kanal";
}
} else if (line && !line.startsWith("#")) {
// URL satırı
if (currentName) {
newChannels.push({
name: currentName,
url: line
});
currentName = "";
} else {
// isim yoksa url'den dosya adı
let fallbackName = "Kanal " + (newChannels.length+1);
newChannels.push({ name: fallbackName, url: line });
}
}
}
if (newChannels.length === 0) {
addDummyChannels();
} else {
channels = newChannels;
renderChannelList();
// İlk kanalı otomatik aç (varsayılan)
if (channels.length > 0) {
loadChannel(0, true);
}
}
}
// Yedek demo kanallar (M3U geçici sorun olursa diye)
function addDummyChannels() {
channels = [];
// Örnek test yayınları (halka açık test akışları, zayıf internete uygun değil ama örnek)
channels.push({ name: "📺 Test 1 (TRT Haber)", url: "https://cdn-trtcanlitv.akamaized.net/channels/trthaber/playlist.m3u8" });
channels.push({ name: "🎥 Test 2 (NASA TV)", url: "https://ntvweblive-lh.akamaihd.net/i/rd_1@328788/master.m3u8" });
channels.push({ name: "🌍 Test 3 (Yaban TV)", url: "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8" });
channels.push({ name: "🎬 Demo Kanal 4", url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" });
channels.push({ name: "🎞️ Klasik Müzik", url: "https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8" });
renderChannelList();
if (channels.length) loadChannel(0, true);
}
// Kanalları listele - uzun liste, hızlı aşağı yukarı kaydırma
function renderChannelList() {
channelListDiv.innerHTML = "";
channels.forEach((ch, idx) => {
const div = document.createElement('div');
div.className = 'channel-item'; | 40 |
| 8 | maxMaxBufferLength: 20,
startLevel: -1, // otomatik kalite seçimi
abrEwmaDefaultEstimate: 500000,
manifestLoadingTimeOut: 10000,
manifestLoadingMaxRetry: 3,
levelLoadingTimeOut: 8000,
fragLoadingTimeOut: 10000,
});
hls.loadSource(videoSrc);
hls.attachMedia(videoElement);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
if (autoPlay) {
videoElement.play().then(() => {
hideLoading();
isLoadingVideo = false;
retryCount = 0;
}).catch(err => {
console.error("HLS oynatma başlatılamadı:", err);
handlePlaybackError();
});
}
});
hls.on(Hls.Events.ERROR, (event, data) => {
if (data.fatal) {
console.error("HLS fatal hatası:", data);
switch(data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
// ağ hatasında tekrar dene - zayıf internet için kurtarma
console.log("Ağ hatası, yeniden bağlanma denenecek");
handlePlaybackError();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
handlePlaybackError();
break;
default:
handlePlaybackError();
break;
}
} else {
// non-fatal hatayı görmezden gel, oynatmaya devam
console.warn("HLS non-fatal:", data);
hideLoading();
}
});
hls.on(Hls.Events.BUFFER_APPENDING, () => {
// tampon doluyorsa loading gizle
hideLoading();
});
} catch (err) {
console.error("HLS kurulum hatası:", err);
hideLoading();
isLoadingVideo = false;
}
}
else {
// Hiçbir destek yoksa uyarı
console.error("M3U8 oynatma desteklenmiyor");
channelNameBar.innerText = channel.name + " (destek yok)";
hideLoading();
isLoadingVideo = false;
}
}
// Hata Yönetimi: Zayıf internet donma/kasmalarında otomatik yeniden bağlanma (oynatmayı devam ettir)
function handlePlaybackError() {
if (retryCount >= 3) {
console.warn("3 kez başarısız oldu, kullanıcıya bilgi ver.");
channelNameBar.innerText = channels[currentChannelIndex]?.name + " (Yüklenemedi, kanal geçiş yapın)";
hideLoading();
isLoadingVideo = false;
retryCount = 0;
return;
}
retryCount++;
console.log(Yeniden bağlanma denemesi ${retryCount}...);
showLoading(true);
// mevcut kanalı tekrar yükle (küçük gecikme ile)
setTimeout(() => {
if (currentChannelIndex >= 0 && currentChannelIndex < channels.length) {
// hızlı şekilde reload
const sameIndex = currentChannelIndex;
// önce mevcut medyayı temizle
if (hls) { hls.destroy(); hls = null; }
videoElement.pause();
videoElement.src = '';
videoElement.load(); | 27 |
| 9 | // Ek olarak native HLS için hata yönetimi donmayı önlemek adına
let hls = null;
function initHLSIfNeeded() {
if (Hls && Hls.isSupported()) {
return true;
}
return false;
}
// Video oynatıcıyı temizle ve kanalı yükle (zayıf internet için "oynatmayı devam et" mekanizması)
function loadChannel(index, autoPlay = true) {
if (index < 0 || index >= channels.length) return false;
if (isLoadingVideo) {
// zaten yükleniyorsa kısmi önlem
console.log("Yükleme zaten devam ediyor, tekrarı geciktir");
return false;
}
const channel = channels[index];
if (!channel || !channel.url) return false;
currentChannelIndex = index;
channelNameBar.innerText = channel.name;
// UI'da aktif kanal vurgusu
document.querySelectorAll('.channel-item').forEach((item, idx) => {
if (idx === index) {
item.classList.add('active');
item.focus();
// Otomatik kaydırma: aktif kanalı görünür yap (asansör efekti)
item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
} else {
item.classList.remove('active');
}
});
// Yükleniyor göster
showLoading(true);
isLoadingVideo = true;
// Önceki medya ve HLS temizliği
if (hls) {
hls.destroy();
hls = null;
}
videoElement.pause();
videoElement.removeAttribute('src');
videoElement.load();
const videoSrc = channel.url;
// Native HLS desteği (Android TV, modern Chrome)
const canPlayM3U8 = videoElement.canPlayType('application/vnd.apple.mpegurl') !== '' ||
videoElement.canPlayType('application/x-mpegURL') !== '';
if (canPlayM3U8) {
// Native oynatma, hata durumunda yeniden dene (kasma/donma önleme)
videoElement.src = videoSrc;
videoElement.load();
if (autoPlay) {
let playPromise = videoElement.play();
if (playPromise !== undefined) {
playPromise.then(() => {
console.log("Native oynatma başarılı");
hideLoading();
isLoadingVideo = false;
retryCount = 0;
}).catch(error => {
console.error("Oynatma hatası (native):", error);
handlePlaybackError();
});
}
}
// Hata dinleyicisi: ağ veya medya hatalarında yeniden bağlanma
videoElement.onerror = (e) => {
console.warn("Video hatası:", videoElement.error);
if (videoElement.error && (videoElement.error.code === 2 || videoElement.error.code === 3)) {
handlePlaybackError();
}
hideLoading();
isLoadingVideo = false;
};
videoElement.onloadeddata = () => {
hideLoading();
isLoadingVideo = false;
retryCount = 0;
};
videoElement.onstalled = () => {
console.warn("Akış takıldı (stalled), yeniden başlatılıyor..");
handlePlaybackError();
};
}
else if (initHLSIfNeeded()) {
// HLS.js ile m3u8 oynatımı (daha kontrollü tampon)
try {
hls = new Hls({
enableWorker: true,
lowLatencyMode: true,
maxBufferLength: 10, // küçük buffer - düşük gecikme ama zayıf internet için yeniden yüklemeyi hızlandırır | 29 |
| 10 | .loading-indicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,0.8);
color: yellow;
padding: 12px 24px;
border-radius: 40px;
font-size: 1.2rem;
font-weight: bold;
z-index: 200;
display: none;
backdrop-filter: blur(6px);
pointer-events: none;
}
/* kumanda / odak yönetimi */
.focusable {
outline: none;
}
/* mobil / tablet uyumu */
@media (max-width: 768px) {
.channel-list {
width: 40%;
min-width: 130px;
}
.channel-item {
padding: 14px 10px;
font-size: 0.9rem;
}
}
/* KAYDIRMA ÇUBUĞU ince ama kullanışlı */
.channel-list::-webkit-scrollbar {
width: 5px;
}
.channel-list::-webkit-scrollbar-track {
background: #222;
}
.channel-list::-webkit-scrollbar-thumb {
background: #ffcc00;
border-radius: 5px;
}
/* hızlı açılma hissi için animasyon */
.channel-item {
transition: background 0.05s, border-left 0.05s;
}
</style>
</head>
<body>
<div class="app-container">
<!-- UZUN KANAL LİSTESİ - otomatik asansör gibi açılma (link basarken hızlı geçiş) -->
<div class="channel-list" id="channelList" tabindex="0">
<!-- Kanal listesi js ile doldurulacak -->
<div style="padding: 20px; text-align:center; color:#aaa;">Kanal listesi yükleniyor...</div>
</div>
<div class="video-area">
<div class="video-wrapper">
<video id="videoPlayer" autoplay muted preload="none" controlslist="nodownload" disablePictureInPicture>
<source src="" type="application/vnd.apple.mpegurl">
Tarayıcınız M3U8 desteklemiyor.
</video>
<button class="fullscreen-btn" id="fullscreenBtn">⛶</button>
<div class="channel-name-bar" id="channelNameBar">Kanal Seçiniz</div>
</div>
<div class="loading-indicator" id="loadingIndicator">⏳ Yükleniyor...</div>
</div>
</div>
<script>
// M3U BAĞLANTISI (VERİLEN LİNK)
const M3U_URL = "https://m3u.ch/pl/8f663c608cd73e594c1ae900c82e75d8_837df462bf1466d9194753fda784da88.m3u";
// ZAYIF İNTERNET İÇİN TAMPONLAMA / DONMA KARŞITI STRATEJİLER:
// - preload="none" yaparak gereksiz ön yükleme engeli; akış başlatılırken düşük buffer
// - Hata yönetimi ile yeniden bağlanma, video elementinin reload mekanizması.
// - Ayrıca canlı yayınlarda "kasma" için live seekable vb.
let channels = []; // { name, url }
let currentChannelIndex = -1;
let retryCount = 0;
let isLoadingVideo = false;
let videoElement = document.getElementById('videoPlayer');
let channelListDiv = document.getElementById('channelList');
let loadingIndicator = document.getElementById('loadingIndicator');
let channelNameBar = document.getElementById('channelNameBar');
let fullscreenBtn = document.getElementById('fullscreenBtn');
// Tam ekran desteği (Android TV & Kumanda)
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(err => {
console.warn(Tam ekran hatası: ${err.message});
});
} else {
document.exitFullscreen();
}
}
fullscreenBtn.addEventListener('click', toggleFullscreen);
// HLS.js desteği (eğer tarayıcı native m3u8 desteklemiyorsa, ama modern android TV ve Chrome destekler) | 1 |
| 11 | <!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>PomakGO TV - Hızlı Kanal Listesi</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none; /* Mobil/Kumanda seçimini engelleme */
}
body {
background: #0a0a0a;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
overflow: hidden;
height: 100vh;
width: 100vw;
position: fixed;
}
/* ANA UYGULAMA KAPSI */
.app-container {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
background: #000;
}
/* SOL: KANAL LİSTESİ (UZUN, HIZLI KAYDIRMA) */
.channel-list {
width: 35%;
max-width: 320px;
background: #111;
border-right: 2px solid #2c3e66;
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
height: 100%;
-webkit-overflow-scrolling: touch;
}
/* Kanal öğeleri - büyük dokunma alanı, kumanda dostu */
.channel-item {
padding: 18px 16px;
border-bottom: 1px solid #222;
color: #eee;
font-size: 1.2rem;
font-weight: 500;
cursor: pointer;
transition: all 0.08s linear;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
background: #111;
border-left: 4px solid transparent;
}
.channel-item:focus, .channel-item.active {
background: #1e3a5f;
border-left: 4px solid #ffcc00;
color: white;
outline: none;
font-weight: bold;
}
/* HOVER / AKTİF */
.channel-item:hover {
background: #2a2a2a;
}
/* SAĞ: VIDEO OYNATICI */
.video-area {
flex: 1;
display: flex;
flex-direction: column;
background: #000;
position: relative;
height: 100%;
}
.video-wrapper {
flex: 1;
background: #000;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
video {
width: 100%;
height: 100%;
object-fit: contain;
background: black;
}
/* Tam ekran kontrolü */
.fullscreen-btn {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(0,0,0,0.7);
border: none;
color: white;
font-size: 28px;
padding: 10px 16px;
border-radius: 40px;
cursor: pointer;
z-index: 100;
backdrop-filter: blur(6px);
transition: 0.1s;
}
.fullscreen-btn:active {
background: #ffcc00;
color: black;
}
/* alt bilgi (kanal adı) */
.channel-name-bar {
background: #000000cc;
color: #ffcc00;
padding: 8px 16px;
font-size: 1rem;
text-align: center;
backdrop-filter: blur(4px);
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 50;
pointer-events: none;
}
/* YÜKLEME GÖSTERGESİ - ZAYIF İNTERNET İÇİN BEKLEME */ | 1 |
| 12 | V | 29 |
| 13 | // Periyodik buffer kontrolü: aşırı tamponlamayı önle (zayıf internet)
setInterval(() => {
if(videoElement && videoElement.networkState === 2 && videoElement.readyState < 2 && !isChangingChannel) {
// eğer bekliyorsa ve loading gösterilmiyorsa hafif uyarı
if(loadingOverlay.style.display !== 'flex') {
showLoading(true, "Düşük hız, tampon devam ediyor...");
setTimeout(() => { if(videoElement.readyState >= 2) showLoading(false); }, 3000);
}
}
}, 4000);
}
init();
</script>
</body>
</html> | 4 |
| 14 | numberSpan.className = 'channel-number';
numberSpan.innerText = (idx+1).toString().padStart(2,'0');
const nameSpan = document.createElement('span');
nameSpan.className = 'channel-name';
nameSpan.innerText = ch.name.length > 28 ? ch.name.slice(0,25)+'...' : ch.name;
channelDiv.appendChild(numberSpan);
channelDiv.appendChild(nameSpan);
channelDiv.addEventListener('click', (e) => {
e.stopPropagation();
if (isChangingChannel) return;
playChannelByIndex(idx);
});
// TV kumandası için Enter tuşu desteği
channelDiv.addEventListener('keypress', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
if (!isChangingChannel) playChannelByIndex(idx);
}
});
container.appendChild(channelDiv);
});
if(activeChannelIndex !== -1) highlightActiveChannel(activeChannelIndex);
}
// Tam Ekran Fonksiyonu (tam ekran desteği Android TV ve tarayıcı)
function toggleFullscreen() {
const wrapper = document.getElementById('videoWrapper');
if (!document.fullscreenElement) {
wrapper.requestFullscreen().catch(err => {
console.warn(Tam ekran hatası: ${err.message});
// alternatif video element fullscreen
videoElement.requestFullscreen();
});
} else {
document.exitFullscreen();
}
}
// Kumanda desteği (ok tuşları ile kanal listesinde gezinme)
function setupRemoteControl() {
window.addEventListener('keydown', (e) => {
const key = e.key;
const channelItems = document.querySelectorAll('.channel-item');
if (key === 'ArrowUp') {
e.preventDefault();
if (activeChannelIndex > 0) {
playChannelByIndex(activeChannelIndex - 1);
} else if (channels.length > 0) {
playChannelByIndex(channels.length - 1);
}
} else if (key === 'ArrowDown') {
e.preventDefault();
if (activeChannelIndex < channels.length - 1) {
playChannelByIndex(activeChannelIndex + 1);
} else if (channels.length > 0) {
playChannelByIndex(0);
}
} else if (key === 'Enter' key === ' ' key === 'Space') {
if (document.activeElement && document.activeElement.classList && document.activeElement.classList.contains('channel-item')) {
// zaten tıklama event'i var
} else {
// boş alanda enter basılırsa mevcut kanal yeniden başlatılabilir
if(activeChannelIndex !== -1 && !isChangingChannel){
playChannelByIndex(activeChannelIndex);
}
}
} else if (key === 'f' key === 'F' key === 'Fullscreen') {
e.preventDefault();
toggleFullscreen();
}
});
// Liste oluştuktan sonra focus yönetimi için ilk öğeye odaklanma opsiyonu
setTimeout(()=>{
const first = document.querySelector('.channel-item');
if(first) first.focus();
}, 500);
}
// Başlangıç ve zayıf internet ayarları, donma önleyici periyodik temizlik
function init() {
configureVideoForWeakNetwork();
loadM3U();
setupRemoteControl();
const fullBtn = document.getElementById('fullscreenBtn');
if(fullBtn) fullBtn.addEventListener('click', toggleFullscreen); | 2 |
| 15 | } else {
item.classList.remove('active');
}
});
}
// M3U dosyasını çek ve kanal listesini oluştur (donma ve hata toleranslı)
async function loadM3U() {
try {
const response = await fetch(M3U_URL, { cache: "no-store" });
if (!response.ok) throw new Error("M3U alınamadı");
const m3uText = await response.text();
parseM3U(m3uText);
} catch (err) {
console.error("M3U yükleme hatası:", err);
document.getElementById('channelsContainer').innerHTML = <div style="padding:20px;color:red;">M3U listesi yüklenemedi. Bağlantınızı kontrol edin.<br>Demo kanallarla devam edin? (hata önleme)</div>;
// Hata durumunda örnek demo kanallar (kullanıcının boş ekran görmemesi için)
addDemoChannels();
}
}
// M3Ü ayrıştırıcı (standart format)
function parseM3U(data) {
const lines = data.split(/\r?\n/);
let newChannels = [];
let current = null;
for (let line of lines) {
line = line.trim();
if (line.startsWith('#EXTINF:')) {
// #EXTINF:-1 tvg-id="..." tvg-name="..." group-title="...",Kanal Adı
const nameMatch = line.match(/,([^,]+)$/);
let name = nameMatch ? nameMatch[1] : "İsimsiz Kanal";
// temizlik
name = name.replace(/\([^)]*\)/g, '').trim();
if(name === "") name = "Kanal";
current = { name: name, url: "" };
} else if (line && !line.startsWith('#') && current) {
current.url = line;
if (current.url && current.name) {
newChannels.push(current);
}
current = null;
}
}
// Yedek: Eğer hiç kanal yoksa veya URL'ler geçersizse demo ekle
if (newChannels.length === 0) {
addDemoChannels();
} else {
channels = newChannels;
renderChannelList();
// ilk kanalı otomatik oynat (zayıf internet için)
if (channels.length > 0) {
playChannelByIndex(0);
} else {
addDemoChannels();
}
}
}
// Demo kanal (eğer M3U boşsa veya hata varsa - donma önleme)
function addDemoChannels() {
channels = [
{ name: "PomakGO Haber", url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" },
{ name: "Nature 4K Demo", url: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" },
{ name: "Spor Pomak", url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" },
{ name: "Belgesel Ultra", url: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" },
{ name: "Müzik Klip", url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" },
{ name: "Pomak TV", url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" }
];
renderChannelList();
if (channels.length) playChannelByIndex(0);
channelInfoDiv.innerText = "⚠️ Demo modu: Gerçek M3U yüklenemedi, örnek akışlar gösteriliyor.";
}
// HTML listeyi oluştur (uzun liste, yukarıdan aşağı)
function renderChannelList() {
const container = document.getElementById('channelsContainer');
if (!container) return;
container.innerHTML = '';
channels.forEach((ch, idx) => {
const channelDiv = document.createElement('div');
channelDiv.className = 'channel-item';
channelDiv.setAttribute('data-index', idx);
channelDiv.setAttribute('tabindex', '0'); // kumanda ile odaklanabilir
const numberSpan = document.createElement('span'); | 2 |
| 16 | if(msgSpan && !customMsg) msgSpan.innerText = "📡 Düşük bant genişliği, tamponlanıyor...";
}
}
} else {
if(loadingOverlay.style.display !== 'none') {
loadingOverlay.style.display = 'none';
}
}
}
// Asansör hızında kanal değişimi: video src'yi hızlıca değiştir, buffer önlemleri.
async function playChannelByIndex(index, isRetry = false) {
if (index < 0 || index >= channels.length) return;
if (isChangingChannel && !isRetry) {
console.log("Zaten kanal değişiyor, beklet");
return;
}
isChangingChannel = true;
showLoading(true, "⏩ Asansör hızında açılıyor...");
activeChannelIndex = index;
const channel = channels[index];
if (!channel || !channel.url) {
showLoading(false);
channelInfoDiv.innerText = "⚠️ Kanal akışı yok";
isChangingChannel = false;
return;
}
// UI aktif kanal vurgusu (hızlı tepki)
highlightActiveChannel(index);
channelInfoDiv.innerText = 📡 ${channel.name} | ⚡ Yükleniyor...;
// Video element mevcut yüklemeyi iptal et ve yeni url ayarla
try {
// Önce video durdur, src boşalt, hızlı geçiş için
videoElement.pause();
videoElement.removeAttribute('src');
videoElement.load(); // reset internal state
// yeni url ata (küçük buffer dene)
videoElement.src = channel.url;
videoElement.load();
// Otomatik oynatım için promise yakala
const playPromise = videoElement.play();
if (playPromise !== undefined) {
playPromise.then(() => {
showLoading(false);
channelInfoDiv.innerText = ▶️ ${channel.name} | Canlı Yayın;
isChangingChannel = false;
}).catch(err => {
console.warn("Oynatma hatası (muhtemelen otomatik politika):", err);
// Eğer kullanıcı etkileşimi yoksa, hata göster ama kanal değişimi tamamlansın
showLoading(false);
channelInfoDiv.innerText = 🔇 ${channel.name} (Sesi başlatmak için tıklayın);
// Videoyu duraklatmayıp tekrar denemek için manual play? kumandada sorun yok
isChangingChannel = false;
});
} else {
showLoading(false);
isChangingChannel = false;
}
} catch (e) {
console.error("Kanal geçiş hatası", e);
showLoading(false);
channelInfoDiv.innerText = ⚠️ ${channel.name} yüklenemedi;
isChangingChannel = false;
}
// Zaman aşımı: 8 saniyede hala yüklenmiyorsa loading kapat (donma hissini engelle)
if(currentLoadingTimeout) clearTimeout(currentLoadingTimeout);
currentLoadingTimeout = setTimeout(() => {
if(isChangingChannel === true) {
showLoading(false);
if(videoElement.readyState < 2) {
channelInfoDiv.innerText = ⚠️ ${channel.name} yavaş ağ, izlemeye devam;
}
isChangingChannel = false;
}
}, 7000);
}
// Kanal listesindeki aktif kanal vurgusu
function highlightActiveChannel(index) {
const items = document.querySelectorAll('.channel-item');
items.forEach((item, i) => {
if (i === index) {
item.classList.add('active');
// TV kumanda odaklı liste içinde görünmesi için kaydır
item.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); | 1 |
| 17 | <div id="loadingIndicator" class="loading-overlay" style="display: none;">
<div class="spinner"></div>
<div style="margin-top: 12px; font-weight: 500;">📡 Düşük bant genişliği, tamponlanıyor...</div>
</div>
</div>
</div>
</div>
<script>
// M3U URL (verilen kaynak)
const M3U_URL = "https://m3u.ch/pl/8f663c608cd73e594c1ae900c82e75d8_837df462bf1466d9194753fda784da88.m3u";
// ---------- Global değişkenler ----------
let channels = []; // { name, url, tvgLogo, group, ... }
let activeChannelIndex = -1;
let videoElement = document.getElementById('videoPlayer');
let loadingOverlay = document.getElementById('loadingIndicator');
let channelInfoDiv = document.getElementById('channelInfo');
let currentLoadingTimeout = null;
let isChangingChannel = false; // kanal değişim kilidi (eşzamanlı önle)
let retryCount = 0;
// Zayıf internet için buffer stratejisi: düşük başlangıç buffer, hızlı geçiş.
// Video element özelliklerini ayarla
function configureVideoForWeakNetwork() {
videoElement.preload = "metadata";
videoElement.autoplay = true;
videoElement.muted = false; // Ses açık
// Buffer hedefi düşük -> daha hızlı başlatma, daha az donma?
// Ayrıca abort handler, hata yönetimi
videoElement.removeAttribute('disableRemotePlayback');
videoElement.setAttribute('playsinline', 'true');
// Hata durumunda yeniden deneme
videoElement.onerror = (e) => {
console.warn("Video hatası:", e);
if (!isChangingChannel && activeChannelIndex !== -1) {
showLoading(false);
// Hata olursa, aynı kanalı bir kere yeniden dene (2sn sonra)
if(retryCount < 2) {
retryCount++;
setTimeout(() => {
if(activeChannelIndex !== -1) {
playChannelByIndex(activeChannelIndex, true);
}
}, 800);
} else {
retryCount = 0;
channelInfoDiv.innerText = "❌ Bağlantı hatası, başka kanal deneyin";
}
} else {
showLoading(false);
}
};
// Buffer yetersizliğinde loading gösterme zayıf internet durumunda:
// waiting event ekleyelim ve kullanıcıya bildirelim
videoElement.onwaiting = () => {
if(!isChangingChannel && activeChannelIndex !== -1) {
showLoading(true, "Düşük internet, tamponlanıyor...");
}
};
videoElement.onplaying = () => {
showLoading(false);
retryCount = 0;
};
videoElement.oncanplay = () => {
showLoading(false);
};
videoElement.onstalled = () => {
if(!isChangingChannel) showLoading(true, "Bağlantı yavaş, bekleniyor...");
};
}
// Loading overlay kontrolü (donma hissini azaltmak için fade yaklaşımı)
function showLoading(show, customMsg = null) {
if(show) {
if(loadingOverlay.style.display !== 'flex') {
loadingOverlay.style.display = 'flex';
if(customMsg) {
let msgSpan = loadingOverlay.querySelector('div:last-child');
if(msgSpan) msgSpan.innerText = customMsg;
else {
let pDiv = document.createElement('div');
pDiv.style.marginTop = '12px';
pDiv.innerText = customMsg;
loadingOverlay.appendChild(pDiv);
}
} else {
let msgSpan = loadingOverlay.querySelector('div:last-child'); | 1 |
| 18 | /* Altyazı & üst bar */
.info-bar {
position: absolute;
bottom: 20px;
left: 20px;
background: rgba(0,0,0,0.6);
backdrop-filter: blur(10px);
padding: 6px 14px;
border-radius: 30px;
font-size: 0.8rem;
pointer-events: none;
z-index: 15;
font-weight: 500;
}
/* Tam ekran butonu (opsiyonel, kumanda için fullscreen API) */
.fullscreen-btn {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(0,0,0,0.7);
border: none;
color: white;
font-size: 24px;
width: 44px;
height: 44px;
border-radius: 44px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 15;
backdrop-filter: blur(8px);
transition: 0.1s linear;
}
.fullscreen-btn:active {
transform: scale(0.94);
}
/* yükleme göstergesi (donma önleyici - sessiz buffer) */
.loading-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
backdrop-filter: blur(4px);
z-index: 20;
transition: opacity 0.2s;
pointer-events: none;
}
.spinner {
width: 48px;
height: 48px;
border: 4px solid rgba(255,255,255,0.2);
border-top: 4px solid #ff6a00;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Zayıf internet için düşük profil ve hızlı değişim */
video::-webkit-media-controls {
display: block !important;
}
/* Kumanda odak göstergesi */
.channel-item:focus-visible {
outline: 3px solid #ffaa44;
outline-offset: 2px;
background: #2e3548;
}
/* mobil veya küçük ekranlarda liste biraz daralabilir */
@media (max-width: 768px) {
.channel-list {
width: 40%;
}
.channel-item {
padding: 10px 8px;
}
.channel-name {
font-size: 0.8rem;
}
}
/* kaydırma stili */
.channel-list::-webkit-scrollbar {
width: 6px;
}
.channel-list::-webkit-scrollbar-track {
background: #1a1c24;
}
.channel-list::-webkit-scrollbar-thumb {
background: #ff6a00;
border-radius: 6px;
}
</style>
</head>
<body>
<div class="app-container">
<!-- Uzun kanal listesi - yukarıdan aşağıya -->
<div class="channel-list" id="channelList">
<div class="list-header">
<h2>📺 PomakGO</h2>
<p>⚡ Asansör hızında geçiş • Zayıf internet dostu</p>
</div>
<div id="channelsContainer"></div>
</div>
<!-- Video oynatıcı bölgesi -->
<div class="player-area">
<div class="video-wrapper" id="videoWrapper">
<video id="videoPlayer" controls playsinline autoplay muted preload="metadata" controlsList="nodownload"></video>
<div class="info-bar" id="channelInfo">🎬 Kanal seçiniz</div>
<button class="fullscreen-btn" id="fullscreenBtn" aria-label="Tam Ekran">⛶</button> | 1 |
| 19 | <!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>PomakGO - Akıcı TV İzleme</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none; /* TV kumandası ile seçimi engelle, daha temiz his */
}
body {
background: #0a0c12;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #fff;
overflow: hidden;
height: 100vh;
width: 100vw;
position: fixed;
}
/* Ana Grid: sol kanal listesi + sağ oynatıcı */
.app-container {
display: flex;
height: 100%;
width: 100%;
background: #000;
}
/* KANAL LİSTESİ - Yukarıdan aşağıya uzun liste, taşma durumunda kaydırma */
.channel-list {
width: 32%;
max-width: 380px;
background: rgba(18, 20, 28, 0.95);
backdrop-filter: blur(8px);
border-right: 1px solid #2c2f3a;
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
z-index: 10;
transition: all 0.2s ease;
/* TV kumandası ile odaklanabilir */
}
/* Liste başlığı */
.list-header {
padding: 18px 16px;
background: #0f1119;
border-bottom: 2px solid #ff6a00;
position: sticky;
top: 0;
z-index: 2;
}
.list-header h2 {
font-size: 1.4rem;
font-weight: 600;
letter-spacing: 1px;
background: linear-gradient(135deg, #ff9a3c, #ff4d00);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.list-header p {
font-size: 0.7rem;
color: #aaa;
margin-top: 6px;
}
/* Kanal öğeleri - uzun liste için kompakt ama tıklanabilir */
.channel-item {
display: flex;
align-items: center;
padding: 14px 16px;
margin: 4px 8px;
border-radius: 14px;
background: #1e212b;
cursor: pointer;
transition: all 0.15s cubic-bezier(0.2, 0.9, 0.4, 1.1);
border-left: 3px solid transparent;
gap: 12px;
font-weight: 500;
}
/* Aktif kanal efekti (asansör hissi) */
.channel-item.active {
background: #ff6a00;
border-left: 4px solid #fff;
box-shadow: 0 6px 14px rgba(255, 106, 0, 0.3);
transform: scale(1.01);
}
.channel-number {
font-weight: bold;
background: #2f3340;
padding: 5px 10px;
border-radius: 40px;
font-size: 0.8rem;
min-width: 48px;
text-align: center;
color: #ffbc7a;
}
.channel-item.active .channel-number {
background: #fff2e5;
color: #ff4d00;
}
.channel-name {
font-size: 0.95rem;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Sağ oynatıcı alanı - tam ekran desteği */
.player-area {
flex: 1;
display: flex;
flex-direction: column;
background: #000000;
position: relative;
}
.video-wrapper {
flex: 1;
background: #000;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
video {
width: 100%;
height: 100%;
object-fit: contain; /* tam ekranda da oran korunsun, siyah bantlar */
background: #000;
} | 1 |
| 20 | }
let cleanUrl = url.trim();
setStatus(Yükleniyor: ${cleanUrl.substring(0, 70)}...);
// Video.js ile kaynağı değiştir
player.pause();
player.src({ type: determineContentType(cleanUrl), src: cleanUrl });
player.load();
player.play().then(() => {
setStatus(▶️ Oynatılıyor: ${cleanUrl.substring(0, 80)});
currentSource = cleanUrl;
}).catch(err => {
console.warn("otomatik oynatma engellendi:", err);
setStatus(⏸️ Yüklendi ancak otomatik oynatma engellendi. (Tarayıcı politikası) - butona basarak oynatabilirsiniz., false);
currentSource = cleanUrl;
});
return true;
}
// URL tipi sezgisel belirleme (m3u8, mp4, m3u destekli)
function determineContentType(url) {
if (url.includes('.m3u8') || url.includes('m3u8')) return 'application/x-mpegURL';
if (url.includes('.mp4')) return 'video/mp4';
if (url.includes('.ts')) return 'video/MP2T';
if (url.includes('.m3u')) return 'application/vnd.apple.mpegurl'; // M3U listesi için HLS benzeri
return 'application/x-mpegURL'; // varsayılan HLS
}
// M3U dosyasını çek, ilk geçerli stream url'sini al
async function fetchAndPlayM3U(url) {
setStatus(📡 M3U listesi taranıyor: ${url.substring(0, 60)}...);
try {
const response = await fetch(url);
if (!response.ok) throw new Error(HTTP ${response.status});
const text = await response.text();
const lines = text.split(/\r?\n/);
let firstMediaUrl = null;
for (let line of lines) {
line = line.trim();
if (line && !line.startsWith('#') && (line.startsWith('http://') || line.startsWith('https://'))) {
firstMediaUrl = line;
break;
}
}
if (firstMediaUrl) {
setStatus(M3U içinden ilk yayın bulundu, oynatılıyor...);
loadAndPlay(firstMediaUrl);
} else {
setStatus("M3U listesinde geçerli bir yayın URL'si bulunamadı.", true);
}
} catch (err) {
setStatus(M3U hatası: ${err.message}, true);
}
}
// Ana yükleme: eğer .m3u uzantılıysa veya içerik tipi m3u gibi ise ayrıştır, değilse doğrudan oynat.
function handleLoad() {
let rawUrl = urlInput.value.trim();
if (!rawUrl) {
setStatus("Lütfen bir IPTV yayın URL'si veya M3U linki girin.", true);
return;
}
if (rawUrl.includes('.m3u') || rawUrl.toLowerCase().includes('m3u8') === false && rawUrl.match(/\.m3u($|\?)/i)) {
// M3U dosyası olabilir
fetchAndPlayM3U(rawUrl);
} else {
// Normal video ya da m3u8 stream
loadAndPlay(rawUrl);
}
}
// Durdur / temizle
function stopAndReset() {
player.pause();
player.src({ type: 'video/mp4', src: '' }); // kaynağı temizle
player.load(); // reload
setStatus("⏹️ Yayın durduruldu. Yeni bir URL girebilirsiniz.");
currentSource = null;
urlInput.value = ""; // isteğe bağlı temizleme
}
// Örnek butonları için
document.querySelectorAll('.preset-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const presetUrl = btn.getAttribute('data-url');
if (presetUrl) {
urlInput.value = presetUrl;
handleLoad();
}
});
});
document.getElementById('loadBtn').addEventListener('click', handleLoad);
document.getElementById('stopBtn').addEventListener('click', stopAndReset);
// Enter tuşu desteği
urlInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') handleLoad();
});
setStatus("IPTV oynatıcı hazır. M3U listesi URL'si veya canlı yayın bağlantısı yükleyin.");
</script>
</body>
</html> | 2 |
Available now! Telegram Research 2025 — the year's key insights 
