🎵
HLS Migrasyon Performans GC Düzeltmesi v2

Donmalar Bitiyor: 10s → 6s

Müzik parçacıklarını küçültüyoruz, tarayıcı nefes alacak

🧠 Önce Hikayeyi Anlayalım

Müzik çalarken sahne arkasında neler oluyor? Şarkı tek bir dev dosya değil, küçük parçalara bölünmüş. Her parça ayrı ayrı indiriliyor. Tarayıcı bu parçaları belleğe alıyor, çalıyor, ardından çöpe atıyor. İşte bu "çöpe atma" işi bazen donmaya neden oluyor.

Şu an normal kalite parçalar 10 saniye. Bu büyük bir lokma. Tarayıcı yutamadığında 958ms donuyor. 6 saniyeye indirirsek daha küçük lokmalar, daha kolay sindirim. ✌️

😰 Şu An Ne Oluyor? (11 Saatlik Oturum Verisi)

958ms
En uzun donma
~1 saniye!
30+
Toplam donma
11 saatte
65MB
Peak bellek
32→65→32→65...
3'lü
Küme donmalar
Art arda 3×500ms+

🧩 Segment Nedir? (Basitçe)

Şarkıyı pizza gibi düşün. Tek büyük pizza yerine dilimlere bölünmüş:

Şarkı "Bohemian Rhapsody" (354 saniye)
❌ ŞU AN: 10 saniyelik dilimler = 36 parça
seg-000
0-10s
seg-001
10-20s
seg-002
20-30s
... 33 tane daha ...
✅ HEDEF: 6 saniyelik dilimler = 59 parça
seg-000
0-6s
seg-001
6-12s
seg-002
12-18s
... 56 tane daha ...
✅ Hızlı başlangıç
İlk ses 6s indirince çıkar, 10s beklemek yok
✅ Hassas kalite geçişi
Yavaş internet → her 6s'de kalite düşürebilir
✅ Daha az GC baskısı
Küçük parça = küçük çöp = kısa donma

🗑️ GC (Garbage Collection) Nedir? Neden Donduruyor?

Tarayıcı her segmenti indirip çalarken bellekte geçici "çöp" oluşuyor. Bu çöpü temizlemek için zaman zaman tüm işi bırakıp temizliğe başlıyor. Bu temizlik süresi = donma.

11 saatlik müzik dinledikten sonra bellek o kadar dağınık hale geliyor ki temizlik 958ms sürüyor. Neredeyse 1 saniye müzik donuyor!

