v3.0 8.514 Satir JS 6 Backend Dosya 4 AI Sentezi Fix Uygulandı

Muzibu Player Derinlemesine Analiz Raporu

HLS Sistemi, Adaptive Bitrate, Soft Mode, Crossfade, Canlı Log Analizi, 4 AI Sentez Raporu, Uygulanan Fix'ler ve Tam Mimari Analiz

22 Subat 2026 main branch 26 Sorun Tespit Edildi v3: 4 AI Sentezi + Fix Raporu

Basit Anlatim (Herkes Icin)

Player Nedir?

Muzibu'nun muzik calar sistemi. Spotify veya Apple Music'teki calar gibi dusunun. Sarki secersiniz, calar, sonraki sarkiya gecer, ses ayarlarsiniz.

HLS Nedir?

HLS (HTTP Live Streaming) = Sarkiyi kucuk parcalara bolup gonderme yontemi. Netflix videolari nasil parca parca yukleniyorsa, sarkilar da oyle. Bant genisliginiz duserse kalite otomatik duser, yukselirse kalite artar. Neden onemli? Hem korsan indirmeyi zorlastirir, hem de internet hizina gore en iyi deneyimi sunar.

Adaptive Bitrate Nedir?

Interneti hizli olan kisiye yuksek kaliteli ses, yavas olan kisiye dusuk kaliteli ses gonderme. Otomatik. 4 seviye var: Ultra dusuk (32k), Dusuk (64k), Orta (128k), Yuksek (~250k). Neden onemli? Mobil verideyken az veri harcar, WiFi'deyken en iyi kaliteyi verir.

Soft Mode Nedir?

Bazi kullanicilara (kurumsal, cok kullanicili hesaplar) dusuk kaliteli ses sunma modu. Sunucu yukunu ve bant genisligi maliyetini azaltir. Neden onemli? 50+ kullanicili kurumsal hesaplarda sunucu maliyetini %60-70 dusurebilir.

Bulunan Sorunlar

Toplamda 26 sorun tespit edildi. Bunlardan 5'i kritik (acil duzeltilmeli), 9'u orta seviye, 12'si dusuk seviye iyilestirme. Kritik sorunlar: sifreleme dosya adi cakismasi, segment suresi tutarsizligi ve kalite filtresi hatasi.

Genel Mimari

Player Dosya Yapisi

public/themes/muzibu/js/player/
├── core/
│   ├── player-core.js        # Ana Alpine.js bileseni (8.514 satir)
│   └── safe-storage.js        # localStorage guvenli wrapper
├── features/
│   ├── api.js                 # Kimlikli fetch helper (401 handling)
│   ├── auth.js                # Giris/kayit sistemi
│   ├── buffer-monitor.js      # Buffer saglik takibi
│   ├── device-profiler.js     # Cihaz profilleme (RAM, CPU)
│   ├── favorites.js           # Favori sarki/playlist
│   ├── old-device-checker.js  # Eski cihaz tespiti
│   ├── performance-debug.js   # Performans izleme
│   ├── play-helpers.js        # Calma yardimcilari
│   ├── session.js             # Oturum yonetimi
│   ├── spa-router.js          # SPA sayfa gecisleri
│   ├── speed-tester.js        # Ag hiz testi
│   └── spot-player.js         # Kurumsal reklam oynatici
└── lib/
    └── hls.min.js             # HLS.js v1.4.12

Sarki Calma Akisi

Kullanici Tiklar
togglePlayPause()
API Istegi
/songs/{id}/stream
Format Cozumleme
resolveAudioFormat()
URL Sifre Coz
XOR + Base64 decrypt
HLS / MP3?
stream_type kontrolu
Calmaya Basla
HLS.js / Howler.js

Alpine.js State Yapisi (Temel Alanlar)

Kimlik & Oturum

isLoggedIn -- Giris durumu
currentUser -- Kullanici bilgileri
showAuthModal -- Giris modali

Calma Durumu

isPlaying -- Caliyor mu
currentTime / duration -- Zaman
volume / isMuted -- Ses
progressPercent -- Ilerleme

HLS Durumu

isHlsStream -- HLS aktif mi
hlsCurrentLevel -- Kalite (0-3)
isSlowConnection -- Yavas baglanti
currentStreamType -- "hls" / "mp3"

HLS Sistemi

Frontend -- HLS.js Entegrasyonu

