Streaming Altyapı Planı
Sıfır Donma Hedefi

Adaptive Bitrate HLS + Bunny CDN

30.000 şarkı, 3 kalite seviyesi, sıfır donma — Spotify seviyesi streaming altyapısı

Sorun Nedir?

Basit Anlatım (Herkes İçin)

Şu an her şarkı tek bir kalitede çalıyor (~270 kbps). Bu ev internetinde sorun değil ama:

  • Yavaş internet (metroda, otobüste, kötü WiFi) → şarkı yüklenemiyor → donma
  • Uzak kullanıcılar (sunucu Fransa'da, kullanıcı Türkiye'de) → mesafe gecikmesi → takılma
  • Yoğun saatler → sunucu yavaşlıyor → gecikme

Kullanıcılar para ödeyip donma yaşayınca şikayet ediyor. Bu kabul edilemez.

Teknik Detay (Geliştiriciler İçin)

Mevcut Yapı

  • HLSService.php → FFmpeg ile tek kalite HLS
  • playlist.m3u8 → ~270kbps AAC, AES-128
  • segment-XXX.ts → 4 saniyelik parçalar
  • CDN yok → her istek doğrudan origin sunucudan

Sonuç

  • Bant genişliği < 270kbps → buffer underrun
  • RTT yüksek → segment fetch gecikmesi
  • Origin yükü → TTFB artışı
  • Tek kalite → fallback mekanizması yok

Çözüm: Adaptive Bitrate + Bunny CDN

Nasıl Çalışacak?

MP3 Yüklendi
FFmpeg
3 Kalite
Origin
Sunucu
Bunny CDN
Global Cache
Kullanıcı
Sıfır Donma

Spotify, Apple Music, YouTube Music — hepsi tam olarak bunu yapıyor. Başka sihirli bir teknoloji yok.

3 Kalite Seviyesi

Kalite Bitrate Sample Rate Kanal 4dk Boyut Ne Zaman?
LOW 64 kbps 22.050 Hz Mono ~1.9 MB 2G/3G, metro, kötü WiFi
MID 128 kbps 44.100 Hz Stereo ~3.8 MB Normal 4G, orta WiFi
HIGH 256-320 kbps 48.000 Hz Stereo ~5.5 MB Hızlı WiFi, fiber (varsayılan)

HLS.js player internet hızını sürekli ölçer. Hız düşerse otomatik olarak düşük kaliteye geçer — kullanıcı fark etmez, şarkı hiç durmaz.

Yeni Dosya Yapısı (Her Şarkı)

Eski (Tek Kalite)

hls/{songId}/
├── playlist.m3u8      # ~270kbps tek
├── segment-000.ts
├── segment-001.ts
├── ...
├── enc.bin            # AES-128 key
└── enc.keyinfo

Yeni (3 Kalite)

hls/{songId}/
├── master.m3u8        # YENİ - yönlendirici
├── playlist.m3u8      # HIGH (mevcut)
├── segment-000.ts     # HIGH (mevcut)
├── ...
├── mid/                # YENİ klasör
│   ├── playlist.m3u8  # 128kbps
│   └── segment-*.ts
├── low/                # YENİ klasör
│   ├── playlist.m3u8  # 64kbps
│   └── segment-*.ts
├── enc.bin            # Aynı key (paylaşımlı)
└── enc.keyinfo

Uygulama Planı (6 Adım)

1

HLSService.php — 3 Kalite Oluşturma

Yeni şarkı yüklendiğinde otomatik 3 kaliteye çevirme

Dosya: app/Services/Muzibu/HLSService.php

Değişiklikler:

  • convertToHLS() → High kalite sonrası mid + low oluşturur
  • generateVariant() → Belirtilen bitrate ile HLS oluşturur (YENİ)
  • createVariantKeyInfo() → Aynı enc.bin'i referans eden keyinfo (YENİ)
  • generateMasterPlaylist() → 3 kaliteyi listeleyen master.m3u8 (YENİ)
  • addVariantsToExisting() → Mevcut şarkılara mid+low ekleme (YENİ)
2

SongStreamController.php — Dosya Sunma

master.m3u8 + mid/ ve low/ klasörlerini sunma desteği

Dosya: Modules/Muzibu/App/Http/Controllers/Api/SongStreamController.php

Değişiklikler:

  • serveHls() regex → master.m3u8, mid/playlist.m3u8, low/playlist.m3u8, mid/segment-*.ts, low/segment-*.ts eklenir
  • master.m3u8 ve variant playlist'ler için imza doğrulama
  • • Variant playlist'lerdeki key URL'leri güvenli API endpoint'e yönlendirme
3

SignedUrlService.php — URL Yönlendirme

playlist.m3u8 yerine master.m3u8'e yönlendirme

Dosya: app/Services/SignedUrlService.php

Değişiklikler:

  • generateHlsUrl() → path: /playlist.m3u8 yerine /master.m3u8
  • • Geriye uyumluluk: master.m3u8 yoksa otomatik playlist.m3u8'e fallback
  • • Bunny CDN URL oluşturma aynı kalır
4

Artisan Komutu — Mevcut Şarkıları Dönüştürme

