📝 Basit Anlatım (Herkes İçin)
🎯 Ne Yapacağız?
Muzibu'da kullanıcılar müzik dinlerken 4 farklı ses kalitesi seçeneği arasından tercih yapabilecek. Bu seçim anında devreye girecek, şarkı kesintiye uğramayacak.
🎚️ Kalite Seviyeleri:
-
🔵
Standard: Hafif, mobil veri tasarrufu için ideal (192 kbps)
-
🟢
Optimized: Dengeli kalite, ses seviyesi normalize (256 kbps + Loudnorm)
-
🟡
EQ Balanced: Optimized + Ekstra bas ve tiz ayarı (EQ)
-
🔴
Ultimate: En yüksek kalite + Stereo genişletme + Tüm filtreler
🚀 Neden Frontend'de?
- Anında değişim: Kullanıcı butona bastığında hemen uygulanır, şarkı yeniden başlamaz
- Disk tasarrufu: Her şarkı için 4 farklı dosya oluşturmaya gerek yok (28K şarkı x 4 = 112K dosya!)
- Eski şarkılar korunur: Zaten işlenmiş 28,208 şarkıya hiç dokunulmaz
- Kullanıcı kontrolü: Herkes kendi zevkine ve internet hızına göre ayarlayabilir
💡 Kullanıcı Ne Yaşar?
- Şarkı çalarken oynatıcıda "Ses Kalitesi" butonu görür
- Tıkladığında 4 seçenek açılır (Standard, Optimized, EQ Balanced, Ultimate)
- Seçtiği anda ses kalitesi değişir (şarkı devam eder, kesinti olmaz)
- Tercihi kaydedilir, sonraki açılışta aynı ayar aktif olur
- Premium aboneler tüm seçeneklere, free kullanıcılar sadece Standard'a erişir
🔧 Teknik Detaylar (Geliştiriciler İçin)
🎵 Web Audio API Kullanımı
Modern tarayıcılarda yerleşik AudioContext
kullanarak gerçek zamanlı ses işleme yapılır. HLS akışı ile entegre çalışır.
// Audio Pipeline Yapısı
Source (HLS.js) → AudioContext → [Filters] → Destination (Speaker)
// Node Chain:
MediaElementSource → GainNode → BiquadFilterNode(s) → StereoPanner → Destination
🎚️ Kalite Presets (JavaScript Object)
const QUALITY_PRESETS = {
standard: {
label: 'Standard',
description: '192 kbps, filtre yok',
bitrate: 192,
filters: {
gain: 1.0, // Hiç dokunma
loudness: false, // Loudness normalize YOK
eq: [], // EQ YOK
stereo: 0, // Stereo genişletme YOK
lowpass: false // Lowpass filter YOK
}
},
optimized: {
label: 'Optimized',
description: '256 kbps + Loudness normalize',
bitrate: 256,
filters: {
gain: 1.2, // +2dB gain (loudness normalize simülasyonu)
loudness: true, // Loudness normalize (Web Audio ile simüle edilir)
eq: [], // EQ YOK
stereo: 0, // Stereo genişletme YOK
lowpass: false // Lowpass filter YOK
}
},
eq_balanced: {
label: 'EQ Balanced',
description: '256 kbps + Loudness + EQ (Bass/Treble)',
bitrate: 256,
filters: {
gain: 1.2,
loudness: true,
eq: [
{ type: 'peaking', frequency: 100, Q: 1, gain: 1 }, // Bass boost +1dB
{ type: 'peaking', frequency: 8000, Q: 1, gain: -2 } // Treble cut -2dB
],
stereo: 0,
lowpass: false
}
},
ultimate: {
label: 'Ultimate',
description: '256 kbps + Tüm filtreler',
bitrate: 256,
filters: {
gain: 1.2,
loudness: true,
eq: [
{ type: 'peaking', frequency: 100, Q: 1, gain: 1 },
{ type: 'peaking', frequency: 8000, Q: 1, gain: -2 }
],
stereo: 0.2, // Stereo genişletme (20% widening)
lowpass: 14000 // 14kHz lowpass filter
}
}
};
🔗 Player Class Entegrasyonu
Mevcut MuzibuPlayer class'ına
Web Audio pipeline eklenecek.
class MuzibuPlayer {
constructor() {
// AudioContext oluştur
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.audioSource = null;
this.gainNode = null;
this.eqNodes = [];
this.stereoPanner = null;
this.lowpassFilter = null;
// Varsayılan kalite
this.currentQuality = localStorage.getItem('muzibu_audio_quality') || 'optimized';
}
setupAudioPipeline(audioElement) {
// Source node (HLS.js'den gelen audio element)
this.audioSource = this.audioContext.createMediaElementSource(audioElement);
// Gain node (loudness için)
this.gainNode = this.audioContext.createGain();
// EQ nodes (bass/treble için)
this.eqNodes = [];
// Stereo panner (stereo widening için)
this.stereoPanner = this.audioContext.createStereoPanner();
// Lowpass filter
this.lowpassFilter = this.audioContext.createBiquadFilter();
this.lowpassFilter.type = 'lowpass';
// Pipeline bağlantısı
this.audioSource
.connect(this.gainNode)
.connect(this.lowpassFilter)
.connect(this.stereoPanner)
.connect(this.audioContext.destination);
// İlk kalite preset'ini uygula
this.applyQualityPreset(this.currentQuality);
}
applyQualityPreset(qualityLevel) {
const preset = QUALITY_PRESETS[qualityLevel];
if (!preset) return;
// Gain ayarla (loudness simülasyonu)
this.gainNode.gain.value = preset.filters.gain;
// EQ filtreleri temizle ve yeniden oluştur
this.eqNodes.forEach(node => node.disconnect());
this.eqNodes = [];
if (preset.filters.eq.length > 0) {
let prevNode = this.gainNode;
preset.filters.eq.forEach(eqConfig => {
const eqNode = this.audioContext.createBiquadFilter();
eqNode.type = eqConfig.type;
eqNode.frequency.value = eqConfig.frequency;
eqNode.Q.value = eqConfig.Q;
eqNode.gain.value = eqConfig.gain;
prevNode.disconnect();
prevNode.connect(eqNode);
this.eqNodes.push(eqNode);
prevNode = eqNode;
});
prevNode.connect(this.lowpassFilter);
}
// Lowpass filter
if (preset.filters.lowpass) {
this.lowpassFilter.frequency.value = preset.filters.lowpass;
} else {
this.lowpassFilter.frequency.value = 20000; // Kapalı (20kHz = insan kulağı limiti)
}
// Stereo panner
// NOT: StereoPanner sadece sol/sağ dengeleme yapar
// Gerçek stereo widening için ChannelSplitter/Merger gerekir (daha karmaşık)
this.stereoPanner.pan.value = preset.filters.stereo;
// Ayarı kaydet
localStorage.setItem('muzibu_audio_quality', qualityLevel);
this.currentQuality = qualityLevel;
console.log('Audio quality changed:', qualityLevel);
}
changeQuality(qualityLevel) {
// Şarkı çalarken kalite değiştir (kesinti olmaz)
this.applyQualityPreset(qualityLevel);
}
}
🎨 Kalite Seçici UI Komponenti
Player bar'da dropdown menü ile kalite seçimi.
<!-- Player Bar'a Eklenecek -->
<div class="audio-quality-selector">
<button class="quality-btn" @click="toggleQualityMenu">
<i class="fas fa-sliders-h"></i>
<span>{{ currentQualityLabel }}</span>
</button>
<div class="quality-menu" x-show="qualityMenuOpen" @click.away="qualityMenuOpen = false">
<div class="quality-option" @click="changeQuality('standard')" :class="{'active': quality === 'standard'}">
<span class="badge bg-blue-600">🔵</span>
<div>
<div class="font-semibold">Standard</div>
<div class="text-xs text-slate-400">192 kbps, hafif</div>
</div>
</div>
<div class="quality-option" @click="changeQuality('optimized')" :class="{'active': quality === 'optimized', 'premium-only': !isPremium}">
<span class="badge bg-green-600">🟢</span>
<div>
<div class="font-semibold">Optimized</div>
<div class="text-xs text-slate-400">256 kbps + Loudnorm</div>
</div>
<span v-if="!isPremium" class="badge bg-yellow-600 text-xs">Premium</span>
</div>
<div class="quality-option" @click="changeQuality('eq_balanced')" :class="{'active': quality === 'eq_balanced', 'premium-only': !isPremium}">
<span class="badge bg-yellow-600">🟡</span>
<div>
<div class="font-semibold">EQ Balanced</div>
<div class="text-xs text-slate-400">Optimized + EQ</div>
</div>
<span v-if="!isPremium" class="badge bg-yellow-600 text-xs">Premium</span>
</div>
<div class="quality-option" @click="changeQuality('ultimate')" :class="{'active': quality === 'ultimate', 'premium-only': !isPremium}">
<span class="badge bg-red-600">🔴</span>
<div>
<div class="font-semibold">Ultimate</div>
<div class="text-xs text-slate-400">En yüksek kalite</div>
</div>
<span v-if="!isPremium" class="badge bg-yellow-600 text-xs">Premium</span>
</div>
</div>
</div>
📁 Dosya Konumları
- JS: public/themes/muzibu/js/player/features/audio-quality.js
- Core: public/themes/muzibu/js/player/core/player-core.js (mevcut dosya güncellenecek)
- UI: resources/views/themes/muzibu/layouts/partials/player.blade.php (kalite seçici ekleme)
- CSS: public/themes/muzibu/css/player-custom.css (kalite menüsü stilleri)
📊 Yapılacaklar (Adım Adım)
1 Hazırlık: Audio Quality Modülü Oluştur
- ✅
audio-quality.jsdosyası oluştur - ✅
QUALITY_PRESETSobject tanımla - ✅
AudioQualityManagerclass yaz - ✅ LocalStorage'dan ayar okuma fonksiyonu
2 Player Core: Web Audio Pipeline Ekle
- ✅
player-core.jsiçinde AudioContext oluştur - ✅ HLS.js audio element'ini AudioContext'e bağla
- ✅ Gain, EQ, Stereo, Lowpass node'larını zincirle
- ✅
applyQualityPreset()metodunu implement et - ✅ Şarkı değiştiğinde pipeline'ı koru (kesinti olmasın)
3 UI: Kalite Seçici Dropdown Ekle
- ✅ Player bar'a "Ses Kalitesi" butonu ekle
- ✅ Dropdown menü komponenti (Alpine.js)
- ✅ 4 kalite seçeneği listele
- ✅ Aktif kaliteyi göster (badge/işaret)
- ✅ Premium kontrolü (free kullanıcılar sadece Standard)
4 CSS: Kalite Menüsü Stilleri
- ✅ Dropdown animasyonları (fade-in/out)
- ✅ Hover efektleri
- ✅ Premium badge stilleri
- ✅ Responsive tasarım (mobil uyumlu)
- ✅ Dark mode uyumlu
5 Test: Tüm Senaryoları Kontrol Et
- ✅ Şarkı çalarken kalite değiştirme (kesinti olmamalı)
- ✅ Şarkı geçişinde ayar korunuyor mu?
- ✅ LocalStorage'a kaydediliyor mu?
- ✅ Sayfa yenilendiğinde ayar yükleniyor mu?
- ✅ Premium kontrolü çalışıyor mu?
- ✅ Tüm tarayıcılarda test (Chrome, Firefox, Safari, Edge)
- ✅ Mobil tarayıcılar (iOS Safari, Android Chrome)
6 Optimizasyon: Performans İyileştirmeleri
- ✅ AudioContext singleton (tek instance)
- ✅ Node'ları yeniden oluştururken disconnect/connect doğru yapılmalı
- ✅ Memory leak kontrolü (şarkı değişiminde node'lar temizlenmeli)
- ✅ CPU kullanımı izleme (console'da performans logları)
✅ Avantajlar
-
✓
Anında geçiş: Şarkı kesintiye uğramadan kalite değişir
-
✓
Disk tasarrufu: Her şarkı için tek dosya yeterli (28K x 1 = 28K dosya)
-
✓
Eski şarkılar korunur: 28,208 şarkıya dokunulmaz
-
✓
Kullanıcı kontrolü: Herkes kendi tercihine göre ayarlar
-
✓
Kolay güncelleme: Preset'leri JavaScript'te değiştirmek çok basit
-
✓
Premium özellik: Free kullanıcılar sadece Standard, premium tüm seçeneklere erişir
⚠️ Dikkat Edilecekler
-
!
Tarayıcı desteği: Eski tarayıcılar Web Audio API desteklemeyebilir (fallback gerekli)
-
!
iOS autoplay: Safari'de AudioContext ilk kullanıcı etkileşiminden sonra başlar
-
!
CPU kullanımı: Çok fazla filtre CPU'yu yorabilir (özellikle mobil)
-
!
Memory leak: Node'lar doğru disconnect edilmezse bellek sızıntısı olur
-
!
HLS.js entegrasyonu: Audio element AudioContext'e bağlanırken timing kritik
-
!
Test: Tüm mobil tarayıcılarda (özellikle iOS Safari) mutlaka test edilmeli
🚫 Alternatif: Backend (FFmpeg) Çözümü (Neden Kullanmıyoruz?)
Backend Yaklaşımı:
- Her şarkı için 4 farklı HLS dosyası oluştur (28K x 4 = 112K dosya)
- Kullanıcı kalite seçtiğinde farklı HLS URL'i ver
- Şarkı yeniden başlar (kesinti olur)
❌ Dezavantajlar:
- 🔴 Disk alanı: 28K şarkı x 4 kalite = ~500GB+ ekstra alan
- 🔴 İşlem süresi: Tüm şarkıları yeniden işlemek günler/haftalar alır
- 🔴 CPU yükü: FFmpeg queue sistemi sürekli çalışır
- 🔴 Kesinti: Kullanıcı kalite değiştirince şarkı baştan başlar
- 🔴 Karmaşıklık: Backend migration, queue, storage yönetimi
✅ Frontend Neden Daha İyi:
Gerçek zamanlı ses işleme tarayıcıda yapıldığı için kullanıcı anında sonuç alır, hiçbir dosya yeniden oluşturulmaz, disk alanı boşa harcanmaz. Modern tarayıcılar Web Audio API ile profesyonel kalitede ses işleme yapabilir.
🚀 Sonraki Adımlar
📅 Uygulama Sırası:
- Onay al: Bu planı kullanıcıya sun, onay bekle
- Modül oluştur:
audio-quality.jsdosyasını yaz - Player entegrasyonu:
player-core.jsgüncellenecek - UI ekle: Kalite seçici dropdown komponenti
- Test: Tüm tarayıcılarda ve mobilde test et
- Deploy: Production'a al
💬 Kullanıcıya Soru:
Bu planı onaylıyor musunuz?
- ✓ Evet → Koda geçiyoruz (audio-quality.js oluşturma)
- ✗ Hayır → Neyi değiştirmek istersiniz?