PC Çalışması (P2-10/11/12) + Safari iOS Sorunları + Geçiş Planı
23 Mart 2026 • v2
Müzik dosyalarını (HLS + MP3) Bunny CDN üzerinden sunarak:
Safari iOS'un native HLS player'ı farklı domain'e (bizim sunucu) istek atarken cookie göndermiyor. Playlist Bunny'de, şifreleme anahtarı bizde → 401 Unauthorized hatası.
Durum: ❌ Çözülemedi (blob URL da desteklenmiyor)
Hls.isSupported() = false — Safari iOS kendi native player'ını kullanıyor.
CachingKeyLoader devreye giremiyor, inline key cache'i kullanılamıyor.
Çözüm: Safari iOS için MP3 fallback (test edilecek)
Bunny'ye sadece HLS dosyaları yüklendi. Safari iOS fallback için MP3'ler de lazım. 40K+ şarkının MP3 versiyonları yüklenecek.
Durum: ⏳ Yükleme devam edecek
enc.key dosyaları Bunny'ye yüklenemez (public olur, güvenlik riski). Key her zaman bizim sunucudan gelmeli, auth kontrolü şart.
Karar: Anahtarlar local'da kalacak
Bunny CDN local mod'da — tüm müzikler kendi sunucumuzdan çalıyor. PC ve mobil dahil her yerde sorunsuz çalışıyor.
Ne yapıldı? HLS müzik çalma sistemi optimize edildi. Şarkı başlatma süresi 4 HTTP isteğinden 1'e düşürüldü.
Nasıl? Master playlist, şifreleme anahtarı ve variant playlist'ler ilk API yanıtına gömüldü (inline).
Bunny CDN? Müzik dosyalarını CDN'den sunmak için entegre edildi ama Safari iOS sorunu çıktı.
Şu an? PC'de her şey çalışıyor. Bunny şu an kapalı (local mod), Safari sorunu çözülünce açılacak.
┌─────────────────────────────────────────────────────────────┐
│ Şarkı Başlatma (4 HTTP Round-Trip) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. /api/songs/{id}/stream ─────► stream_url al │
│ 2. master.m3u8 ─────► variant listesi al │
│ 3. playlist.m3u8 ─────► segment listesi al │
│ 4. /hls-key/{id} ─────► şifre anahtarı al │
│ 5. segment-000.ts ─────► ilk segment (çalmaya │
│ başla) │
│ │
│ Toplam: ~400-600ms gecikme │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Şarkı Başlatma (1 HTTP + Inline Data) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. /api/songs/{id}/stream ─────► HER ŞEY BİRDEN: │
│ { │
│ "stream_url": "...", │
│ "master_inline": "#EXTM3U...", ← P2-10 │
│ "key_inline": "base64...", ← P2-11 │
│ "playlists_inline": { ← P2-12 │
│ "playlist_32.m3u8": "...", │
│ "playlist_64.m3u8": "...", │
│ "playlist_128.m3u8": "...", │
│ "playlist.m3u8": "..." │
│ } │
│ } │
│ │
│ 2. segment-000.ts ─────► ilk segment (çalmaya │
│ başla) │
│ │
│ Toplam: ~100-150ms gecikme (4x hızlanma!) │
└─────────────────────────────────────────────────────────────┘
master.m3u8 içeriği API yanıtına gömülü. Blob URL oluşturulup HLS.js'e veriliyor.
master_inline: "#EXTM3U..."
AES-128 şifreleme anahtarı base64 olarak gömülü. _hlsKeyCache'e yazılıyor.
key_inline: "base64..."
Tüm variant playlist'ler (32k, 64k, 128k, orig) gömülü. _hlsPlaylistCache'e yazılıyor.
playlists_inline: {...}
HLS.js'in varsayılan loader'ı override edildi. Key ve playlist istekleri önce cache'e bakıyor:
class CachingKeyLoader extends Hls.DefaultConfig.loader {
load(context, config, callbacks) {
// 1. Key isteği mi?
if (context.type === 'key') {
var cachedKey = _hlsKeyCache[normalizedUrl];
if (cachedKey) {
console.log('🔑 Key served from CACHE (0ms)');
callbacks.onSuccess(...); // Anında dön
return;
}
}
// 2. Playlist isteği mi?
if (context.url.includes('.m3u8')) {
var cachedPlaylist = _hlsPlaylistCache[url];
if (cachedPlaylist) {
console.log('📋 P2-12: Playlist served from cache (0ms)');
callbacks.onSuccess(...); // Anında dön
return;
}
}
// 3. Cache'de yoksa normal HTTP isteği
super.load(context, config, callbacks);
}
}
🔑 P2-11 DIRECT: Key inline → cache (16 bytes, song: 23390) 🚀 P2-10: master.m3u8 inline blob kullanıldı 📋 P2-12: 4 playlist inline → cache 🔄 HlsPool.acquire: 4 tid=4 → 3i / 1a 🔍 CachingKeyLoader.load() CALLED: manifest text blob:... 🔍 CachingKeyLoader.load() CALLED: level text playlist.m3u8 📋 P2-12: Playlist served from cache (0ms) 🔑 Key served from CACHE (0ms, 16 bytes) ✅ Şarkı çalıyor!
┌─────────────────────────────────────────────────────────────┐
│ Bunny Hybrid Serving │
├─────────────────────────────────────────────────────────────┤
│ │
│ Redis Set: bunny:uploaded_songs │
│ ├── 23390 (Bunny'de var) │
│ ├── 22287 (Bunny'de var) │
│ └── ... │
│ │
│ SignedUrlService.generateHlsUrl($songId): │
│ ├── Redis.sismember('bunny:uploaded_songs', $songId) │
│ ├── TRUE → https://muzibu-audio-cdn.b-cdn.net/hls/... │
│ └── FALSE → https://www.muzibu.com/hls/muzibu/songs/... │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐ │ Safari iOS'ta HLS Key Hatası │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Safari iOS: Hls.isSupported() = FALSE │ │ → HLS.js çalışmıyor, CachingKeyLoader devrede değil │ │ → Safari kendi native HLS player'ını kullanıyor │ │ │ │ Playlist: muzibu-audio-cdn.b-cdn.net (Bunny) │ │ Key: www.muzibu.com/hls-key/ (Bizim sunucu) │ │ │ │ Cross-origin istek → Safari cookie göndermiyor → 401 │ │ │ └─────────────────────────────────────────────────────────────┘
[Log] 🔍 HLS PATH DEBUG: Hls.isSupported()= false canPlayType= maybe
[Log] 🍎 HLS PATH: Using Safari NATIVE HLS (not HLS.js!)
[Error] Failed to load resource: 401 Unauthorized
https://www.muzibu.com/hls-key/muzibu/songs/23390
1. Session Middleware
Safari cross-origin'de cookie göndermiyor, session işe yaramaz.
2. Blob URL + Data URI Key
Safari native HLS blob:// URL desteklemiyor. "NotSupportedError"
3. Safari iOS için MP3 Fallback
Safari iOS tespit → ?force_mp3=1 → MP3 URL dön. Muhtemelen çalışır.
4. Bunny'ye enc.key Yükleme
Güvenlik riski - anahtarlar public olmamalı.
5. Playlist'leri Yeniden Encode
40K+ şarkı var, çok uzun sürer.
BUNNY_STORAGE_ENABLED=true BUNNY_STORAGE_MODE=local ← Şu an LOCAL BUNNY_FALLBACK_TO_LOCAL=true
MP3 Yükleme Tamamla
php artisan bunny:migrate --type=mp3 --batch=100
Safari iOS MP3 Fallback Ekle
// player-core.js
var isSafariIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) &&
/Safari/.test(navigator.userAgent) &&
!navigator.userAgent.includes('CriOS');
if (isSafariIOS) _streamUrl += '?force_mp3=1';
// SongController.php
if ($request->has('force_mp3')) {
return MP3_URL;
}
Local Mode'da Test
Safari iOS'ta MP3 fallback çalışıyor mu kontrol et
Hybrid Moda Geç
# .env BUNNY_STORAGE_MODE=hybrid # Cache temizle php artisan config:cache && php artisan cache:clear
Tüm Cihazlarda Test
| Chrome/Firefox/Edge | → HLS from Bunny |
| Safari macOS | → HLS from Bunny + Local Key |
| Safari iOS | → MP3 from Bunny (fallback) |
| Android | → HLS from Bunny |
# .env BUNNY_STORAGE_MODE=local # Cache temizle php artisan config:cache
eb0acb8ff 23 Mar 05:XX 🔙 Safari iOS denemelerini geri al + Bunny local moda 83d1043bd 23 Mar 05:XX 🍎 Safari iOS HLS Denemeleri (HATALI) f2ef4bcbd 22 Mar 22:56 🐰 Bunny Hybrid Serving + Redis Tracking b489ec4fa 22 Mar 22:41 🐰 Bunny Migration optimizasyonları 55ff250f8 21 Mar 00:27 🐰 Bunny Storage Zone entegrasyonu 6b7340e26 01 Mar 21:19 🚀 P2-10/11/12 inline + HLS iyileştirmeleri 9af2f34e4 01 Mar 01:42 🔧 Fast-start + Hover preload + Rebuffer fix