HLS.js Konfigurasyonu (Satir 462-546)
HLS_SHARED_CONFIG = {
  enableWorker: true,              // Web Worker ile ayri thread
  lowLatencyMode: false,           // VOD, canli degil
  autoStartLoad: false,            // Manuel baslatma (ABR lock icin KRiTiK)
  startLevel: 3,                   // Yuksek kaliteden basla
  abrEwmaDefaultEstimate: 250000,  // 250kbps baslangic tahmini
  abrBandWidthUpFactor: 0.5,       // Muhafazakar yukseltme (0.7->0.5)
  abrBandWidthFactor: 0.8,         // Muhafazakar dusurme (0.95->0.8)
  maxBufferLength: 12,             // 12sn buffer (GC dostu)

  keyLoadPolicy: {
    default: {
      maxTimeToFirstByteMs: 10000,   // Key yukleme timeout: 10sn
      maxLoadTimeMs: 20000,          // Key toplam timeout: 20sn
      timeoutRetry: { maxNumRetry: 3, retryDelayMs: 1000 }
    }
  }
}
Key Pre-Cache Sistemi (Satir 352-454) -- Race Condition Cozumu

Problem: HLS.js v1.4.12'de key-loader race condition -- ayni key URI icin birden fazla fragment yuklenmesi keyUriToKeyInfo map'ini eziyor.

Cozum: 3 katmanli key onbellekleme sistemi:

1. Key Normalize
URL parametrelerini alfabetik sirala, cache buster kaldir -> tutarli cache key
2. Pre-fetch
Calmadan ONCE key'i fetch() ile indir -> _hlsKeyCache[]'e kaydet
3. Custom Loader
CachingKeyLoader -- HLS.js XHR'i intercept et, cache'ten senkron dondur
HLS Instance Pool (Satir 548-678)

Pool Yonetimi

  • - 2 adet HLS.js instance havuzu
  • - acquire() -- Havuzdan al
  • - release() -- Havuza geri ver
  • - Stale instance temizleme
  • - Overflow: yeni instance -> hard limit

Cleanup Sirasi

  1. 1. hls.stopLoad()
  2. 2. hls.detachMedia()
  3. 3. hls.removeAllListeners()
  4. 4. hls.destroy()
  5. 5. audio.load() -- MediaSource flush
  6. 6. DOM'dan kaldir (pool harici)
MP3 Fallback Mekanizmasi (Satir 6113-6147)

Tetikleyiciler: HLS init hatasi, Fatal error, bufferAppendError, 60sn timeout