# Bellek döngüsü (her 15 saniyede bir!)
04:39:38 → 46MB → 34MB (-12MB) 🗑️
04:39:52 → 65MB → 34MB (-31MB) 🗑️
04:40:08 → 63MB → 35MB (-28MB) 🗑️
...
# 11 saat sonra...
15:37:24 → DONMA: 902ms 💀
15:39:24 → DONMA: 482ms 💀
15:40:50 → DONMA: 958ms 💀
Donma süreleri zamanla nasıl büyüdü:
3. saat
114ms
5. saat
195ms
7. saat
274ms
9. saat
570-674ms (3'lü küme!)
11. saat
902-958ms (3'lü küme!)

🔧 Ne Yapıldı, Ne Yapılacak?

YAPILDI ✅ backBufferLength: 5 → 0

Çalınan segmentleri bellekte tutmayı durdurduk. Şarkı geçişlerinde oluşan ani çöp miktarı %60 azaldı. Bu tek değişiklik bile büyük fark yaratacak.

// player-core.js → HLS_SHARED_CONFIG
2
SIRADAKI 🎯 Normal segmentler: 10s → 6s

Tüm şarkıların normal kalite .ts dosyaları yeniden encode edilecek. Her parça küçülecek, GC'nin temizleyeceği çöp daha az olacak. Bunun için aşağıdaki AI promptu kullanılacak.

📁 hls/{id}/segment-*.ts 10s → 6s
3
SONRA Test ve doğrulama

backBuffer fix sonrası test, ardından segment encode sonrası test. Donma sayısı 0'a inmeli.

🛡️ Canlı Dinleme Sırasında Güvenli mi? (Önemli Soru!)

"Birisi şu an müzik dinlerken biz sunucudaki dosyaları değiştirirsek ne olur?" diye sorulabilir. Cevap: Tamamen güvenli. İşte nedenleri:

1️⃣ Tarayıcı Zaten Bufferlıyor

Kullanıcı segment-005.ts'i dinliyorsa, tarayıcı büyük ihtimalle 007, 008, 009'u da indirmiş ve kendi belleğine kopyalamış. Diskteki dosyayı silsen bile tarayıcı kendi kopyasından çalar. Etkilenmez.

2️⃣ Linux Açık Dosya Koruması

Tam o anda sunucudan indirilmekte olan bir segment varsa, Linux o dosyanın "inode"unu (kimliğini) korur. Üzerine yazsan bile aktif HTTP isteği tamamlanır. Veri kaybı yok.

3️⃣ Atomik Playlist Swap

Tek tehlike: playlist.m3u8'i yarım güncellersen eski segment isimleri + yeni sayı karışıklığı olur. Çözüm: önce TÜM yeni segment-*.ts'leri yaz, SONRA playlist.m3u8'i güncelle. Sıra bozulmamalı.

4️⃣ Karma Geçiş Normal

Migrasyon sırasında şarkı A 6s'ye geçmiş, şarkı B hâlâ 10s olabilir. Her şarkının kendi bağımsız playlist.m3u8'i var — karışmazlar. Kullanıcılar aynı anda farklı versiyonları dinleyebilir, sorun yok.

✅ Doğru Migrasyon Sırası
1. Yeni segment-*.ts yaz
2. playlist.m3u8 güncelle
3. Eski segment-*.ts sil
❌ YANLIŞ SIRA:
Eski sil → playlist güncelle → yeni yaz
→ Kısa pencerede 404 hatası! Playlist geçersiz segment referans eder.

📁 Dosya Yapısı (Neye Dokunulacak, Neye Dokunulmayacak)

/storage/tenant1001/app/public/muzibu/hls/
└── 34461/ (şarkı ID)
├── segment-000.ts ← 10s, YENİSİYLE DEĞİŞECEK
├── segment-001.ts ← 10s, YENİSİYLE DEĞİŞECEK
├── ...
├── playlist.m3u8 ← YENİDEN ÜRETILECEK (6s)
├── master.m3u8 ← kontrol edilecek
├── enc.bin ← DOKUNULMAYACAK 🔒
├── enc.keyinfo ← DOKUNULMAYACAK 🔒
├── low/ ← DOKUNULMAYACAK ✅ (4s)
└── ultralow/ ← DOKUNULMAYACAK ✅ (4s)
⚠️ Eski segment-*.ts dosyaları önce yenileri yazılıp, playlist güncellendikten sonra silinecek. Sıra önemli!

🤔 Neden 6 Saniye? 4 Değil, 10 Değil?

Süre HTTP İstek/Şarkı İlk Ses GC Sonuç
4s ~50 istek 4s ✅ Az ✅ Sunucuya fazla yük ⚠️
6s ⭐ ~33 istek 6s ✅ Az ✅ Tatlı nokta 🎯
8s ~25 istek 8s ⚠️ Orta Kabul edilebilir
10s ~20 istek 10s ❌ Fazla ❌ Mevcut sorun 💀

⚙️ Teknik Detaylar (Geliştiriciler İçin)

Mevcut Durum
HLSService.php:
const CHUNK_DURATION = 4;
↑ Bu low/ultralow için kullanılmış
Normal segmentler: 10s
(eski encode, farklı ayar)
TARGETDURATION: 10
Şarkı başına segment: ~20
Segment boyutu (192k): ~240KB
Hedef Durum
HLSService.php:
const CHUNK_DURATION = 6;
↑ Tüm kaliteler için 6s olacak
Normal segmentler: 6s
(yeniden encode)
TARGETDURATION: 6
Şarkı başına segment: ~34
Segment boyutu (192k): ~144KB
Servis Dosyası
app/Services/Muzibu/HLSService.php
Storage Yolu
storage/tenant1001/app/public/muzibu/hls/
Şifreleme
AES-128 (enc.bin + enc.keyinfo)
🤖

AI Agent Prompt'u

Bu promptu başka bir AI'a ver — segment migrasyonunu yapsın

═══════════════════════════════════════════════════════════════
GÖREV: HLS normal kalite segmentlerini 10 saniyeden 6 saniyeye
       yeniden encode et, eskileri sil
SUNUCU: muzibu.com (CANLI PROD - çok dikkatli ol!)
DİL: Türkçe yanıt ver
═══════════════════════════════════════════════════════════════

⚠️ SUNUCU NOTU:
  Bu prompt mztest.muzibu.com (test sunucusu) üzerinde hazırlandı.
  Asıl işlem PRODUCTION sunucusunda yapılacak: muzibu.com
  Prod dizin:  /var/www/vhosts/muzibu.com/httpdocs/
  Test dizin:  /var/www/vhosts/mztest.muzibu.com/httpdocs/
  Prod owner:  tuufi.com_:psaserv
  Test owner:  mztest:psacln
  (Aşağıdaki tüm yollar prod için — mztest referans aldıysan düzelt!)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. MEVCUT DURUM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

HLS dosyaları şu yerde (PROD):
  /var/www/vhosts/muzibu.com/httpdocs/storage/tenant1001/app/public/muzibu/hls/

Her şarkı için klasör yapısı:
  hls/{song_id}/
  ├── segment-000.ts   ← BUNLAR 10s, YENİSİYLE DEĞİŞECEK
  ├── segment-001.ts   ← BUNLAR 10s, YENİSİYLE DEĞİŞECEK
  ├── ...
  ├── playlist.m3u8    ← YENİDEN ÜRETILECEK (6s)
  ├── master.m3u8      ← güncellenmesi gerekebilir
  ├── enc.bin          ← DOKUNMA (şifreleme anahtarı)
  ├── enc.keyinfo      ← DOKUNMA (şifreleme bilgisi)
  ├── low/             ← DOKUNMA (zaten 4s, iyi)
  └── ultralow/        ← DOKUNMA (zaten 4s, iyi)

Mevcut normal kalite playlist.m3u8 örneği:
  #EXT-X-TARGETDURATION:10
  #EXTINF:10.005333,
  segment-000.ts

Hedef (6s sonrası):
  #EXT-X-TARGETDURATION:6
  #EXTINF:6.000000,
  segment-000.ts

PHP binary: /opt/plesk/php/8.3/bin/php
Servis dosyası: app/Services/Muzibu/HLSService.php
Ana dizin (PROD): /var/www/vhosts/muzibu.com/httpdocs
Dosya sahibi (PROD): tuufi.com_:psaserv (mztest'ten farklı!)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2. ÖNCE ANLA - SONRA YAP
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Başlamadan şunları öğren:

A) Kaç şarkının normal segmenti var?
   (low/ ve ultralow/ içindekiler hariç sadece root'taki segment-*.ts)

B) HLSService.php'i oku:
   - Normal kalite için FFmpeg parametreleri neler?
   - Bitrate, sample rate, codec ne?
   - CHUNK_DURATION sabiti nerede, nasıl kullanılıyor?
   - AES-128 şifreleme nasıl uygulanıyor? enc.keyinfo formatı ne?

C) master.m3u8 içeriğine bak (örn: hls/34461/master.m3u8):
   Normal kaliteye olan referans nasıl yazılmış?

D) Şarkı tablosunda HLS ile ilgili hangi alanlar var?
   (hls_url, hls_path, hls_status vs.)
   DB'ye yazma YOK ama bağımlılık var mı diye bilmek lazım

