Planlama Dokumani

Crossfade Kaldirilma Plani

29 Aralik 2025 - Muzibu Player Refactoring

Mevcut Sorun

Crossfade neden sorun cikariyor?

  • bufferAppendError - HLS buffer'a veri eklenemiyor
  • mediaError - MediaSource API hatalari
  • Iki HLS instance ayni anda calisinca browser kaynagi tuketiyor
  • Mobile Safari'de zaten calismiyordu (devre disi)
  • Background tab'da ses kesiliyor
  • Fatal error olunca player tamamen duruyor

GECICI COZUM: Crossfade simdi devre disi!

player-core.js:172 - crossfadeEnabled: false

Buyuk Platformlar Nasil Yapiyor?

Spotify

  • Gapless Playback varsayilan
  • Crossfade opsiyonel (0-12sn)
  • Preload: Sonraki sarki onceden yuklenir
  • Web Audio API + MSE kullanir
Anahtar: Tek audio context, buffer swap

Apple Music

  • Gapless Playback varsayilan
  • Crossfade yok (web'de)
  • Native HLS (Safari optimized)
  • MusicKit JS framework
Anahtar: Native HLS, seek-to-end tekniği

YouTube Music

  • Gapless album icinde
  • Crossfade yok
  • Adaptive streaming (DASH/HLS)
  • Shaka Player (Google)
Anahtar: ended event + instant load

Ortak Ozellikler

  • 1. Gapless playback varsayilan - Crossfade opsiyonel veya yok
  • 2. Preload sistemi - Sonraki sarki onceden yukleniyor (ilk segment)
  • 3. Tek player instance - Iki player ayni anda calismaz
  • 4. ended event'e guven - Sarki bitince hemen sonrakini cal

Onerilen Yeni Mimari

1. Gapless Playback (Varsayilan)

Nasil Calisir:

  1. Sarki calarken sonraki sarkinin URL'ini al
  2. Sonraki sarkinin ilk segmentini preload et
  3. ended event tetiklenince
  4. Mevcut HLS'i destroy et
  5. Preload edilmis sarkiyi hemen cal

Avantajlari:

  • Tek HLS instance - kaynak tasarrufu
  • Buffer hatalari olmaz
  • Mobile'da calisisr
  • Background tab'da calisisr

2. Akilli Preload Sistemi

Mevcut sistem zaten var: preloadNextSong()

Gelistirme onerileri:

  • Preload basari durumunu state'e kaydet
  • Preload basarisizsa tekrar dene (3 deneme)
  • Cache'e alinan URL'i streamUrlCache'de sakla
  • Sarki gecisinde cache'den hemen kullan

3. Opsiyonel Crossfade (Gelecekte)

Simdilik implement ETME! Once gapless duzgun calismali.

Eger gelecekte eklenecekse:

  • Web Audio API kullan (AudioContext + GainNode)
  • Sadece MP3 icin aktif et (HLS'de sorunlu)
  • Kullanici ayarlarindan acilip kapanabilmeli
  • Mobile'da otomatik devre disi

Crossfade Kodunu Temizleme Plani

Adim 1: State Degiskenleri (Silinecek)

- crossfadeEnabled (satir 172)

- crossfadeDuration (satir 173)

- isCrossfading (satir 175)

- crossfadeTimeoutId (satir 176)

- crossfadeNextIndex (satir 177)

- howlNext (satir 179)

- hlsNext (satir 181)

- nextHlsAudioId

Adim 2: Fonksiyonlar (Silinecek)

- startCrossfade() (~satir 1486)

- createNextHowlerPlayer() (~satir 1670)

- createNextHlsPlayer() (~satir 1703)

- completeCrossfade() (~satir 1831)

- fadeAudioElement() (crossfade icin kullanilan)

Adim 3: Event Listener'lar (Duzeltilecek)

- timeupdate: crossfade trigger kodunu kaldir

- ended: crossfade kontrolunu kaldir, direkt onTrackEnded()

- BUFFER_EOS: crossfade kontrolunu kaldir

- pause: crossfade completion kodunu kaldir

Adim 4: HTML Elementler (Temizlenecek)

- hlsAudioNext audio elementi (artik gerekli degil)

- Sadece tek hlsAudio elementi yeterli

Adim 5: Korunacak Kodlar

+ preloadNextSong() - Bu kalmali!

+ streamUrlCache - Bu kalmali!

+ onTrackEnded() - Bu zaten var

+ playNextSong() - Bu zaten var

Yeni Sarki Gecis Akisi (Gapless)

1

Sarki Calmaya Basladiginda

currentTime > 2sn olunca preloadNextSong() cagir

2

Preload Islemi

API'den URL al, streamUrlCache'e kaydet (HLS instance OLUSTURMA!)

3

Sarki Bittiginde (ended event)

onTrackEnded() → playNextSong() → playSongFromQueue()

4

Sonraki Sarkiyi Cal

Cache'de URL varsa kullan, yoksa API'den al. Tek HLS instance ile cal.

Pseudocode:

// Sarki bittiginde (ended event)
onTrackEnded() {
    // Mevcut HLS'i temizle
    if (this.hls) {
        this.hls.destroy();
        this.hls = null;
    }

    // Sonraki sarkiya gec
    const nextIndex = this.getNextSongIndex();
    if (nextIndex >= 0) {
        // playSongFromQueue cache'den URL alacak
        this.playSongFromQueue(nextIndex);
    }
}

// playSongFromQueue zaten cache kontrolu yapiyor:
// const cached = this.getCachedStream(song.song_id);
// if (cached) { data = cached; } else { fetch from API }
                

Uygulama Oncelik Sirasi

1 Crossfade'i devre disi birak (TAMAMLANDI)
2 Test et: Gapless playback (ended event) duzgun calisiyor mu?
3 Preload sistemini guclendir (sadece URL cache, HLS instance degil)
4 Crossfade kodlarini tamamen temizle (refactoring)
5 (Opsiyonel) Web Audio API ile soft crossfade ekle