Keşfet
Bağlan
Daha fazla bildirim göster
Daha fazla mesaj göster
Bildirim Ayarları
Vugar Farzaliyev
baku, Azerbaijan
34915 Parçalar
1 Çalma listeleri
🎧 5
📥 0
2026-03-03T00:19:40+04:00
Tacir Rustemov & Gulka Elekberli
Azerbaijan
İncime
Beğen
Ekle
Yorum
🎧 2
📥 0
2026-03-03T00:09:40+04:00
Aytən Məhərrəmova
Azerbaijan
Gözlər
Beğen
Ekle
Yorum
🎧 3
📥 0
2026-03-02T22:36:10+04:00
Xəyalə Qafarzadə
Azerbaijan
Maralım
Beğen
Ekle
Yorum
🎧 3
📥 0
2026-03-02T22:35:10+04:00
Elsen Pro & Hüseyn Enes
Remix
Fadimem
Beğen
Ekle
Yorum
🎧 1
📥 0
2026-03-02T22:34:30+04:00
Gülay Zeynallı
Azerbaijan
Doya doya
Beğen
Ekle
Yorum
🎧 6
📥 0
2026-03-02T22:32:15+04:00
Fuad İbrahimov
Azerbaijan
Ayıb olsun sənə ayıb
Beğen
Ekle
Yorum
🎧 0
📥 0
2026-03-02T22:30:53+04:00
Gülay Zeynallı
Azerbaijan
Qayıtdım
Beğen
Ekle
Yorum
🎧 1
📥 0
2026-03-02T22:28:36+04:00
Mahir Başkan
Türkçe
Yastayım
Beğen
Ekle
Yorum
🎧 1
📥 0
2026-03-02T20:21:21+04:00
Babek Nur
Azerbaijan
Qara gozler
Beğen
Ekle
Yorum
🎧 1
📥 0
2026-03-02T20:12:34+04:00
Babek Nur
Azerbaijan
Sevgi Dolu Nifret (Remix)
Beğen
Ekle
Yorum
🎧 3
📥 0
2026-03-02T20:11:29+04:00
Pərviz Qasımov & Xəyalə Qafarzadə & Aytən Məhərrəmova
Azerbaijan
Qal sənə qurban
Beğen
Ekle
Yorum
🎧 0
📥 0
2026-03-02T20:09:23+04:00
Fatime Memmedli
Azerbaijan
Allah Allah
Beğen
Ekle
Yorum
🎧 0
📥 0
2026-03-02T20:08:38+04:00
JJ06
Remix
Vivaldi For Automne (Abdullah Özdoğan Rmx)
Beğen
Ekle
Yorum
🎧 0
📥 0
2026-03-02T20:04:20+04:00
Gökhan Doğanay
Türkçe
Koçgiri
Beğen
Ekle
Yorum
🎧 0
📥 0
2026-03-02T20:02:57+04:00
Orxan Mirzəyev
Azerbaijan
Ad günü
Beğen
Ekle
Yorum
🎧 1
📥 0
2026-03-02T18:51:04+04:00
Derviş Yılmaz
Türkçe
Rüyamda Gördüm Yüzünü
Beğen
Ekle
Yorum
🎧 6
📥 0
2026-03-02T18:49:18+04:00
Zawanbeats
Remix
Aşiqem
Beğen
Ekle
Yorum
🎧 2
📥 1
2026-03-02T18:45:59+04:00
Elsever Goycayli
Azerbaijan
Sen Gedenden (Remix Arif Feda)
Beğen
Ekle
Yorum
🎧 3
📥 1
2026-03-02T18:32:21+04:00
Metanet İsgenderli
Azerbaijan
Asiq Olmusam
Beğen
Ekle
Yorum
🎧 2
📥 1
2026-03-02T18:29:40+04:00
Gülay Zeynallı
Azerbaijan
Ağladım
Beğen
Ekle
Yorum
🎧 1
📥 1
2026-03-02T18:29:02+04:00
Pərviz Qasımov & Xəyalə Qafarzadə & Aytən Məhərrəmova
Azerbaijan
Nə bağ bildi, nə də bağban
Beğen
Ekle
Yorum
🎧 4
📥 1
2026-03-02T16:34:36+04:00
Taner Yalçın
Remix
Annem Gibi
Beğen
Ekle
Yorum
🎧 2
📥 1
2026-03-02T16:33:58+04:00
Dilek Ergin
Türkçe
Senin Ellerinde
Beğen
Ekle
Yorum
🎧 2
📥 1
2026-03-02T15:35:08+04:00
Xəyalə Qafarzadə & Aytən Məhərrəmova
Azerbaijan
Azərbaycan
Beğen
Ekle
Yorum
🎧 11
📥 1
2026-03-02T15:31:09+04:00
Dodo
Türkçe
Aşkın Izdırabı
Beğen
Ekle
Yorum
🎧 2
📥 0
2026-03-02T15:29:06+04:00
Pərviz Qasımov & Xəyalə Qafarzadə & Aytən Məhərrəmova
Azerbaijan
Qaçaq Nəbi
Beğen
Ekle
Yorum
🎧 7
📥 0
2026-03-02T14:57:54+04:00
Amin Abbasov
Azerbaijan
Ölüm Sənin Qucağında
Beğen
Ekle
Yorum
🎧 5
📥 1
2026-03-02T04:28:03+04:00
Elektro Bağlama
AI
Elektro Bağlama
Beğen
Ekle
Yorum
🎧 15
📥 5
2026-03-02T00:52:33+04:00
Zahide Güneş
Azerbaijan
Deli Fırtına
Beğen
Ekle
Yorum
🎧 14
📥 0
2026-03-02T00:48:22+04:00
Haksızlığıda Koydum Bavula Sevda Annem Gibi ( Taner Yalçın Remix )
Remix
Haksızlığıda Koydum Bavula Sevda Annem Gibi ( Taner Yalçın Remix )
Beğen
Ekle
Yorum
🎧 4
📥 1
2026-03-02T00:47:36+04:00
Deniz Bolat
Remix
Bir Taraf Seç
Beğen
Ekle
Yorum
🎧 7
📥 1
2026-03-01T21:29:11+04:00
Murda
Remix
Ahlele Ahlelas ( Uğur Yılmaz & Kadir Koca Remix ) Hay Allah
Beğen
Ekle
Yorum
🎧 16
📥 1
2026-03-01T21:28:03+04:00
Caspian Pulse
AI
Həsrət Qaldığım Yeni Instrumental Azerbaycan Mahnısı
Beğen
Ekle
Yorum
🎧 7
📥 0
2026-03-01T21:26:53+04:00
Zeyn
Azerbaijan
Kusura Bakma (Cover)
Beğen
Ekle
Yorum
🎧 37
📥 3
2026-03-01T19:49:42+04:00
Hayit Murat
Remix
Trapline
Beğen
Ekle
Yorum
🎧 60
📥 2
2026-03-01T19:48:37+04:00
Zay Diem
Türkçe
Epifani
Beğen
Ekle
Yorum
🎧 180
📥 5
2026-03-01T19:48:00+04:00
Qayıt Gülüm
AI
Qayıt Gülüm
Beğen
Ekle
Yorum
🎧 1,281
📥 607
2026-03-01T19:47:05+04:00
Rauf Tagiyev
AI
Твой аромат витает в воздухе (etrin duyulur havada) rus version
Beğen
Ekle
Yorum
🎧 35
📥 2
2026-03-01T19:45:08+04:00
Rashad Rc
Remix
Zülmkar
Beğen
Ekle
Yorum
🎧 12
📥 5
2026-03-01T17:09:03+04:00
Ararsan Açmam Psychedelic Anatolian LapMusica
AI
Ararsan Açmam Psychedelic Anatolian LapMusica
Beğen
Ekle
Yorum
🎧 11
📥 2
2026-03-01T14:37:41+04:00
Simge
Türkçe
Öpücem
Beğen
Ekle
Yorum
🎧 3
📥 3
2026-03-01T14:37:08+04:00
Simge
Türkçe
Üzülmedin mi?
Beğen
Ekle
Yorum
🎧 4
📥 2
2026-03-01T14:36:36+04:00
Simge
Türkçe
As Bayrakları
Beğen
Ekle
Yorum
🎧 0
📥 1
2026-03-01T14:36:09+04:00
Simge
Türkçe
Yalnız Başına
Beğen
Ekle
Yorum
🎧 1
📥 1
2026-03-01T14:35:42+04:00
Simge Sağın
Türkçe
Ödeme Vakti
Beğen
Ekle
Yorum
🎧 2
📥 4
2026-03-01T14:35:13+04:00
Simge Sağın
Türkçe
Başı Dertte
Beğen
Ekle
Yorum
🎧 2
📥 1
2026-03-01T14:34:41+04:00
Simge
Türkçe
Miş Miş
Beğen
Ekle
Yorum
🎧 1
📥 2
2026-03-01T14:34:12+04:00
Simge
Türkçe
Yankı
Beğen
Ekle
Yorum
🎧 2
📥 3
2026-03-01T14:33:41+04:00
Simge
Türkçe
Prens & Prenses
Beğen
Ekle
Yorum
🎧 0
📥 2
2026-03-01T14:33:08+04:00
Simge & Ozan Bayraşa
Türkçe
Çapkınca
Beğen
Ekle
Yorum
🎧 0
📥 1
2026-03-01T14:32:38+04:00
Simge
Türkçe
Önümüz Yaz
Beğen
Ekle
Yorum
🎧 3
📥 6
2026-03-01T14:29:06+04:00
Simge
Remix
Aşkın Olayım (Onurr)
Beğen
Ekle
Yorum
🎧 0
📥 1
2026-03-01T14:26:41+04:00
Simge
Remix
Bip Bip (Bayraşa Mix)
Beğen
Ekle
Yorum
🎧 23
📥 4
2026-03-01T14:19:27+04:00
Rüya Gibiydin Kabuslarım Oldun ( Ferhat Güneş Remix ) Ahiyan Rüya Gibiydin
Remix
Rüya Gibiydin Kabuslarım Oldun ( Ferhat Güneş Remix ) Ahiyan Rüya Gibiydin
Beğen
Ekle
Yorum
🎧 3
📥 1
2026-03-01T14:18:15+04:00
Simge
Remix
Malum ( Fatih Yılmaz Remix )
Beğen
Ekle
Yorum
🎧 20
📥 2
2026-02-28T23:15:14+04:00
Elsen Pro
Remix
Ellerin Elime Deymir
Beğen
Ekle
Yorum
🎧 7
📥 0
2026-02-28T23:06:41+04:00
Bize Lazım Money
Remix
Cash Flow & El Musto ( Uğur Yılmaz Remix )
Beğen
Ekle
Yorum
🎧 4
📥 3
2026-02-28T23:05:57+04:00
Rubail Azimov
Azerbaijan
ƏZİZ ANAM
Beğen
Ekle
Yorum
🎧 4
📥 6
2026-02-28T22:50:01+04:00
Resad Memmedov
Azerbaijan
Gel Barisaq
Beğen
Ekle
Yorum
🎧 12
📥 3
2026-02-28T22:48:52+04:00
Eypio
Remix
Yeraltı ( Taner Yalçın Remix ) Deep House Remix
Beğen
Ekle
Yorum
Daha fazla yükle
Hakkında
Arşivler
Tüm zamanlar
Mart - 2026
Şubat - 2026
Ocak - 2026
Aralık - 2025
Kasım - 2025
Ekim - 2025
Eylül - 2025
Ağustos - 2025
Temmuz - 2025
Haziran - 2025
Mayıs - 2025
Nisan - 2025
Şubat - 2025
Ocak - 2025
Aralık - 2024
Ocak - 2023
Yorum
Embed
Sosyal ağlarda paylaş
URL paylaş
Embed Code
Otomatik çalma
Kapat
Çalma Listesi
Kaydet
Kapat
Sil
Parçayı silmek istediğinizden emin misiniz?
Bu çalma listesini silmek istediğinizden emin misiniz?
Sil
Vazgeç
Giriş
Kayıt
Beni hatırla
Şifrenizi mi unuttunuz?
Giriş
Kayıt
/* =========================================================== BLUE.AZ — Global Player FIX: - PREV: STOP -> neighbors fetch -> prev PLAY (no restart) - NEXT: Random ON => random; Random OFF => real next (neighbors fetch) next tapılmasa => STOP (random atmaz) =========================================================== */ (function(){ // ---------- CSS ---------- const css = ` .gp{position:fixed;left:0;right:0;bottom:0;z-index:2147483000;display:grid; grid-template-columns:64px 1fr auto;grid-template-rows:auto auto auto; gap:12px;align-items:center;padding:10px 14px; background:rgba(3,10,22,.92);backdrop-filter:blur(8px);color:#e6f4ff; font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif; border-top:1px solid rgba(42,168,255,.25)} .gp-cover{grid-column:1;grid-row:1 / span 3;width:56px;height:56px;border-radius:10px;object-fit:cover;background:#0a122a;cursor:pointer} .gp-info{grid-column:2;grid-row:1;min-width:0;cursor:pointer} .gp-title{font-weight:700;font-size:14px;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .gp-artist{font-size:12px;opacity:.8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px} .gp-time{grid-column:2;grid-row:2;font-size:11px;color:#9dc8ff;margin-top:4px;text-align:left} .gp-ctrls{grid-column:3;grid-row:1 / span 2;display:flex;align-items:center;gap:8px;justify-content:center} .gp-bar{grid-column:2 / span 2;grid-row:3;width:100%;height:8px;background:#163262;border-radius:6px;cursor:pointer;position:relative;box-shadow:inset 0 0 0 1px #1b3c6b} .gp-progress{position:absolute;left:0;top:0;height:100%;width:0;border-radius:6px; background:linear-gradient(90deg,#2aa8ff,#6ad8ff);box-shadow:0 1px 6px #1e9eff66} .gp-btn{height:42px;min-width:42px;border-radius:12px;border:1px solid rgba(42,168,255,.45); background:rgba(255,255,255,.06);color:#cfe6ff;cursor:pointer;display:flex;align-items:center;justify-content:center} .gp-btn:hover{background:rgba(255,255,255,.12);border-color:rgba(42,168,255,.7)} .gp-btn svg{width:24px;height:24px;fill:currentColor;display:block} .gp-btn.play .icon-play{display:inline}.gp-btn.play .icon-pause{display:none} .gp-btn.play.is-playing .icon-play{display:none}.gp-btn.play.is-playing .icon-pause{display:inline} .gp-btn.toggle.active{border-color:rgba(46,224,197,.9);color:#2ee0c5;background:rgba(46,224,197,.1); box-shadow:0 0 0 1px rgba(46,224,197,.35) inset} .gp-vol{width:120px} #gpRateTxt{font-weight:600} @media (max-width:768px){ .gp{grid-template-columns:48px 1fr;grid-template-rows:auto auto auto;gap:6px; padding:8px 10px;} .gp-cover{width:44px;height:44px;grid-row:1 / span 3} .gp-info{display:none} .gp-time{grid-column:2;grid-row:1;text-align:center;font-size:12px;margin-top:0} .gp-ctrls{grid-column:2;grid-row:2;justify-content:center;gap:8px} .gp-bar{grid-column:1 / span 2;grid-row:3;height:6px} .gp-vol{display:none} .gp-btn{min-width:38px;height:38px;border-radius:10px} .gp-btn svg{width:20px;height:20px} }`; if (!document.getElementById('gpStyle')) { const st = document.createElement('style'); st.id = 'gpStyle'; st.textContent = css; document.head.appendChild(st); } // ---------- HTML ---------- if (!document.getElementById('globalPlayer')) { const root = document.createElement('div'); root.id = 'globalPlayer'; root.className = 'gp'; root.innerHTML = `
Player hazırdır
Mahnı seç
00:00 / 00:00
1×
`; document.body.appendChild(root); } // ---------- Selectors ---------- const $ = s => document.querySelector(s); const gp = { info:$('#gpInfo'), cover:$('#gpCover'), title:$('#gpTitle'), artist:$('#gpArtist'), bar:$('#gpBar'), progress:$('#gpProgress'), time:$('#gpTime'), prev:$('#gpPrev'), play:$('#gpPlay'), next:$('#gpNext'), random:$('#gpRandom'), volume:$('#gpVolume'), download:$('#gpDownload'), loopBtn:$('#gpLoop'), mute: $('#gpMute'), rateBtn: $('#gpRate'), rateTxt: $('#gpRateTxt') }; // ---------- Audio ---------- const audio = new Audio(); audio.preload = 'metadata'; audio.crossOrigin = 'anonymous'; window.audioPlayerMain = audio; let current = null; // aktiv track meta let pendingSrc = null; // yalnız PLAY zamanı qoşulacaq src // ---------- Loop persist ---------- let isLoop = false; try { isLoop = localStorage.getItem('gpLoop') === '1'; } catch(_){} function applyLoopUI(){ gp.loopBtn?.classList.toggle('active', isLoop); gp.loopBtn?.classList.add('toggle'); gp.loopBtn?.setAttribute('aria-label', isLoop ? 'Təkrar: açıq' : 'Təkrar: bağlı'); if (gp.loopBtn) gp.loopBtn.title = isLoop ? 'Təkrar: açıq' : 'Təkrar: bağlı'; } function setLoop(v){ isLoop = !!v; audio.loop = isLoop; applyLoopUI(); try { localStorage.setItem('gpLoop', isLoop ? '1' : '0'); } catch(_){} } setLoop(isLoop); // ---------- Random persist ---------- let isRandom = false; try { isRandom = localStorage.getItem('gpRandom') === '1'; } catch(_){} function applyRandomUI(){ if (!gp.random) return; gp.random.classList.add('toggle'); gp.random.classList.toggle('active', isRandom); gp.random.setAttribute('aria-label', isRandom ? 'Random: açıq' : 'Random: bağlı'); gp.random.title = isRandom ? 'Random: açıq' : 'Random: bağlı'; } function setRandom(v){ isRandom = !!v; applyRandomUI(); try { localStorage.setItem('gpRandom', isRandom ? '1' : '0'); } catch(_){} } setRandom(isRandom); // ---------- Queue ---------- const queue = []; function queueAdd(meta){ if (meta && (meta.src||meta.stream||meta.audioUrl)) queue.push(meta); } function queueNext(){ if (queue.length) { const m = queue.shift(); loadAndPlay(m, true); return true; } return false; } // ---------- Anti-repeat helpers ---------- function getTrackId(meta){ if (!meta) return null; if (meta.id != null) return String(meta.id); if (meta.slug) return 'slug:'+meta.slug; const s = meta.src || meta.stream || meta.audioUrl; if (s){ let h=0; for (let i=0;i
= 0) recentIds.splice(ix,1); recentIds.push(id); while (recentIds.length > RECENT_LIMIT) recentIds.shift(); } function getExcludeParam(){ return recentIds.join(','); } // ---------- UI helpers ---------- const fmt = s => { s = Math.max(0, Math.floor(s||0)); const m = Math.floor(s/60), x = s%60; return (m<10?'0':'')+m+':' + (x<10?'0':'')+x; }; const fallbackDownload = meta => meta?.downloadUrl || ('/wait.php?id='+ (meta?.id||'')); const decodeHTML = s => { if (s == null) return ''; const el = document.createElement('textarea'); el.innerHTML = String(s); return el.value; }; function setPlayingUI(isPlaying){ gp.play?.classList.toggle('is-playing', !!isPlaying); gp.play?.setAttribute('aria-label', isPlaying ? 'Dayandır' : 'Oynat'); } // ---------- Broadcast ---------- let lastCast = 0; function getPayload(stateForced){ const dur = isFinite(audio.duration) ? audio.duration : null; const cur = isFinite(audio.currentTime) ? audio.currentTime : null; const state = stateForced || (audio.ended ? 'ended' : (audio.paused ? 'paused' : 'playing')); return { state, currentTime: cur, duration: dur, volume: audio.volume, muted: !!audio.muted, track: current }; } function broadcastState(stateForced){ const payload = getPayload(stateForced); const msg = { type: 'PLAYER_STATE', state: payload.state, isPlaying: payload.state === 'playing', payload }; try { window.postMessage(msg, '*'); } catch(_){} for (let i=0;i
400) { lastCast = now; broadcastState(stateForced); } } // ---------- Cross-tab ---------- let bc; try { bc = new BroadcastChannel('blue_gp'); } catch(_){} function castAcross(type,payload){ try { bc && bc.postMessage({type, payload}); } catch(_){} } bc && bc.addEventListener('message', ev=>{ const m = ev.data || {}; if (m.type === 'PLAYING') { if (!audio.paused) { audio.pause(); setPlayingUI(false); broadcastState('paused'); } } }); audio.addEventListener('play', ()=> castAcross('PLAYING', { id: current?.id || null })); // ---------- UI update ---------- function updateUI(meta){ if (!meta) return; const artist = decodeHTML(meta.artist || ''); const title = decodeHTML(meta.title || ''); // Artist üstə, Song altda gp.title.textContent = artist; gp.artist.textContent = title; gp.cover.src = meta.cover || ''; gp.time.textContent = '00:00 / 00:00'; gp.progress.style.width = '0%'; if (gp.download) gp.download.href = fallbackDownload(meta); document.title = (title ? title + ' – ' : '') + 'BLUE.AZ'; } // ---------- HLS attach ---------- function attachSrc(src){ if (!src) return; if (typeof src === 'string' && src.includes('.m3u8') && !audio.canPlayType('application/vnd.apple.mpegurl')) { const add = ()=> { const Hls = window.Hls; if (Hls && Hls.isSupported()) { const hls = new Hls({ maxBufferLength: 30 }); hls.loadSource(src); hls.attachMedia(audio); } else { audio.src = src; } }; if (!window.Hls) { const s = document.createElement('script'); s.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest'; s.onload = add; document.head.appendChild(s); } else add(); } else { audio.src = src; } } // ---------- Preload next ---------- let nextLinkEl = null; function preloadNext(meta){ if (!meta?.next || isRandom) return; const nsrc = meta.next.src || meta.next.stream || meta.next.audioUrl; if (!nsrc) return; try { if (!nextLinkEl) { nextLinkEl = document.createElement('link'); nextLinkEl.rel = 'preload'; nextLinkEl.as = 'audio'; document.head.appendChild(nextLinkEl); } nextLinkEl.href = nsrc; } catch(_){} } // ---------- Core play ---------- function loadAndPlay(meta, autoplay=true){ if (!meta) return; const src = meta.src || meta.stream || meta.audioUrl; if (!src) return; current = meta; updateUI(meta); audio.loop = isLoop; // src-ni yalnız PLAY zamanı qoşmaq üçün pending-də saxlayırıq pendingSrc = src; if (autoplay){ attachSrc(pendingSrc); pendingSrc = null; audio.play().then(()=>{ setPlayingUI(true); broadcastState('playing'); }) .catch(()=>{ setPlayingUI(false); broadcastState('paused'); }); } else { setPlayingUI(false); broadcastState('paused'); } try{ localStorage.setItem('lastTrackMeta', JSON.stringify(meta)); }catch(_){} applyMediaSession(meta); preloadNext(meta); pushRecent(meta); } // ---------- Random fetch ---------- function fetchRandomGlobalAndPlay(retries=5){ const exclude = getExcludeParam(); const url = `/tracks.php?random=1&all=1` + (exclude ? `&exclude=${encodeURIComponent(exclude)}` : ''); return fetch(url) .then(r=>r.json()) .then(m=>{ const id = getTrackId(m); if (!m || !(m.src||m.stream||m.audioUrl)) throw new Error('empty_track'); if (id && recentIds.includes(id) && retries > 0){ return fetchRandomGlobalAndPlay(retries-1); } loadAndPlay(m,true); }) .catch(_=>{ // random alınmadısa heç nə etmə (istəsən burada fallback yazaq) }); } // ---------- Neighbors fetch (prev/next) ---------- let neighborsFetchInFlight = null; function fetchNeighbors(){ if (!current?.id) return Promise.resolve(null); if (neighborsFetchInFlight) return neighborsFetchInFlight; neighborsFetchInFlight = fetch(`/tracks.php?neighbors=1&id=${encodeURIComponent(current.id)}`) .then(r => r.json()) .then(nb => { if (nb?.prev) current.prev = nb.prev; if (nb?.next) current.next = nb.next; return nb || null; }) .catch(() => null) .finally(() => { neighborsFetchInFlight = null; }); return neighborsFetchInFlight; } function ensurePrevMeta(){ if (current?.prev && (current.prev.src || current.prev.stream || current.prev.audioUrl)) { return Promise.resolve(current.prev); } if (!current?.id) return Promise.resolve(null); return fetchNeighbors().then(()=> current?.prev || null); } function ensureNextMeta(){ if (current?.next && (current.next.src || current.next.stream || current.next.audioUrl)) { return Promise.resolve(current.next); } if (!current?.id) return Promise.resolve(null); return fetchNeighbors().then(()=> current?.next || null); } // ---------- STOP helper ---------- function stopNow(){ try { audio.pause(); } catch(e){} try { audio.currentTime = 0; } catch(e){} setPlayingUI(false); broadcastState('paused'); } // ---------- Next / Prev ---------- function playNext(){ // 0) queue varsa onu oynat if (queueNext()) return; // 1) Random ON -> random track if (isRandom) { if (current) pushRecent(current); fetchRandomGlobalAndPlay(); return; } // 2) Random OFF -> next hazırdırsa oynat if (current?.next && (current.next.src || current.next.stream || current.next.audioUrl)) { loadAndPlay(current.next, true); return; } // 3) Random OFF -> neighbors-dan next çək, varsa oynat ensureNextMeta().then(next => { if (next && (next.src || next.stream || next.audioUrl)) { loadAndPlay(next, true); return; } // 4) Next tapılmadı -> random atma, STOP qal stopNow(); }); } function playPrev(){ // 1) cari musiqini STOP et stopNow(); // 2) prev-i tap (neighbors) və PLAY ensurePrevMeta().then(prev => { if (prev && (prev.src || prev.stream || prev.audioUrl)) { loadAndPlay(prev, true); return; } // 3) Prev tapılmadı -> restart eləmə, stopda qal // stopNow() artıq edilib }); } // ---------- Open track page ---------- function openPage(){ if (current?.pageUrl) { try{ window.top.location.href = current.pageUrl; } catch(_){ location.href=current.pageUrl; } } } gp.info?.addEventListener('click', openPage); gp.cover?.addEventListener('click', openPage); // PLAY üçün helper: lazımdırsa pendingSrc-ni qoş function ensureSrcBeforePlay(){ if (pendingSrc){ attachSrc(pendingSrc); pendingSrc = null; } } // ---------- Controls ---------- gp.play?.addEventListener('click', ()=>{ if (!current) return; if (audio.paused) { ensureSrcBeforePlay(); audio.play().then(()=>{ setPlayingUI(true); broadcastState('playing'); }) .catch(()=>{ setPlayingUI(false); broadcastState('paused'); }); } else { stopNow(); } }); gp.next?.addEventListener('click', playNext); gp.prev?.addEventListener('click', playPrev); gp.loopBtn?.addEventListener('click', ()=> setLoop(!isLoop)); gp.random?.addEventListener('click', ()=> setRandom(!isRandom)); // ---------- Seek ---------- const seek = clientX => { const rect = gp.bar.getBoundingClientRect(); const p = Math.min(Math.max((clientX - rect.left)/rect.width, 0), 1); if (!isNaN(audio.duration)) { audio.currentTime = p * audio.duration; throttleBroadcast(); } }; gp.bar?.addEventListener('click', e=>seek(e.clientX)); gp.bar?.addEventListener('mousedown', e=>{ const move = ev=>seek(ev.clientX); const up = ()=>{ document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', up); }; document.addEventListener('mousemove', move); document.addEventListener('mouseup', up); }); // ---------- Time/progress ---------- function syncTime(){ const cur = audio.currentTime||0, dur = audio.duration||0; if (gp.time) gp.time.textContent = fmt(cur) + ' / ' + (isNaN(dur)?'00:00':fmt(dur)); if (gp.progress) gp.progress.style.width = (dur? (cur/dur*100):0).toFixed(2)+'%'; } audio.addEventListener('timeupdate', ()=>{ syncTime(); throttleBroadcast(); }); audio.addEventListener('loadedmetadata', ()=>{ syncTime(); throttleBroadcast(); }); audio.addEventListener('play', ()=>{ setPlayingUI(true); broadcastState('playing'); }); audio.addEventListener('pause', ()=>{ setPlayingUI(false); broadcastState('paused'); }); audio.addEventListener('ended', ()=>{ setPlayingUI(false); broadcastState('ended'); if (!audio.loop) playNext(); }); audio.addEventListener('error', ()=>{ setPlayingUI(false); broadcastState('paused'); if (!audio.loop) playNext(); }); // ---------- Volume/Mute persist ---------- try { const savedVol = localStorage.getItem('gpVolume'); if (savedVol != null) audio.volume = Math.max(0, Math.min(1, parseFloat(savedVol))); if (gp.volume) gp.volume.value = String(audio.volume || 0.9); } catch(_){} function reflectMuteUI(){ const muted = audio.muted || audio.volume === 0; gp.mute?.classList.toggle('active', muted); const x = document.getElementById('gpMuteX'); if (x && x.style) x.style.display = muted ? 'block' : 'none'; gp.mute?.setAttribute('aria-label', muted ? 'Səssiz (açıq)' : 'Səssiz (bağlı)'); } gp.volume?.addEventListener('input', ()=>{ const v = parseFloat(gp.volume.value); if (!isNaN(v)) { audio.volume = Math.max(0, Math.min(1, v)); try { localStorage.setItem('gpVolume', String(audio.volume)); } catch(_){} reflectMuteUI(); throttleBroadcast(); } }); gp.mute?.addEventListener('click', ()=>{ if (audio.muted || audio.volume === 0) { const back = parseFloat(localStorage.getItem('gpVolume') || '0.7') || 0.7; audio.muted = false; audio.volume = back; if (gp.volume) gp.volume.value = String(back); } else { audio.muted = true; } try { localStorage.setItem('gpVolume', String(audio.volume)); } catch(_){} reflectMuteUI(); throttleBroadcast(); }); audio.addEventListener('volumechange', reflectMuteUI); reflectMuteUI(); // ---------- Playback rate persist ---------- const rates = [1, 1.25, 1.5, 2]; let rateIdx = 0; try { const savedRate = parseFloat(localStorage.getItem('gpRate') || '1'); const ix = rates.indexOf(savedRate); if (ix >= 0) rateIdx = ix; audio.playbackRate = rates[rateIdx]; } catch(_){} function renderRate(){ if (gp.rateTxt) gp.rateTxt.textContent = rates[rateIdx] + '×'; } renderRate(); gp.rateBtn?.addEventListener('click', ()=>{ rateIdx = (rateIdx + 1) % rates.length; audio.playbackRate = rates[rateIdx]; try { localStorage.setItem('gpRate', String(rates[rateIdx])); } catch(_){} renderRate(); }); // ---------- Keyboard ---------- document.addEventListener('keydown', e=>{ if (['INPUT','TEXTAREA'].includes((e.target||{}).tagName)) return; if (e.code==='Space'){ e.preventDefault(); gp.play?.click(); } if (e.key==='ArrowRight'){ e.preventDefault(); playNext(); } if (e.key==='ArrowLeft'){ e.preventDefault(); playPrev(); } if (e.key?.toLowerCase()==='l'){ setLoop(!isLoop); } if (e.key?.toLowerCase()==='r'){ setRandom(!isRandom); } }); // ---------- postMessage API ---------- window.addEventListener('message', ev=>{ const d = ev.data||{}; if (!d || typeof d !== 'object') return; if (d.type==='PLAY_TRACK' && d.payload) { loadAndPlay(d.payload,true); return; } if (d.type==='NEXT') { playNext(); return; } if (d.type==='PREV') { playPrev(); return; } if (d.type==='QUEUE_ADD' && d.payload){ queueAdd(d.payload); return; } if (d.type==='PAUSE' || d.type==='STOP') { stopNow(); return; } if (d.type==='TOGGLE') { if (audio.paused) { ensureSrcBeforePlay(); audio.play().then(()=>{ setPlayingUI(true); broadcastState('playing'); }) .catch(()=>{ setPlayingUI(false); broadcastState('paused'); }); } else { stopNow(); } return; } if (d.type==='SEEK_REL') { const sec = Number(d.payload?.seconds) || 0; const dur = isFinite(audio.duration) ? audio.duration : Infinity; const cur = isFinite(audio.currentTime) ? audio.currentTime : 0; audio.currentTime = Math.max(0, Math.min(dur, cur + sec)); syncTime(); throttleBroadcast(); return; } }); // ---------- Media Session ---------- function applyMediaSession(meta){ if (!('mediaSession' in navigator) || !meta) return; try{ navigator.mediaSession.metadata = new MediaMetadata({ title: decodeHTML(meta.title || ''), artist: decodeHTML(meta.artist || ''), artwork: meta.cover ? [{ src: meta.cover, sizes: '512x512', type: 'image/png' }] : [] }); navigator.mediaSession.setActionHandler('play', ()=> { ensureSrcBeforePlay(); audio.play(); }); navigator.mediaSession.setActionHandler('pause', ()=> stopNow()); navigator.mediaSession.setActionHandler('previoustrack', playPrev); navigator.mediaSession.setActionHandler('nexttrack', playNext); }catch(_){} } // ---------- Restore last track (NO autoplay) ---------- try{ const saved = localStorage.getItem('lastTrackMeta'); if (saved){ const meta = JSON.parse(saved); if (meta && (meta.src||meta.stream||meta.audioUrl)) { loadAndPlay(meta,false); } else { broadcastState('paused'); } } else { broadcastState('paused'); } }catch(_){ broadcastState('paused'); } })();