E) Mevcut encode artisan command'i var mı?
   /opt/plesk/php/8.3/bin/php artisan list | grep -i hls

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3. CANLI DİNLEME SIRASINDA GEÇİŞ GÜVENLİĞİ (ÖNEMLE OKU!)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Migrasyon sırasında kullanıcılar o şarkıları dinliyor olabilir.
Bu SORUN DEĞİL. İşte nedenler:

1. TARAYICI BELLEKTE ZATEN VAR:
   Kullanıcı seg-005'i dinliyorsa tarayıcı seg-007, 008, 009'u
   indirmiş ve kendi belleğine kopyalamış. Diskteki dosya değişse
   etkilenmez, kendi kopyasından çalar.

2. LİNUX AÇIK DOSYA KORUMASI:
   Tam o anda bir segment HTTP ile indirilirken bile üzerine
   yazabilirsin. Linux o inode'u aktif istek için korur, yeni
   yazma yeni inode alır. Aktif istek kesilmez.

3. HER ŞARKI BAĞIMSIZ:
   Migrasyon sırasında şarkı A 6s'ye geçmiş, şarkı B hâlâ
   10s olabilir. Her şarkının kendi playlist.m3u8'i bağımsız.
   Kullanıcılar aynı anda farklı formatlarda dinleyebilir, karışmaz.

