Frontend Müzik Çalar Detaylı Analizi
~7.9k
Satır (Player Core)
1.1MB
JS Dosyaları
2
UI Modu (Mobile/Desktop)
HLS
Encryption Streaming
Muzibu'nun player sistemi, sayfanın altında sabit duran müzik çalar barıdır. Spotify veya YouTube Music gibi modern platformlardaki player'a benzer şekilde çalışır. Kullanıcı sayfalarda gezerken müzik kesintisiz devam eder ve player her zaman ekranda görünür kalır.
Bu sistem tamamen JavaScript ile çalışır. Sayfa yenilemeden müzik dinlenebilir, şarkı değiştirilebilir, kuyruk yönetilebilir.
Mobilde farklı, masaüstünde farklı görünüm. Mobilde progress ring (halka), masaüstünde linear bar. Her iki modda da kullanımı kolay ve şık.
Her şarkının kendine özel renk paleti var. Player, şarkı değiştikçe gradient renkleri değişir. Progress bar, ring, border - hepsi şarkıya özel renklerle uyumlu.
Müzikler HLS formatında şifrelenmiş. Browser'da görünen URL'ler bile blob URL olarak maskelenmiş. Kullanıcı Network tab'ı açsa bile gerçek müzik URL'ini göremez.
Sayfa değişse bile müzik durmaz. SPA (Single Page Application) router sistemi ile sayfa geçişleri JavaScript ile yapılır, player state korunur.
Infinite queue: Kuyruk bitince backend'den otomatik yeni şarkılar eklenir. Drag & drop ile sıralama. Duplicate kontrolü, queue context (playlist, album, genre) takibi.
Space = Play/Pause, ← → = İleri/Geri, Shift+↑↓ = Volume, K = Toggle Play, L = 10sn İleri, J = 10sn Geri. YouTube benzeri kısayollar.
Core Framework
Audio Libraries
UI Libraries
public/themes/muzibu/js/ (1.1MB) ├── player/ │ ├── core/ │ │ ├── player-core.js (7,883 satır - Ana player mantığı) │ │ └── safe-storage.js (localStorage wrapper) │ └── features/ │ ├── play-helpers.js (1,015 satır - Queue, play functions) │ ├── api.js (API çağrıları) │ ├── session.js (331 satır - Session check) │ ├── spa-router.js (687 satır - SPA navigation) │ └── spot-player.js (564 satır - Corporate spot ads) ├── context-menus/ │ ├── actions/ (8 action handler) │ ├── handlers/ (5 feature handler) │ ├── utils/ │ └── menu-builder.js ├── ai/ │ └── tenant1001-ai-chat.js └── alpine-apps.js (Dashboard, Corporate, Playlist Editor) resources/views/themes/muzibu/ ├── components/ │ ├── player.blade.php (19KB - Player UI component) │ ├── queue-overlay.blade.php (21KB - Queue modal) │ ├── lyrics-overlay.blade.php │ ├── context-menu.blade.php │ └── keyboard-shortcuts-overlay.blade.php └── layouts/ └── app.blade.php (41KB - Main layout + Alpine init)
Pattern: Alpine.store() ile global state management
Alpine.store('player')
State:
currentSong - Şu an çalan şarkıqueue - Sıradaki şarkılar array'iisPlaying - Çalıyor mu booleancurrentTime - Geçen süre (saniye)duration - Toplam süre (saniye)isMuted - Sessiz modisSongLoading - Yükleniyor muplayContext - { type, id, data }Methods:
playSong(songId)togglePlayPause()nextTrack()previousTrack()seekTo(time)addToQueue(songs, next)removeFromQueue(index)reorderQueue(oldIndex, newIndex)playPlaylist(id)playAlbum(id)playRadio(id)Alpine.store('contextMenu')
Sağ tık menüsü için global state. Song, album, playlist için farklı menüler.
Alpine.store('playlistModal')
"Playlist'e Ekle" modal state. Kullanıcının playlist'lerini listeler.
Alpine.store('sidebar')
Sağ sidebar state. Preview info (hover), entity info (click), quick access list.
1. Şarkı Seçimi
playSong(songId) tetiklerGET /api/muzibu/songs/{id} ile şarkı detayları çekilir{ song_id, title, artist, hls_url, cover_url, color_hues: [30, 350, 320] }2. Blob URL Oluşturma
createHlsBlobUrl(originalHlsUrl) fonksiyonu çalışırblob:https://muzibu.com/abc-1233. HLS.js İnit
new Hls() instance oluşturulurhls.loadSource(blobUrl) - m3u8 yüklenirhls.attachMedia(audioElement) - Audio element'e bağlanırMANIFEST_PARSED event'i tetiklenince audio.play()4. Playback Events
audio.ontimeupdate → currentTime güncelleniraudio.onended → nextTrack() tetikleniraudio.onerror → Hata toast gösteriliraudio.oncanplay → Loading spinner gizlenir5. Cleanup
hls.destroy() çağrılırURL.revokeObjectURL(blobUrl) - Blob memory temizleniraudio.pause(); audio.removeAttribute('src'); audio.load()⚠️ Güvenlik Katmanları
Queue State
queue: [] - Sıradaki şarkılar array'i
queueIndex: 0 - Şu an çalan index
playContext: {} - Playlist/Album/Genre context
Örnek:
queue: [
{ song_id: 1, title: "Song 1", ... },
{ song_id: 2, title: "Song 2", ... },
{ song_id: 3, title: "Song 3", ... }
]
queueIndex: 0 // "Song 1" çalıyor
Queue Operations
addToQueue(songs, next)removeFromQueue(index)reorderQueue(old, new)clearQueue()🔁 Infinite Queue
Kuyruk bitince otomatik yeni şarkılar eklenir. Backend'e istek atılır:
POST /api/muzibu/queue/refill
Body: { context: { type: 'playlist', id: 5 }, count: 10 }
🎯 Context Tracking
Queue her zaman bir context'e bağlı: Playlist, Album, Genre, Sector, Radio. Bu sayede "sonraki şarkılar" aynı context'ten gelir.
Queue overlay'de SortableJS ile sürükle-bırak özelliği. Hem mobile hem desktop uyumlu.
Initialization
Sortable.create(queueContainer, {
animation: 200,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
handle: '.queue-drag-handle',
onEnd: function(evt) {
reorderQueue(evt.oldIndex, evt.newIndex);
}
});
CSS Animations
.sortable-drag - Sürüklenen item (havada asılı efekt).sortable-ghost - Bırakılacak yer (dashed border placeholder).sortable-chosen - Seçilen item (highlight)@keyframes queue-item-drop - Bırakıldığında parlama📱 Mobile Player (< 1024px)
🖥️ Desktop Player (>= 1024px)
✨ Ortak Özellikler
@keyframes gradientShift)File: public/themes/muzibu/js/player/features/api.js
GET /api/muzibu/songs/{id}
Şarkı detaylarını çeker
Response: {
song_id, title, slug, artist_title, album_title, album_cover,
genre_title, duration, hls_url, lyrics, is_favorite,
color_hues: [30, 350, 320], // Dinamik renkler
...
}
POST /api/muzibu/songs/{id}/play
Dinleme kaydı oluşturur (song_plays tablosuna insert)
POST /api/muzibu/queue/refill
Infinite queue için yeni şarkılar getirir
GET /api/muzibu/playlists/{id}
Playlist detayı + songs eager load
POST /api/favorites/toggle
Favori ekleme/çıkarma (polymorphic relation)
File: public/themes/muzibu/js/player/features/session.js (331 satır)
Auto Session Check
Her 2 dakikada bir GET /api/auth/check-session çağrılır.
Page Visibility API
Kullanıcı tab'ı gizlediğinde session check durur, tab aktif olunca devam eder. Battery saver mode.
File: public/themes/muzibu/js/player/features/spa-router.js (687 satır)
Nasıl Çalışır?
<a> link'leri intercept edilirevent.preventDefault() ile normal navigation engellenirfetch(url) ile HTML çekilir#main-content alanı değiştirilirhistory.pushState() ile URL güncellenirÖzellikler
popstate event)Exceptions (SPA Bypass)
Playback Controls
Volume & UI
⚠️ Context-aware
Input, textarea içinde iken kısayollar devre dışı kalır. Sadece player focused iken aktif.
File: public/themes/muzibu/js/player/core/safe-storage.js
Saklanan Veriler
muzibu_volume - Son ses seviyesimuzibu_queue - Son kuyruk statemuzibu_current_song - Son çalan şarkımuzibu_play_context - Son context (playlist/album/genre)muzibu_queue_index - Kuyrukta konumSayfa yenilense bile player state korunur. Kullanıcı kaldığı yerden devam eder.
Safe Storage Wrapper
localStorage hatası (quota exceeded, private mode) tetiklerse fallback olarak memory'de tutar. Hata fırlatmaz, graceful degradation.
~11k
Satır JS (Player)
~60KB
Blade Components
1.1MB
Toplam JS
Core Files
Blade Components