HLS 4 Saniye Production v2

HLS 4-Saniye Standardizasyon

Production Deployment Rehberi + Claude Prompt

Basit Anlatim Teknik Detay Production Adimlari Dogrulama Hata Yonetimi Claude Prompt Test Sonuclari

📝 Basit Anlatim (Herkes Icin)

Muzibu'daki sarkilar dinlenirken kucuk parcalar halinde (segment) yukleniyor. Onceden bu parcalar 6 saniyeydi, simdi tum kalite seviyelerinde 4 saniye olarak standardize edildi.

Onceki Durum

  • High kalite: 6 saniye segment
  • Diger kaliteler: 4 saniye segment
  • Tutarsiz FFmpeg parametreleri
  • Eski olu kodlar mevcut

Simdiki Durum

  • Tum kaliteler: 4 saniye segment
  • Standart FFmpeg parametreleri
  • Olu kodlar temizlendi
  • Production'a hazir

Neden Onemli? 4 saniye segment, Apple HLS standardina uygun ve tum varyantlar arasinda tutarlilik sagliyor. Bu sayede adaptive bitrate (otomatik kalite gecisi) daha yumusak calisiyor.

🔧 Teknik Detaylar (Gelistiriciler Icin)

Yapilan Kod Degisiklikleri

# Dosya Degisiklik
1 ConvertToHLSJob.php FFmpeg'e -profile:a aac_low -ar 48000 -ac 2 eklendi
2a HLSService.php:125 $targetBitrate undefined bug fix
2b HLSService.php:158 buildFFmpegCommand() internal helper olarak isaretlendi
3 AddHlsVariantsCommand.php --re-encode-high flag'i eklendi (high'i 4sn ile yeniden olusturur)
4 ConvertSongToHLS.php Silindi (olu kod)
5 routes/web.php /stream/key/ eski route kaldirildi
6 hls-streaming.blade.php Dokumantasyon guncellendi

Her Sarki Dosya Yapisi

storage/tenant{id}/app/public/muzibu/hls/{song_id}/
├── enc.bin              ← 16 byte AES-128 key (binary)
├── enc.keyinfo          ← 3 satir: URI + path + IV
├── master.m3u8          ← 4 varyant referansi
├── playlist.m3u8        ← high kalite (4sn, VOD, encrypted)
├── segment-*.ts         ← high segment'ler
├── ultralow/            ← 32kbps, mono, 22050Hz
├── low/                 ← 64kbps, mono, 22050Hz
└── mid/                 ← 128kbps, stereo, 44100Hz

storage/tenant{id}/app/public/muzibu/songs/mp3_128/
└── {song_id}.mp3        ← 128kbps MP3 fallback

🚀 Production Deployment (~30K Sarki)

Ana sunucuda adim adim yapilacaklar. Sirasini BOZMA!

1

Kodu Cek + Cache Temizle

cd /var/www/vhosts/muzibu.com/httpdocs

# Kodu cek
git pull origin main

# Cache temizle (route degisti, eski /stream/key/ kaldirildi)
php artisan cache:clear
php artisan route:clear
php artisan config:clear
php artisan view:clear
composer dump-autoload

Neden? Yeni kod geldi: --re-encode-high flag'i, bug fix'ler, olu kod temizligi. Cache temizlemezsen eski route'lar sorun cikarir.

2

Dry-Run (Sadece Say, Dokunma)

php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="dry-run=1"

Beklenen cikti: "Toplam HLS: ~30000, Islenecek: ~30000". Hicbir dosyaya dokunmaz, sadece sayar.

3

Kucuk Batch Test (10 Sarki)

php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="limit=10"

Beklenen: "10 basarili, 0 basarisiz". ~3-5 dakika surer.

4

Test Sonucunu Dogrula

HLS_BASE="storage/tenant1001/app/public/muzibu/hls"