30.000 mevcut şarkıya mid + low kalite ekleme (mevcut high'a dokunmaz!)

Komut: php artisan hls:add-variants

Mantık:

  • • Mevcut HLS klasörlerini tarar
  • master.m3u8 yoksa → mid/ ve low/ oluşturur
  • • Mevcut playlist.m3u8 ve segment'lere DOKUNMAZ
  • • Horizon queue ile paralel işleme (batch)
  • • İlerleme takibi: --progress flag

Süre tahmini: 30.000 şarkı × ~5 sn = ~42 saat (Horizon ile paralel: ~10-15 saat)

5

Bunny CDN Aktifleştirme

Zaten kurulu olan CDN'i devreye alma

Pull Zone: muzibu-hls (ID: 5347238)

Hostname: cdn.muzibu.com

Yapılacak:

  • • Production .env: BUNNY_CDN_ENABLED=true
  • • Cache temizle: php artisan config:clear
  • • Test et: birkaç şarkı çalıştır, CDN header'larını kontrol et

Zaten hazır: Pull Zone, Token Auth, Edge Rules, CNAME — hepsi kurulu. Sadece switch açılacak.

6

Player Ayarları (Otomatik)

HLS.js zaten adaptive bitrate destekliyor — ek kod gerektirmez

Mevcut player: public/themes/muzibu/js/player/core/player-core.js

HLS.js davranışı:

  • master.m3u8 yüklenince otomatik olarak kalite listesini algılar
  • • Bant genişliğini sürekli ölçer (EWMA algoritması)
  • • Hız düşerse → otomatik düşük kaliteye geçer
  • • Hız yükselirse → yüksek kaliteye geri döner
  • Kullanıcı hiçbir şey fark etmez, şarkı hiç durmaz

Not: İsteğe bağlı olarak player'a kalite seçici eklenebilir (Spotify'daki "Yüksek Kalite" / "Veri Tasarrufu" gibi).

Sıfır Donma Garantisi — 4 Katmanlı Koruma

Katman 1: Adaptive Bitrate

3 kalite seviyesi. İnternet yavaşlayınca kalite düşer ama şarkı asla durmaz. En kötü 64kbps mono — FM radyo kalitesi, ama akıcı.

Katman 2: Bunny CDN

Dosyalar kullanıcıya en yakın CDN noktasından gelir. Türkiye'deki kullanıcı İstanbul edge'inden alır — gecikme minimuma iner.

Katman 3: Preload Buffer

Mevcut player zaten 20 saniyelik buffer tutuyor. Sonraki şarkı önceden yükleniyor. Geçişlerde takılma olmaz.

Katman 4: Retry + Fallback

Kısa internet kesintisinde player otomatik tekrar dener. HLS tamamen başarısız olursa MP3 fallback devreye girer. Hiçbir durumda sessiz kalmaz.

Maliyet ve Disk Hesabı

Disk Alanı (Production Sunucu)

Kalite Şarkı Başı 30.000 Şarkı Durum
HIGH (mevcut) ~5.5 MB ~165 GB Zaten var
MID (yeni) ~3.8 MB ~114 GB Eklenecek
LOW (yeni) ~1.9 MB ~57 GB Eklenecek
TOPLAM ~11.2 MB ~336 GB +171 GB ekleniyor

Toplam Disk

885 GB

Şu an Kullanılan

433 GB

+171 GB Sonrası Kalan

281 GB boş

Maliyet Karşılaştırması

Seçenek Aylık Tek Seferlik Kurulum Not
Kendi Sunucu + Bunny CDN ~$5 $0 %90 hazır En hızlı uygulama
Mux ~$360+ $0 Tamamen yeniden Aynı teknolojiyi kullanıyor
AWS MediaConvert + CloudFront ~$50 ~$1,800 Karmaşık Over-engineering

Neden Dış Servis Değil?

Bunny Stream & Cloudflare Stream: Audio-only dosya desteklemiyor. MP3 yüklersen hata veriyor. Sadece video.

Mux: Audio destekliyor ama aylık $360+. Aynı teknolojiyi kullanıyor (HLS + CDN). Para versen de donma çözümü aynı: adaptive bitrate.

AWS MediaConvert: Çalışır ama kurulumu karmaşık, maliyet yüksek ve mevcut AES-128 şifreleme sistemimizle uyumsuz.

Kendi sistemimiz: FFmpeg bedava, Bunny CDN kurulu ($5/ay), kod %90 hazır. Spotify ile aynı mimari. En hızlı, en ucuz, en kontrollü çözüm.

Uygulama Sırası

Faz 1

Test Sunucusunda Geliştirme (mztest.muzibu.com)

HLSService + Controller + SignedUrl kod değişiklikleri. 66 şarkı üzerinde test.

Kod yazımı
Faz 2

Production Deploy (muzibu.com)

Kod deploy + .env BUNNY_CDN_ENABLED=true + test

Deploy
Faz 3

Mevcut 30.000 Şarkıya Variant Ekleme

php artisan hls:add-variants — Horizon queue ile paralel dönüştürme

~10-15 saat
Faz 4

Cloudflare HLS Cache Kuralını Kaldırma

Bunny CDN aktif olduktan sonra Cloudflare'daki #10 HLS Audio Cache kuralını kaldır

5 dakika

Servis Araştırma Sonuçları

Servis Audio Oto. Transcoding Adaptive Token Auth AES-128 Aylık
Bunny Stream (video) ~$15
Cloudflare Stream (video) ~$5+
Mux ~$360+
AWS MediaConvert ~$50+
FFmpeg + Bunny CDN (biz) ~$5

Teknik: master.m3u8 Formatı

#EXTM3U

# Düşük kalite - yavaş internet için (64kbps, mono)
#EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.2",NAME="low"
low/playlist.m3u8

# Orta kalite - normal internet için (128kbps, stereo)
#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="mp4a.40.2",NAME="mid"
mid/playlist.m3u8

# Yüksek kalite - hızlı internet için (orijinal, stereo)
#EXT-X-STREAM-INF:BANDWIDTH=280000,CODECS="mp4a.40.2",NAME="high"
playlist.m3u8

HLS.js bu dosyayı okuyunca 3 kaliteyi görür ve bant genişliğine göre otomatik seçim yapar. BANDWIDTH değeri bps (bit per second) cinsindendir.