✅ DOĞRU SIRANIN ÖNEMİ:
   Playlist.m3u8 hiçbir zaman "var olmayan segment" referans
   etmemeli. Bu yüzden sıra ŞÖYLE OLMALI:

   ADIM 1: Yeni 6s segment-*.ts dosyalarını geçici klasöre yaz
   ADIM 2: Tüm segmentler tamam mı? (sayı ve boyut kontrolü)
   ADIM 3: Yeni segmentleri hedef klasöre kopyala/taşı
   ADIM 4: playlist.m3u8'i güncelle (artık yeni segmentlere uygun)
   ADIM 5: Eski segment-*.ts dosyalarını sil

   ❌ YANLIŞ: Eskiyi sil → playlist güncelle → yeni yaz
      (Kısa pencerede playlist geçersiz segment referans eder → 404)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4. MİGRASYON STRATEJİSİ (SIRASINI BOZMA!)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

AŞAMA 1 — TEK ŞARKI TEST (song_id: 34461)
  1a. Mevcut playlist.m3u8 ve segment-*.ts'leri yedekle:
      /tmp/hls_backup_34461/ klasörüne kopyala
  1b. Orijinal ses dosyasını bul (.mp3 veya .aac)
  1c. FFmpeg ile 6s segmentler üret:
      - Geçici klasöre yaz (/tmp/hls_new_34461/)
      - AYNI bitrate, codec, sample rate kullan
      - AES-128 şifrelemeyi aynı enc.bin ile uygula
      - enc.keyinfo dosyasını doğru referans et
  1d. Yeni playlist.m3u8 üret (6s TARGETDURATION ile)
  1e. TEST: Yeni playlist'i kontrol et:
      - Şarkı ~200s ise: 200/6 ≈ 34 segment olmalı
      - TARGETDURATION:6 yazıyor mu?
      - EXTINF değerleri ~6s mi?
  1f. DOĞRU SIRADA yerleştir (yukarıdaki Bölüm 3'e bak):
      Önce yeni segment-*.ts'leri kopyala → sonra playlist.m3u8
  1g. Eski dosyaları SİLME, önce kullanıcıdan onay iste

AŞAMA 2 — TOPLU MİGRASYON (kullanıcı onayı sonrası)
  2a. Tüm song_id'leri bul (sadece kök dizinde segment-*.ts olanlar)
  2b. Her şarkı için şu SIRAYI takip et:
      - Orijinal ses dosyası var mı? (yoksa atla, log'a yaz)
      - 6s segmentler üret → /tmp/hls_new_{id}/ geçici klasörüne
      - Üretim başarılı mı? (segment sayısı mantıklı mı?)
      - BAŞARILI ise:
        a) Yeni segment-*.ts'leri hedef klasöre kopyala
        b) playlist.m3u8'i güncelle
        c) Eski segment-*.ts'leri sil (sadece artık listede olmayanları!)
        d) Dosya izinlerini düzelt:
           chown tuufi.com_:psaserv {dosya} && chmod 644 {dosya}
      - HATA ise: o şarkıyı atla, log'a yaz, devam et
  2c. Her 10 şarkıda bir ilerleme raporu ver
  2d. Hata olan şarkıları /tmp/hls_migrate_errors.log'a yaz