# Ilk 10 sarkinin hepsini kontrol et
GOOD=0; BAD=0; COUNT=0
for DIR in $(ls -d $HLS_BASE/*/ | head -10); do
    [ ! -f "$DIR/master.m3u8" ] && continue
    COUNT=$((COUNT + 1))

    # Segment suresi (4.xxx olmali, 6.xxx olmamali)
    MAX=$(grep '#EXTINF:' "$DIR/playlist.m3u8" | sed 's/#EXTINF://' | sed 's/,.*//' | sort -rn | head -1)
    INT=$(echo "$MAX" | cut -d. -f1)

    # 4 varyant olmali
    HAS_ALL=1
    for V in ultralow low mid; do
        [ ! -f "$DIR/$V/playlist.m3u8" ] && HAS_ALL=0
    done

    # VOD olmali
    HAS_VOD=0
    grep -q '#EXT-X-PLAYLIST-TYPE:VOD' "$DIR/playlist.m3u8" && HAS_VOD=1

    if [ "$INT" -le 4 ] && [ "$HAS_ALL" -eq 1 ] && [ "$HAS_VOD" -eq 1 ]; then
        GOOD=$((GOOD + 1))
    else
        BAD=$((BAD + 1))
        echo "SORUN: $(basename $DIR) max=$MAX varyant=$HAS_ALL vod=$HAS_VOD"
    fi
done
echo "Kontrol: $COUNT sarki, $GOOD OK, $BAD SORUNLU"

Beklenen: "10 OK, 0 SORUNLU". Sorun varsa DURMA, once analiz et.

5

Tam Re-encode (3 Paralel Terminal)

~7 SAAT

3 ayri terminal ac. Her birinde farkli offset ile calistir. screen veya tmux kullan ki terminal kapansa da devam etsin!

TERMINAL 1 — Sarki 1 - 10.000

screen -S hls-batch1
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="limit=10000" \
    --option="offset=0"

TERMINAL 2 — Sarki 10.001 - 20.000

screen -S hls-batch2
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="limit=10000" \
    --option="offset=10000"

TERMINAL 3 — Sarki 20.001 - 30.000

screen -S hls-batch3
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="limit=10000" \
    --option="offset=20000"

Tahmini Sure: ~30K sarki x ~20sn/sarki = ~7 saat (3 paralel). mztest'te 66 sarki 22 dakikada bitti.

screen kullanimi: Ctrl+A D = ayir (arka planda calisir), screen -r hls-batch1 = geri baglan

6

Son Dogrulama (3 Batch Bittikten Sonra)

HLS_BASE="storage/tenant1001/app/public/muzibu/hls"

echo "=== GENEL DURUM ==="
echo "Toplam HLS klasoru: $(ls -d $HLS_BASE/*/ 2>/dev/null | wc -l)"
echo "master.m3u8 olan: $(ls $HLS_BASE/*/master.m3u8 2>/dev/null | wc -l)"
echo "MP3 128k: $(ls storage/tenant1001/app/public/muzibu/songs/mp3_128/*.mp3 2>/dev/null | wc -l)"

echo ""
echo "=== RASTGELE 20 SARKI KONTROL ==="
GOOD=0; BAD=0
for DIR in $(ls -d $HLS_BASE/*/ | shuf | head -20); do
    [ ! -f "$DIR/master.m3u8" ] && continue
    MAX=$(grep '#EXTINF:' "$DIR/playlist.m3u8" | sed 's/#EXTINF://' | sed 's/,.*//' | sort -rn | head -1)
    INT=$(echo "$MAX" | cut -d. -f1)
    HAS_ALL=1
    for V in ultralow low mid; do
        [ ! -f "$DIR/$V/playlist.m3u8" ] && HAS_ALL=0
    done
    if [ "$INT" -le 4 ] && [ "$HAS_ALL" -eq 1 ]; then
        GOOD=$((GOOD + 1))
    else
        BAD=$((BAD + 1))
        echo "SORUN: $(basename $DIR)"
    fi
done
echo "Sonuc: $GOOD OK, $BAD SORUNLU"
7

Final Cache Temizligi

php artisan cache:clear
php artisan view:clear
php artisan responsecache:clear

Dogrulama Kontrol Listesi

Kontrol Beklenen Nasil Kontrol?
High segment suresi ~4.0xx sn grep '#EXTINF:' playlist.m3u8 | head -3
master.m3u8 varyant sayisi 4 (ultralow + low + mid + original) cat master.m3u8
Varyant klasorleri ultralow/ + low/ + mid/ mevcut ls -d */
enc.keyinfo URI /hls-key/muzibu/songs/{id} head -1 enc.keyinfo
Playlist tipi #EXT-X-PLAYLIST-TYPE:VOD grep PLAYLIST-TYPE playlist.m3u8
MP3 128k dosyasi mp3_128/{song_id}.mp3 mevcut ls songs/mp3_128/ | wc -l

⚠️ Hata Yonetimi + Guvenlik Garantileri

Durum Ne Olur? Risk
MP3 dosyasi yok Atlar, failed sayar, devam eder Yok
HLS klasoru yok Atlar Yok
FFmpeg hata Log'lar, failed sayar, devam eder Yok
enc.keyinfo yok re-encode atlar, variant eklemeye devam Yok
Zaten variant var Atlar (uzerine yazmaz) Yok
Disk dolu FFmpeg hata verir, log'lanir, devam eder Orta
Terminal kapanirsa screen kullan! Orta
Islem ortasinda durur Ayni komutu tekrar calistir, mevcut olanlari atlar Yok

Onemli Guvenlik Notu

  • • Orijinal MP3'ler HICBIR ZAMAN silinmez veya degistirilmez
  • • enc.bin (encryption key) korunur, sadece segment'ler yeniden uretilir
  • • Islem sirasinda sarkilar calismaya devam eder (mevcut segment'ler silinip yerine yenileri yazilir)
  • • Komut hatada durmaz, devam eder ve sonunda rapor verir

Rollback Plani

En kotu senaryoda geri almak icin:

  1. Kod degisikliklerini geri al: git checkout -- .
  2. Orijinal MP3'ler her zaman mevcut
  3. Yeniden HLS donusumu icin: ConvertToHLSJob zaten 4sn + varyant uretiyor
  4. Tek sarki test: --option="song=12345" ile belirli sarki test et

🤖 Claude Prompt (Production Sunucuya Kopyala-Yapistir)

Asagidaki prompt'u production sunucudaki Claude'a ver. Tum islemleri otomatik yapacak.

KOPYALA
Muzibu HLS sisteminde 4-saniye standardizasyon yapildi. Test sunucusunda (mztest) 66 sarki basariyla tamamlandi. Simdi production sunucuda (~30K sarki) ayni islemi yapman gerekiyor.

## Ne Yapildi (mztest'te)?
1. ConvertToHLSJob.php: FFmpeg'e -profile:a aac_low -ar 48000 -ac 2 eklendi
2. HLSService.php: $targetBitrate undefined bug fix
3. AddHlsVariantsCommand.php: --re-encode-high flag'i eklendi
4. ConvertSongToHLS.php silindi (olu kod)
5. /stream/key/ eski route kaldirildi
6. hls-streaming.blade.php dokumantasyonu guncellendi

## Senin Yapacaklarin (SIRAYLA!)

### 1. Kodu cek
```bash
cd /var/www/vhosts/muzibu.com/httpdocs
git pull origin main
php artisan cache:clear && php artisan route:clear && php artisan config:clear && php artisan view:clear
composer dump-autoload
```

### 2. Dry-run (sadece say, hicbir seye dokunma)
```bash
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="dry-run=1"
```
Beklenen: "Toplam HLS: ~30000, Islenecek: ~30000"

### 3. 10 sarki ile test
```bash
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" \
    --option="mp3-128=1" \
    --option="refresh-master=1" \
    --option="re-encode-high=1" \
    --option="limit=10"
```
Beklenen: "10 basarili, 0 basarisiz" (~3-5 dk)

### 4. Test sonucunu dogrula
Ilk 10 sarkiyi kontrol et:
- playlist.m3u8'deki #EXTINF degerleri ~4.0xx olmali (6.xxx OLMAMALI)
- master.m3u8'de 4 varyant olmali (ultralow + low + mid + original)
- enc.keyinfo URI /hls-key/ ile baslamali
- VOD tipi olmali
- Sorun varsa DURMA, analiz et

### 5. Tam re-encode (3 paralel terminal, screen kullan!)
```bash
# Terminal 1
screen -S hls-batch1
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" --option="mp3-128=1" \
    --option="refresh-master=1" --option="re-encode-high=1" \
    --option="limit=10000" --option="offset=0"

# Terminal 2
screen -S hls-batch2
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" --option="mp3-128=1" \
    --option="refresh-master=1" --option="re-encode-high=1" \
    --option="limit=10000" --option="offset=10000"

# Terminal 3
screen -S hls-batch3
php artisan tenants:run hls:add-variants --tenants=1001 \
    --option="quality=all" --option="mp3-128=1" \
    --option="refresh-master=1" --option="re-encode-high=1" \
    --option="limit=10000" --option="offset=20000"
```
Tahmini sure: ~7 saat (3 paralel). screen -r hls-batch1 ile takip et.

### 6. Tamamlaninca dogrulama
Rastgele 20 sarki kontrol et:
- High segment suresi 4sn mi?
- 4 varyant var mi?
- enc.keyinfo URI dogru mu?
- MP3 128k var mi?
Sonucu bana raporla.

### 7. Final cache temizligi
```bash
php artisan cache:clear && php artisan view:clear && php artisan responsecache:clear
```

## ONEMLI NOTLAR
- Orijinal MP3'ler HICBIR ZAMAN silinmez/degistirilmez
- Hata olursa komut durmaz, sayar ve devam eder
- Islem ortasinda kesilirse, ayni komutu tekrar calistir (mevcut olanlari atlar)
- screen kullan ki terminal kapansa da islem devam etsin
- SERVIS RESTART YAPMA (apache, nginx, redis vs.)
- Migration YOK, sadece dosya islemi

Test Sunucusu Sonuclari (mztest.muzibu.com)

66 sarki, 22 dakika, 0 hata

Kontrol Sonuc
High segment suresi 66/66 = 4sn
6sn eski segment 0 (tamamen temizlendi)
master.m3u8 (4 varyant) 66/66
enc.keyinfo URI (/hls-key/) 66/66
VOD tipi 66/66
MP3 128k 66
Basarisiz 0

⚙️ Artisan Command Referansi

php artisan tenants:run hls:add-variants --tenants=1001

Secenekler:
  --option="quality=all"        Tum varyantlar (ultralow + low + mid)
  --option="quality=low"        Sadece low varyant
  --option="mp3-128=1"          128kbps MP3 de uret
  --option="refresh-master=1"   master.m3u8'i yeniden olustur
  --option="re-encode-high=1"   High playlist'i 4sn segment ile yeniden olustur
  --option="song=123"           Belirli bir sarki ID
  --option="limit=100"          Maksimum islenecek sarki
  --option="offset=0"           Atlanacak sarki (paralel batch icin)
  --option="dry-run=1"          Sadece sayilari goster, islem yapma
22 Subat 2026 • Muzibu.com.tr