🔐

HLS Şifreleme Key Uyumsuzluğu

Sorun tespiti, kök neden analizi, uygulanan çözüm ve production kontrol rehberi

Kritik Bug mztest Düzeltildi Prod Kontrol Gerekli
716
Toplam HLS Şarkı
mztest ortamı
239
Etkilenen Şarkı
%33.4 — key uyumsuz
477
Sağlıklı Şarkı
%66.6 — sorunsuz
~662ms
Tasarruf (P2-10)
master.m3u8 inline

📝 Basit Anlatım (Herkes İçin)

Her şarkı dinlenirken şifreleme anahtarı (key) ile korunan parçalara bölünüyor. Farklı internet hızlarına göre 4 kalite seviyesi var: ultralow (çok düşük), low (düşük), mid (orta) ve high (yüksek/orijinal).

Sorun: Bazı şarkılarda yüksek kalite parçaları yeni anahtarla, düşük kalite parçaları ise eski anahtarla şifrelenmiş. Player düşük kaliteye geçmeye çalışınca eski anahtarla şifreli parçaları çözemez → şarkı durur veya hata verir.

Çözüm: Etkilenen şarkıların düşük kalite parçaları doğru anahtarla yeniden oluşturuldu. Ayrıca bu sorunun tekrar olmaması için koruma eklendi.

Production: Gerçek sunucuda bu sorun olup olmadığı henüz bilinmiyor. Kontrol komutu hazır — aşağıda.

🔧 Teknik Detaylar (Geliştiriciler İçin)

Kök Neden

// ConvertToHLSJob tekrar çalıştırıldığında:
1. random_bytes(16) → yeni enc.bin oluşturur ❌ Sorun burada
2. FFmpeg high segment'leri yeni key ile şifreler
3. addVariantsToExisting() → variant "zaten var" → ATLAR
4. Variant segment'ler ESKİ key ile kalır → fragParsingError

Sorunlu Akış

ConvertToHLSJob (1. çalışma)
├── enc.bin → KEY_A oluştur
├── high segment'ler → KEY_A ile şifrele  ✅
└── variant'lar → KEY_A ile şifrele       ✅  (hepsi aynı key)

ConvertToHLSJob (2. çalışma — TEKRAR)
├── enc.bin → KEY_B oluştur               ❌  YENİ KEY!
├── high segment'ler → KEY_B ile şifrele  ✅  (yeni key)
└── variant'lar → "zaten var" → ATLA      ❌  (hâlâ KEY_A ile şifreli!)

HLS.js oynatırken:
├── enc.bin → KEY_B okur
├── high segment → KEY_B ile çözer        ✅
└── low segment → KEY_B ile çözmeye çalışır
    └── KEY_A ile şifreli → ÇÖZEMEZ       ❌ fragParsingError

Değişen Dosyalar

FIX ConvertToHLSJob.php

enc.bin zaten varsa yeni key oluşturma → mevcut key'i koru

YENİ HLSService.php → generateVariant()

$force parametresi eklendi — mevcut variant'ı silip yeniden oluşturabilir

YENİ AddHlsVariantsCommand.php

--fix-key-mismatch seçeneği — timestamp kontrolü + force yeniden oluşturma

Doğrulama (Decrypt Testi)

// Song 35074 — Fix öncesi:
HIGH: Decrypt OK (yeni key ile şifreli)
LOW: Decrypt FAIL (eski key ile şifreli)
MID: Decrypt FAIL
ULTRALOW: Decrypt FAIL
// Song 35074 — Fix sonrası:
HIGH: Decrypt OK
LOW: Decrypt OK
MID: Decrypt OK
ULTRALOW: Decrypt OK

🛠️ Fix Komutları

1. Kaç şarkı etkilenmiş? (dry-run — hiçbir şeye dokunmaz)

php artisan tenants:run hls:add-variants --tenants=TENANT_ID --option="fix-key-mismatch=1" --option="dry-run=1"

2. Tek şarkıda test (önce bunu yap)

php artisan tenants:run hls:add-variants --tenants=TENANT_ID --option="fix-key-mismatch=1" --option="song=SONG_ID"

3. Tümünü düzelt (arka planda çalıştır)

php artisan tenants:run hls:add-variants --tenants=TENANT_ID --option="fix-key-mismatch=1"

~1.5 dk/şarkı — 239 şarkı ≈ 6 saat

⚠️ Production Kontrol Rehberi

Production'da bu sorunun olma ihtimali düşük — sorun sadece ConvertToHLSJob tekrar çalıştırıldığında oluşur. İlk defa dönüştürülen şarkılarda sorun olmaz.

Hızlı Bash Kontrolü (Claude'a sormadan)

HLS_DIR="storage/tenant*/app/public/muzibu/hls"
total=0; mismatch=0
for dir in $HLS_DIR/*/; do
  [ ! -f "$dir/enc.bin" ] && continue
  total=$((total + 1))
  enc_t=$(stat -c '%Y' "$dir/enc.bin")
  for v in low ultralow mid; do
    [ ! -f "$dir/$v/segment-000.ts" ] && continue
    v_t=$(stat -c '%Y' "$dir/$v/segment-000.ts")
    [ $((enc_t - v_t)) -gt 60 ] && { mismatch=$((mismatch+1)); break; }
  done
done
echo "Toplam: $total | Uyumsuz: $mismatch"

Sonuç 0 ise: Sorun yok, hiçbir şeye dokunma.

Sonuç > 0 ise: Önce dry-run, sonra tek şarkı test, sonra toplu fix.

🛡️ Tekrar Olmasını Önleyen Koruma

// ConvertToHLSJob.php — satır ~90
if (file_exists($keyPath) && file_exists($keyInfoPath) && filesize($keyPath) === 16) {
// Mevcut key'i koru — yeni key oluşturma
Log::info('Mevcut key korunuyor (re-run)');
} else {
// İlk dönüşüm — yeni key oluştur
$encryptionKey = random_bytes(16);
}

Artık ConvertToHLSJob tekrar çalışsa bile mevcut enc.bin korunur → variant'larla key uyumu bozulmaz.

📊 mztest Fix Durumu

Tespit edilen uyumsuz şarkı 239
Etkilenen ID aralığı 34802 — 35172
Fix komutu hls:add-variants --fix-key-mismatch
Fix durumu Çalışıyor...
Tahmini süre ~6 saat (239 × ~1.5dk)
ConvertToHLSJob koruması Eklendi ✓

📅 Zaman Çizelgesi

1
26 Şubat — İlk HLS dönüşüm
Variant'lar KEY_A ile oluşturuldu (13:15-13:44)
2
26 Şubat — ConvertToHLSJob tekrar çalıştı
Yeni KEY_B oluşturuldu, high yeniden encode (15:40-16:28), variant'lar atlandı
3
28 Şubat — Sorun tespit edildi
ABA test, fragParsingError yakaladı (song 35074)
4
1 Mart — Kök neden analizi
Decrypt testi ile doğrulandı: HIGH ✅ LOW ❌ MID ❌ ULTRALOW ❌
5
1 Mart — Fix uygulandı
--fix-key-mismatch komutu + ConvertToHLSJob koruması eklendi
1 Mart 2026 • Muzibu.com.tr