AŞAMA 3 — DOĞRULAMA
  3a. Rastgele 5 şarkı seç:
      - playlist.m3u8'de TARGETDURATION:6 var mı?
      - EXTINF değerleri ~6s mi?
      - Segment sayısı: (şarkı süresi / 6) ile uyuşuyor mu?
  3b. enc.bin dosyaları hâlâ yerinde mi? (dokunulmadı mı?)
  3c. low/ ve ultralow/ klasörleri hâlâ 4s mi? (dokunulmadı mı?)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5. KRİTİK UYARILAR
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

❌ DOKUNMA:
  - low/ klasörleri (zaten 4s)
  - ultralow/ klasörleri (zaten 4s)
  - enc.bin dosyaları (şifreleme anahtarı, değişirse şarkı çalmaz)
  - enc.keyinfo dosyaları
  - Veritabanı tabloları
  - .env dosyası
  - player-core.js
  - php artisan migrate çalıştırma

⚠️ DİKKAT:
  - Encode sırasında orijinal kaliteyi koru (bitrate, codec değişmesin)
  - Şifreleme parametreleri HLSService.php ile AYNI olmalı
  - playlist.m3u8 URI yolları relative kalmalı (segment-000.ts, tam URL değil)
  - enc.bin URI'si absolute URL olmalı (playlist içinde tam URL)
  - Yeni segmentler yazılmadan playlist.m3u8 GÜNCELLEME (sıra önemli!)
  - Migrasyon sırasında karma durum (kimi 6s, kimi 10s) normaldir, sorun değil

✅ ZORUNLU:
  - Her encode sonrası dosya izinlerini düzelt (PROD için):
    chown tuufi.com_:psaserv {dosya} && chmod 644 {dosya}
  - Hata halinde o şarkıyı atla, log'a yaz, dur değil devam et
  - Playlist güncellemesi ATOMIK olmalı (önce segmentler, sonra playlist)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
6. BAŞARI KRİTERLERİ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✅ Tüm normal kalite playlist.m3u8 → TARGETDURATION:6
✅ Eski 10s segment-*.ts dosyaları yok
✅ Yeni 6s segment-*.ts dosyaları yerinde
✅ enc.bin / enc.keyinfo dokunulmamış
✅ low/ ve ultralow/ klasörleri dokunulmamış
✅ Dosya sahipleri (PROD): tuufi.com_:psaserv, izin: 644
✅ Hata olan şarkılar raporlandı

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7. RAPORLAMA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

AŞAMA 1 bitince KULLANICIDAN ONAY İSTE, toplu işleme geçme.

Toplu işlem bitince söyle:
- Toplam kaç şarkı işlendi?
- Kaçı başarılı?
- Kaçı hata verdi? (song_id listesi)
- Kaçı atlandı? (orijinal ses dosyası yok)
- Toplam disk farkı ne oldu?
- 3 örnek şarkının playlist.m3u8 ilk 5 satırını göster

🎯 Her Şey Bitince Ne Olacak?

❌ Şu An
11 saatte 30+ donma
En kötüsü 958ms
Art arda 3'lü küme donmalar
65MB bellek tepesi
Normal: 10s segment, 2 buffer
✅ Hedef
Donma yok (veya çok nadir, kısa)
Varsa max 100-150ms
Küme yok, izole kalacak
~40MB bellek tepesi
Normal: 6s segment, 3 buffer
19 Şubat 2026 • Muzibu.com.tr