triggerMp3Fallback(reason):
  1. HLS taint + release (pool'a geri ver)
  2. Blob URL cleanup
  3. safeAudioCleanup() -- Event handler temizleme
  4. fallback_url varsa -> playWithHowler()
  5. Toast: "HLS basarisiz, MP3 ile caliniyor..."

Backend -- HLS Donusturme & Sunma

ConvertToHLSJob -- Donusturme Islemi

FFmpeg Pipeline

ffmpeg -i input.mp3 \
  -c:a aac -b:a {bitrate}k \
  -af "loudnorm + stereotools + eq + lowpass" \
  -hls_key_info_file enc.keyinfo \
  -hls_time 6 -hls_list_size 0 \
  -hls_segment_filename "segment-%03d.ts" \
  playlist.m3u8

Kalite Seviyeleri

SeviyeBitrateKanalSample RateSegment
ultralow32 kbpsMono22.05 kHz4 sn
low64 kbpsMono22.05 kHz4 sn
mid128 kbpsStereo44.1 kHz4 sn
high~180-280 kbpsStereo44.1 kHz6 sn
AES-128 Sifreleme Akisi
Key Olustur
random_bytes(16)
IV Olustur
bin2hex(random_bytes(16))
Keyinfo Dosyasi
URI + key path + IV
FFmpeg Sifrele
-hls_key_info_file
Key Endpoint: GET /hls-key/muzibu/songs/{id}?token=...&sig=...&expires=...
Key Dosyasi: storage/tenant{id}/app/public/muzibu/hls/{songId}/enc.bin
Imza: HMAC-SHA256 ile dogrulanir, suresi dolmussa 401 doner
API Endpoint'leri
EndpointYetkiAciklama
/api/muzibu/songs/{id}/streamAuthSifreli HLS/MP3 URL dondurur
/hls/muzibu/songs/{id}/master.m3u8SignedMaster playlist (variant listesi)
/hls/muzibu/songs/{id}/segment-*.tsPublicAES-128 sifreli segment (auth yok)
/hls-key/muzibu/songs/{id}Signed+Rate16-byte AES-128 key (60req/dk)
/audio/songs/{id}/{exp}/{sig}SignedCDN MP3 URL (path-based)
/songs/{id}/track-startSanctumDinleme baslangici (play_id doner)
/songs/{id}/track-hitSanctum30sn milestone (play_count++)
/songs/{id}/track-endSanctumBitis/atlama (sendBeacon)

Adaptive Bitrate (ABR) Sistemi

ABR Stratejisi

Baslangic Seviyesi
startLevel: 3 -- Yuksek kaliteden baslar, gerekirse dusurur
Bant Genisligi Tahmini
abrEwmaDefaultEstimate: 250kbps -- EWMA algoritmasi ile olcum
Yukseltme Esigi
abrBandWidthUpFactor: 0.5 -- 2x bant genisligi gerekli (muhafazakar)
Dusurme Esigi
abrBandWidthFactor: 0.8 -- %80 altina duserse kalite indirilir

Startup Lock Mekanizmasi

  1. 1 loadSource() oncesi -> _abrStartupLocked = true
  2. 2 MANIFEST_PARSED -> currentLevel = startLevel (sabit)
  3. 3 FRAG_BUFFERED -> unlockABR() -> currentLevel = -1 (oto)
  4. 4 5sn fallback timeout (FRAG_BUFFERED gec gelirse)
Neden? Ilk segment'te ABR yanlis dusuk seviye secmesin diye. Yuksek kaliteden baslar, ilk parca yuklendikten sonra ABR devralir.

Cihaza Gore Adaptasyon

- Dusuk RAM / CPU: startLevel=0, buffer=10MB
- saveData modu: Kalite otomatik dusurulur
- slow-2g baglanti: Ultra dusuk kaliteye sabitlenir

Soft Mode & Format Sistemi

Format Cozumleme Zinciri (D4)

1
Admin Tercihi
user.audio_preference -- Admin panelden atanan
↓ auto ise
2
Kurumsal Esik
50+ kullanicili hesaplar -> MP3 zorlanir
↓ esik altindaysa
3
Sistem Varsayilani
MUZIBU_DEFAULT_AUDIO_FORMAT=auto

Soft Player Modu (D8)

Ne yapar? Master playlist'ten yuksek kalite variant'lari cikarir.

// SongStreamController::serveHls()
if (soft=1) {
  allowed = ['ultralow', 'low']  // config'den
  // high ve mid kaldirilir
  master.m3u8 -> sadece ultralow + low
}
Sorun: Regex filtresi hatali calisiyor (Bkz: Sorun #7)

URL Sifreleme (Frontend)

Backend sifreli URL dondurur: response._ + response.__

Frontend XOR ile cozer -> stream_url, fallback_url, stream_type

Crossfade Sistemi (E Grubu)

DURUM: DEVRE DISI

Kod hazir ancak kapali. HLS keyLoadError sorunu cozuldu, artik acilabilir.

Implementasyon (Satir 2465-2650)

  1. 1. Durum kontrol -- pause/stop yapildiysa baslatma
  2. 2. Cache check -- Sonraki sarki URL'de varsa instant crossfade
  3. 3. Stream fetch -- Sonraki sarki bilgisi al
  4. 4. Format belirle -- HLS mi MP3 mi?
  5. 5. Paralel calma -- currentAudio fade-out, nextAudio fade-in

Dual Audio Yonetimi

hlsAudio -- Aktif calan element
hlsAudioNext -- Preload / crossfade element
Crossfade ABR: 3sn timeout (main 5sn)
Risk: Dual audio ayni anda buffer -> bant genisligi yarilanir

Queue & Playlist Yonetimi

nextTrack() Akisi

  1. 1. _nextTrackInProgress eszamanlilik kilidi
  2. 2. 10sn timeout (kilit takilirsa otomatik serbest)
  3. 3. 300ms minimum interval (cift tetikleme onleme)
  4. 4. fromNaturalEnd: true -> gapless gecis
  5. 5. _safePlayFromQueue(): max 3 deneme + token yenileme
  6. 6. Queue bittiyse -> _refillQueue()

Queue Yenileme Zinciri

Adim 1 Tur ile doldur (_fetchUniqueGenreSongs)
Adim 2 Populer sarkilar (/songs/popular)
Adim 3 Karistir (Fisher-Yates) + bastan cal
Adim 4 Acil durum: tur 1 ile doldur
Tekrarlama filtresi: Song ID'leri takip edilir, ayni sarki atlanir

Guvenlik & Sifreleme

Imza Dogrulama

Algoritma: HMAC-SHA256
Base: "{path}|{user_id}|{expires}"
Key: config('app.key')
Dogrulama: sig === expected_sig && now < expires

Playlist ve key endpoint'lerinde zorunlu. Segment'ler AES-128 sifreli oldugu icin imzasiz sunulur (CDN uyumlu).

Guvenlik Katmanlari

AES-128 segment sifreleme
HMAC-SHA256 URL imzalama
XOR + Base64 URL gizleme (frontend)
File traversal korumasi (regex whitelist)
Rate limiting: 60req/dk (sadece key endpoint)
Token = user_id (tahmin edilebilir) -- Bkz: Sorun #22

Canli Log Analizi -- keyLoadError Kok Neden v2 YENi

Basit Anlatim (Herkes Icin)

Muzik calarken her sarkida "sifre cozme hatasi" olusuyordu. Sarkinin sifresini cozmek icin gereken "anahtar"in (key) adresi yanlis yazilmis.

Player dogru adrese gidip anahtari aliyor (/hls-key/... endpoint'i). Ancak playlist dosyasi (sarkinin "tarifi") yanlis bir adrese yonlendiriyor: /storage/... klasorune.

Storage klasoru dogrudan erisime kapali (403 Forbidden). Dolayisiyla HLS.js key dosyasini alamiyor, sifre cozulemiyor, sarki calinmiyor.

Sonuc olarak HLS ile calma basarisiz oluyor ve MP3 yedek modu devreye giriyor. Kullanici sarkiyi dinleyebiliyor ama dusuk kalitede ve HLS'in avantajlari (adaptive bitrate, sifreleme) kullanilamiyor.

Teknik Analiz (Detayli)

Hata Akisi Diyagrami (Adim Adim)

Adim 1 prefetchHlsKey() basarili
/hls-key/muzibu/songs/{id} -> 16 bytes key indirildi -> cache'e yazildi
Adim 2 HLS.js master.m3u8 yukler
4 variant (ultralow/low/mid/high) -> MANIFEST_PARSED basarili
Adim 3 HLS.js playlist.m3u8 yukler
Playlist iceriginde EXT-X-KEY satirini gorur -> URI alanini okur
Adim 4 playlist.m3u8 icindeki URI YANLIS
#EXT-X-KEY:METHOD=AES-128,
URI="https://mztest.muzibu.com/storage/tenant1001/muzibu/hls/{id}/enc.bin",
IV=0xac37483e0d64e537ae63f308d3d89c0a
Adim 5 Storage URL -> 403 Forbidden
/storage/ yolu dogrudan erisime kapali. Nginx/Apache tarafindan engelleniyor.
Adim 6 CachingKeyLoader: Cache MISS
Prefetch cache key: /hls-key/muzibu/songs/{id}
Playlist'teki URI: /storage/tenant1001/muzibu/hls/{id}/enc.bin
URL'ler eslesmediginiz icin -> cache MISS -> XHR ile storage'a gider -> 403
Adim 7-8 keyLoadError -> retry -> fatal -> sonsuz dongu
non-fatal keyLoadError -> retry -> yine 403 -> fatal
Recovery loadSource -> ayni playlist -> ayni yanlis URI -> tekrar ayni hata
Adim 9 MP3 fallback ile kurtarma
HLS basarisiz -> triggerMp3Fallback('keyLoadError') -> Howler.js ile MP3 calma

Kanit Loglari (Gercek Konsol Ciktisi)

🔑 Key pre-fetched OK (16 bytes)
🔑 Key loaded via XHR (391ms, 16 bytes)
⚠️ HLS ERROR: {"details":"keyLoadError","fatal":false,"response":null}
🔑 Non-fatal keyLoadError #1 | response:null | errMsg:after key load, decryptdata unset or changed
⚠️ HLS ERROR: {"details":"keyLoadError","fatal":true,"response":null}
🔴 HLS FATAL ERROR: {song_id: 34455, errorDetails: "keyLoadError"}
🔄 FATAL keyLoadError → loadSource recovery (hard lock)
Dikkat: response:null -- Bu, HLS.js'in key yuklerken hic bir HTTP yaniti alamadigini (veya 403 aldiktan sonra key'i eslestiremedigi icin "decryptdata unset or changed" hatasini) gosteriyor.

Etkilenen Sarkilar (5/5 = %100 Basarisizlik Orani)

Song IDSarki AdiHLS SonucuRebufferKurtarma
34455A Friend Like YouFAILREBUF:3MP3 Fallback
34456A Great DayFAILREBUF:3MP3 Fallback
34457After HoursFAILREBUF:3MP3 Fallback
34458AfterimageFAILREBUF:1MP3 Fallback
34459All AgainFAILREBUF:3MP3 Fallback

Kok Neden: enc.keyinfo Dosyasi

FFmpeg -hls_key_info_file parametresi ile enc.keyinfo dosyasini okur ve icindeki URI'yi playlist.m3u8'e yazar. Bu dosyanin ici:

# enc.keyinfo icerigi (3 satir):
https://mztest.muzibu.com/storage/tenant1001/muzibu/hls/34455/enc.bin  <-- YANLIS URI (Satir 1)
/var/.../enc.bin                                                     <-- Key dosyasinin sunucu yolu (Satir 2)
ac37483e0d64e537ae63f308d3d89c0a                                    <-- IV degeri (Satir 3)
Satir 1 (URI): FFmpeg bunu alip playlist.m3u8'in EXT-X-KEY satirina yaziyor. Storage URL oldugu icin 403 aliyor.
Olmasi gereken: https://mztest.muzibu.com/hls-key/muzibu/songs/34455?token=...&sig=...&expires=...
Bu dosyayi ConvertToHLSJob ve HLSService olusturuyor. Her ikisinde de URI olarak storage yolunu kullaniyor.

Cozum Stratejisi (2 Yol)

Yol A Backend Fix (serveHls'de Key URI Replace)

serveHls() fonksiyonunda playlist icerigi donerken key URI'yi dinamik olarak signed endpoint'e replace eder.

// SongStreamController::serveHls()
$content = file_get_contents($playlistPath);
$content = str_replace(
    'https://.../storage/.../enc.bin',
    route('hls-key', [...]) + signed params
);
return response($content);
+ Mevcut dosyalar degismez, aninda cozum
- Her playlist isteginde string replace
Yol B Encode Fix (enc.keyinfo'da Dogru URI)

ConvertToHLSJob ve HLSService'de enc.keyinfo olusturulurken /hls-key/ endpoint URI'si yazilir.

// ConvertToHLSJob / HLSService
$keyUri = url("/hls-key/muzibu/songs/{$songId}");
file_put_contents($keyInfoPath,
    $keyUri . "\n" .
    $keyFilePath . "\n" .
    $iv
);
+ Playlist dosyalari dogru olur, runtime fix gerekmez
- ~30K sarki re-encode gerekli (veya sed ile fix)
Onerilen: Yol A + Yol B Birlikte
Yol A ile mevcut tum sarkilar aninda duzeltilir (runtime replace). Yol B ile yeni encode'lar dogru URI ile olusturulur. Zamanla Yol A'ya ihtiyac kalmaz.

Debug Panel Bilgileri

Bellek

Stabil: ~28-31MB
Peak: 59MB
GC sonrasi: 59 -> 29MB (normal)

Jank & Performans

Jank: 1 (51ms) -- kabul edilebilir
GC: Normal calisiyor

HLS Pool & Preload

Pool: 1 idle / 1 active
Preload: Calisiyor (hlsAudioNext hazir)

Ikincil Sorunlar (Log'dan Tespit Edilen)

Thumbnail 403
7 adet webp dosyasi erisime kapali. Storage URL uzerinden sunuluyor, tenant symlink veya Nginx config kontrol edilmeli.
PWA Icon 404
/pwa-icon/192.png bulunamiyor. PWA manifest'te tanimli ama dosya mevcut degil. Mobil "ana ekrana ekle" deneyimini bozuyor.
Reklam Engelleyici Uyarisi: Tespit suresinde aktif reklam engelleyici bulundu. Bazi stream URL'leri (ozellikle /stream, /track iceren) bloklanabilir. Kullanici tarafli sorun ancak log'da gorunuyor.

4 AI Sentez Raporu — Çoklu Analiz Karşılaştırması v3 YENİ

Basit Anlatım

Aynı hatayı 4 farklı yapay zekaya analiz ettirdik. Her biri farklı açılardan baktı ve farklı sorunlar buldu. Hepsinin bulgularını birleştirerek çok katmanlı bir kök neden analizi oluşturduk. Tek bir AI'ın bulamayacağı derinlikte bir çözüm ortaya çıktı.

AI Analiz Karşılaştırması

AI Odak Noktası Bulunan Kök Neden Önerilen Çözüm Doğruluk
AI #1 Prefetch + KEY_LOADING race Prefetch ile fragment loading arasında race condition Prefetch'i devre dışı bırak Kısmi — Semptom, neden değil
AI #2 CachingKeyLoader implementasyonu Cache-serve kodu eksik — her zaman super.load() çağrılıyor Cache hit durumunda senkron callback Doğru — İkincil neden
AI #3 keyUriToKeyInfo map + key URI replace serveHls() key URI replace sırasında ?v= parametresi siliniyor → map çakışması Variant parametresini koru Kısmi — Tasarımla uyumsuz (aynı key URI bilinçli)
AI #4 Alpine.js reactive proxy cascade self.hls.currentLevel = X → Alpine proxy 4x setter cascade → double loadFragment HLS instance'ını proxy dışında tut Doğru — Üçüncül neden

Çok Katmanlı Kök Neden Analizi

F1 — BİRİNCİL enc.keyinfo'da Storage URL (403)

ConvertToHLSJob ve HLSService, enc.keyinfo dosyasında key URI olarak /storage/tenant.../enc.bin yazıyor. Bu URL doğrudan erişime kapalı (403 Forbidden). Playlist.m3u8'e bu yanlış URI gömülüyor.

Dosyalar: ConvertToHLSJob.php (satır 96), HLSService.php (satır 232)
F2 — İKİNCİL CachingKeyLoader Cache-Serve Eksik

CachingKeyLoader cache'e key yazıyor ama asla cache'den serve etmiyor. super.load() HER ZAMAN çağrılıyor → 300-400ms async XHR bekleme → fragment referansı değişebilir → decryptdata race condition.

Dosya: player-core.js (satır 424-454)
F3 — ÜÇÜNCÜL Alpine Proxy Setter Cascade

self.hls.currentLevel = safeLvl satırı Alpine.js reactive proxy üzerinden geçiyor → setter 4 kez tetikleniyor → HLS.js double loadFragment → aynı segment için paralel yükleme.

Dosya: player-core.js (satır 5196)

Uygulanan Fix'ler — 6 Adımlı Çözüm v3 YENİ

Basit Anlatım

6 farklı düzeltme yapıldı. Bunların 3'ü doğrudan keyLoadError sorununu çözüyor, 2'si gelecekte aynı sorunun tekrar oluşmasını engelliyor, 1'i de performans iyileştirmesi yapıyor.

1

CachingKeyLoader Senkron Cache-Serve

player-core.js — satır 424-454
TAMAMLANDI
Cache'de key varsa callbacks.onSuccess() direkt çağrılıyor, super.load() atlanıyor. Async XHR bekleme süresi 0ms'e düşürüldü.
if (cachedKey && cachedKey.byteLength === 16) {
    // Cache hit → senkron callback (0ms)
    callbacks.onSuccess(fakeResponse, fakeStats, context, null);
    return; // XHR atla
}
2

ConvertToHLSJob — enc.keyinfo URI Düzeltme

ConvertToHLSJob.php — satır 96
TAMAMLANDI
Storage URL yerine /hls-key/muzibu/songs/{id} endpoint'i yazılıyor. Yeni encode edilen şarkılar doğru key URI ile oluşturuluyor.
// ESKİ: url('storage/tenant.../enc.bin') → 403!
// YENİ:
$keyUri = "https://{$domain}/hls-key/muzibu/songs/{$songId}";
3

HLSService — createKeyInfoFile URI Düzeltme

HLSService.php — satır 230-232
TAMAMLANDI
Eski /stream/key/{id} formatı yerine /hls-key/muzibu/songs/{id} endpoint'i yazılıyor.
4

Alpine Proxy Bypass — _rawHls Referansı

player-core.js — MANIFEST_PARSED + unlockABR
TAMAMLANDI
self._rawHls.currentLevel = safeLvl kullanılarak Alpine reactive proxy bypass ediliyor. 4x setter cascade önleniyor.
// ESKİ: self.hls.currentLevel = safeLvl (Alpine proxy → 4x cascade)
// YENİ: self._rawHls.currentLevel = safeLvl (direkt HLS.js setter)
5

Mevcut 66 Şarkının enc.keyinfo Toplu Güncelleme

storage/tenant1001/app/public/muzibu/hls/*/enc.keyinfo
TAMAMLANDI
203 dosya (66 ana + 137 variant) güncellendi. Tüm enc.keyinfo URI'leri /hls-key/muzibu/songs/{id} formatına çevrildi.
6

serveHls() — /hls-key/ Format Pattern Eklendi

SongStreamController.php — key URI replace
TAMAMLANDI
serveHls() artık 3 farklı key URI formatını yakalıyor: /storage/, /stream/key/, /hls-key/ — hepsini signed endpoint'e replace ediyor.

TODO Listesi v3 YENİ

Tamamlanan İşler

CachingKeyLoader senkron cache-serve
ConvertToHLSJob enc.keyinfo URI fix
HLSService createKeyInfoFile URI fix
Alpine proxy bypass (_rawHls)
66 şarkı enc.keyinfo toplu güncelleme (203 dosya)
serveHls() /hls-key/ pattern ekleme

Bekleyen İşler

Segment süresi hizalama: ConvertToHLSJob 6sn → 4sn (HLSService ile uyumlu)
Playlist cache TTL: 1 saat → 5 dakikaya düşür
Crossfade (E Grubu): keyLoadError düzeldi, etkinleştirilebilir
Yavaş bağlantı badge: Player bar WiFi ikonu animasyonlu badge
Production re-encode: ~30K şarkı (IV + 4sn segment + doğru master.m3u8)

ABA Test Senaryosu v3 YENİ

keyLoadError Fix Doğrulama Testi

Görev

HLS keyLoadError fix'inin çalıştığını doğrula. Müzik çalarken şarkılar HLS ile sorunsuz çalmalı, MP3 fallback'e düşmemeli.

Senaryo

  1. 1. https://mztest.muzibu.com adresine git
  2. 2. Giriş yap (test kullanıcısı)
  3. 3. Herhangi bir albüme tıkla
  4. 4. İlk şarkıyı çal, 10 saniye dinle
  5. 5. İleri (next) butonuna bas, 2. şarkıyı dinle
  6. 6. Konsol loglarını kontrol et

Başarı Kriterleri

Konsolda "Key served from CACHE (0ms)" mesajı görülmeli
keyLoadError hatası OLMAMALI
"MP3 fallback" mesajı OLMAMALI
Şarkılar sorunsuz çalmalı (buffer stall yok)
Debug panelde "HLS Aktif: Evet" görülmeli

Performans Optimizasyonlari

OptimizasyonKonumEtki
G1 Lazy HLS.js yuklemeSatir 14-36JS bundle kuculur, sayfa hizlanir
Progress 250ms intervalSatir 6235Ana thread yuku %60 azalir
HLS Instance havuzuSatir 548-678Instance olusturma/yok etme maliyeti sifir
Key pre-cacheSatir 352-454Key yukleme gecikmesi sifir
DOM cache (hlsAudio lookup)Satir 1044-1060DOM sorgulari ~0
Stream LRU cacheSatir 7289-7299Tekrar calma: ag istegi yok
Segment'ler session'sizRoute middlewareParalel 30+ istek -> session kilidi yok
M3U8 disk cache (3600sn)ControllerDosya okuma maliyeti azalir
CDN uyumlu path-based URLSignedUrlServiceCloudflare cache kullanilabilir
Buffer 12sn (GC dostu)HLS configBellek baskisi azalir

Tespit Edilen Sorunlar (26 Adet)

Kritik Sorunlar (5 Adet)

#1 Yuksek Kalite Bitrate Master Playlist'te 0
Dosya: HLSService.php:125
Problem: $targetBitrate degiskeni generateMasterPlaylist() cagrildiginda tanimsiz. calculateTargetBitrate() sonucu dis scope'a tasinmiyor.
Sonuc: Master playlist'teki high variant bandwidth = 0 -> HLS.js ABR yanlis karar verir.
Cozum Onerisi
// calculateTargetBitrate() sonucunu sakla
$targetBitrate = $this->calculateTargetBitrate($originalBitrate);
// ... FFmpeg komutunu olustur ...
$highBitrate = (int) str_replace('k', '', $targetBitrate) * 1000;
$this->generateMasterPlaylist($storagePath, $highBitrate);
#2 Segment Suresi Tutarsizligi (6sn vs 4sn)
Dosya: ConvertToHLSJob.php:138 vs HLSService.php:20
Problem: ConvertToHLSJob: -hls_time 6 -> HLSService: CHUNK_DURATION = 4
Sonuc: Ana HLS 6sn segment, variant'lar 4sn segment -> Master playlist'te tutarsizlik. Seeking sorunlarina yol acabilir.
#7 Soft Mode Playlist Filtre Regex'i Hatali
Dosya: SongStreamController.php:754-777
Problem: Regex sadece playlist.m3u8 satirini kaldiriyor, #EXT-X-STREAM-INF header satirini birakiyor. Kalan header -> HLS.js'de "playlist not found" hatasi.
#8 Encryption Key URI Yanlis Endpoint'e Isaret Ediyor v2 GUNCELLENDI
Dosyalar: ConvertToHLSJob.php, HLSService.php (enc.keyinfo olusturma)
Problem: enc.keyinfo dosyasindaki URI satiri https://mztest.muzibu.com/storage/tenant1001/muzibu/hls/{id}/enc.bin seklinde olusturuluyor. Bu URL storage dizinine isaret ediyor ve dogrudan erisim 403 Forbidden donuyor. Playlist.m3u8 icindeki EXT-X-KEY URI'si de bu yanlis adresi kullaniyor.
Kok Neden: FFmpeg, enc.keyinfo'nun ilk satirindaki URI'yi playlist dosyasina yaziyor. Bu URI /hls-key/ signed endpoint yerine /storage/ yoluna isaret ediyor.
Sonuc: %100 HLS basarisizlik orani. Tum sarkilarda keyLoadError -> MP3 fallback. (Detay: Canli Log Analizi boluumu)
Cozum: Yol A (serveHls'de runtime URI replace) + Yol B (enc.keyinfo'da dogru URI olusturma)
#19 Encryption Key URI Standardizasyonu Yok -- Kok Neden Belirlendi v2 GUNCELLENDI
Problem: 3 farkli dosyada 2 farkli key dosya adi ve yanlis URI endpoint kullaniliyor. Asil sorun dosya adi (enc.key vs enc.bin) degil, enc.keyinfo'daki URI'nin /storage/ yoluna isaret etmesi. Player'in pre-cache ettigi key URL'si (/hls-key/...) ile playlist icindeki URI (/storage/...) eslesmediginden CachingKeyLoader cache MISS yapiyor.
Standardizasyon Gereklilikleri:
• Key dosya adi: Tek standart (enc.bin veya enc.key) belirlenip tum dosyalarda uygulanmali
• Key URI: enc.keyinfo'nun ilk satiri /hls-key/ endpoint'ine isaret etmeli
• CachingKeyLoader: Prefetch URL ile playlist URI'si ayni olmali (cache HIT icin)

Orta Seviye Sorunlar (9 Adet)

#3 addVariantsToExisting() Eksik Key Olusturma
Variant ekleme sirasinda keyinfo dosyasi olusturma tutarliligi belirsiz.
#5 generateMp3128() Path Formati Tutarsiz
sourceMp3: Job'dan mutlak yol, API'den bagil yol geliyor.
#9 Variant Key URI Endpoint Uyumsuzlugu
createVariantKeyInfo() variant adini URI'ye ekliyor ama serveKey() bunu kontrol etmiyor.
#15 MP3 128k CDN URL Kalite Parametresi
SignedUrlService'den ?q=mp3_128 gonderiliyor ama backend'de bu parametreyi alan endpoint belirsiz.
#17 getHlsDir() 3 Ayri Yol Denemesi
Tenant context'te yalnizca Yol 2 calisir, digerleri gereksiz fallback.
#22 Token = user_id (Tahmin Edilebilir)
Imza dogrulama guclu ama token'in user_id olmasi bilgi sizintisina neden olabilir.
#25 Playlist Cache 1 Saat -- Stale Riski
Variant eklendiginde cache invalidate edilmiyor -> eski master.m3u8 sunulabilir.
#26 FFprobe Hata Yonetimi Eksik
shell_exec() NULL donebilir, json_decode basarisiz -> undefined array access.
#10 TTL Max 1 Saat -- Crossfade'de Yetersiz
Uzun sarkilarda veya crossfade sirasinda imza suresi dolabilir. Max 2 saat onerilir.

Dusuk Seviye Sorunlar (12 Adet)

#4 Key URI'de variant parametresi tutarsizligi
#6 MP3 128k dosya adi standardizasyonu eksik
#11 FFmpeg AF parametresi (kontrol edildi, sorun yok)
#12 hls_time tutarsizligi (#2 ile ayni)
#13 Tum segment'lerde tek IV (acceptable)
#14 MP3 128k dosya boyutu log kontrolu zayif
#16 Imza formati eslesiyor (sorun yok)
#18 getMp3Path() Spatie tenant-aware belirsiz
#20 High variant bandwidth hesaplama (zaten EXTINF kullaniliyor)
#21 Crossfade hala kapali (acilabilir)
#23 Segment public erisim (AES sifreli, kabul edilebilir)
#24 File traversal korumasi (zaten iyi)

Dosya Haritasi

BilesenDosya YoluSatir
Ana Playerpublic/themes/muzibu/js/player/core/player-core.js8.514
Stream ControllerModules/Muzibu/App/Http/Controllers/Api/SongStreamController.php~800
HLS Servisiapp/Services/Muzibu/HLSService.php~650
Donusturme JobModules/Muzibu/App/Jobs/ConvertToHLSJob.php~250
Signed URLapp/Services/SignedUrlService.php~180
Variant CommandModules/Muzibu/App/Console/Commands/AddHlsVariantsCommand.php~280
Muzibu ConfigModules/Muzibu/config/config.php~80
API RoutesModules/Muzibu/routes/api.php~100
Player Bladeresources/views/themes/muzibu/components/player.blade.php~500
HLS.js Kutuphanepublic/themes/muzibu/js/player/lib/hls.min.jsv1.4.12

Ozet & Oncelik Sirasi

5
Kritik Sorun
Acil duzeltilmeli
9
Orta Seviye
Yakinda duzeltilmeli
12
Dusuk Seviye
Iyilestirme onerisi

Genel Degerlendirme

Player Core (8.514 satir): Stabil, production-ready. HLS pool, key pre-cache, ABR startup lock gibi ileri seviye optimizasyonlar mevcut.
HLS Guvenlik: AES-128 + HMAC imza + file traversal korumasi. Temel guvenlik saglam.
Tamamlanan Gruplar: A (Queue), B (Favorites), G (HLS lazy), C (Spot), F (Session), D (Format) -- hepsi calisiyor.
keyLoadError Kok Neden (v2): enc.keyinfo'daki URI /storage/ yoluna isaret ediyor. Tum sarkilarda %100 HLS basarisizlik. Cozum: serveHls'de runtime URI replace + enc.keyinfo'da dogru URI.
Backend Tutarsizliklar: enc.key vs enc.bin, segment 6sn vs 4sn, path formatlari -- standardizasyon gerekli.
Crossfade (E Grubu): Kod hazir, kapali. keyLoadError cozuldukten sonra acilabilir.

Duzeltme Oncelik Sirasi

  1. 1 KEY URI FIX: serveHls'de playlist key URI -> /hls-key/ endpoint replace (#8, #19) YENi ONCELIK
  2. 2 enc.keyinfo olusturmada dogru URI (yeni encode'lar icin) (#8, #19)
  3. 3 Segment suresi tutarsizligi (#2)
  4. 4 High bitrate master playlist hatasi (#1)
  5. 5 Soft mode regex duzeltmesi (#7)
  6. 6 Playlist cache invalidation (#25)
  7. 7 FFprobe hata yonetimi (#26)
  8. 8 TTL uzatma -- crossfade hazirligi (#10)
  9. 9 Crossfade'i ac (E Grubu)