🎵 Muzibu Kullanıcı & Müzik Dinleme Sistemi

📅 Tarih: 2025-12-04 15:30
🎯 Tenant: 1001 (muzibu.com)
👤 Talep: Sistem çalışma mantığı analizi

📊 Sistem Genel Bakış

Muzibu, tenant 1001 üzerinde çalışan bir müzik streaming platformudur. Sistem, 3 farklı kullanıcı tipi için farklı dinleme deneyimleri sunar:

  • 👥 Üye Olmayan (Guest): Kayıt olmadan müzik keşfi
  • 🔐 Üye (Normal Member): Kayıtlı hesap ile sınırlı dinleme
  • Premium Üye: Aktif abonelik ile sınırsız dinleme

💡 Önemli Bilgi

Sistem, User modelindeki isPremium() metodu ile kullanıcının premium durumunu kontrol eder. Bu method, subscriptions tablosunda aktif bir abonelik olup olmadığını sorgualar.

👥 Kullanıcı Tipleri ve Yetkiler

👤 Üye Olmayan (Guest) Misafir

Tanım: Kayıt olmadan siteye erişen ziyaretçiler. Authentication sistemi ile ilişkilendirilmemiş kullanıcılar.

Dinleme Hakları:

  • ⏱️ 30 saniye önizleme: Her şarkıdan sadece ilk 30 saniye dinlenebilir
  • 🔒 Tam dinleme yok: Şarkıyı sonuna kadar dinleyemez
  • 🎧 Sınırsız önizleme: İstediği kadar farklı şarkıyı 30 saniye önizleyebilir
  • Analytics kaydı yok: Dinleme geçmişi tutulmaz

Frontend Davranışı:

1
Şarkı başlar ve 30 saniye oynar
2
30. saniyede player otomatik durur
3
Ekranda mesaj gösterilir: "Kayıt olun, tam dinleyin"

⚠️ Backend Kontrolü

SongStreamController::stream() methodu, auth()->user() kontrolü yapar. Guest için null döner ve status: preview response döndürür.

🔐 Üye (Normal Member) Kayıtlı

Tanım: Kayıt olmuş ancak premium aboneliği olmayan kullanıcılar. Email/şifre ile giriş yapmış durumda.

Dinleme Hakları:

  • ⏱️ 30 saniye önizleme: Guest ile aynı - tam dinleme hakkı yok
  • 📊 Analytics kaydı: Dinleme geçmişi muzibu_song_plays tablosunda tutulur
  • Favoriler: Şarkıları favorilere ekleyebilir
  • 🎵 Playlist oluşturma: Kendi playlist'lerini oluşturabilir

💡 Eski Kural (Şu An Devre Dışı)

Eskiden günde 3 şarkı limiti vardı. Kullanıcı 60+ saniye dinlediği her şarkı sayılırdı. Bu kural SongStreamController içinde comment out edilmiş durumda.

canPlaySong() ve getRemainingPlays() methodları hala mevcut ancak kullanılmıyor. Backend şu an tüm üyelere 30 saniye preview veriyor.

Frontend Davranışı:

1
Şarkı başlar ve 30 saniye oynar
2
30. saniyede player otomatik durur
3
Ekranda mesaj gösterilir: "Premium'a geçin, sınırsız dinleyin"

⭐ Premium Üye Premium Trial

Tanım: Aktif subscription olan kullanıcılar. İki tip premium durumu var:

Premium Tipleri:

  • 💳 Active Subscription: status = 'active' ve ends_at > now()
  • 🎁 Trial Period: status = 'trial' ve trial_ends_at > now()

Dinleme Hakları:

  • 🎵 Sınırsız dinleme: Tüm şarkıları sonuna kadar dinleyebilir
  • 🚀 Yüksek kalite HLS stream: Adaptif bitrate ile kesintisiz deneyim
  • 📊 Detaylı analytics: Dinleme geçmişi tam detaylı tutulur
  • 💾 Offline dinleme: (Planlanan - şu an aktif değil)
  • Rate limit: Dakikada 300 stream request (Guest: 30, Member: 120)

Frontend Davranışı:

1
Şarkı başlar ve sonuna kadar oynar
2
Limit kontrolü yok - sınırsız dinleme
3
Şarkı bittiğinde otomatik sıradaki şarkıya geçer

💡 Premium Kontrolü

User::isPremium() methodu, 1 saatlik cache ile optimize edilmiş. Her stream request'inde database'ye gitmeden cache'den kontrol eder. Bu sayede performans optimize edilmiş.

📊 Kullanıcı Karşılaştırma Tablosu

Özellik 👤 Guest 🔐 Üye ⭐ Premium
Tam Dinleme 30 saniye 30 saniye Sınırsız
Analytics Kayıt yok Kayıt var Detaylı
Favoriler
Playlist Oluşturma
Günlük Limit Sınırsız preview Sınırsız preview Sınırsız
Stream Kalitesi MP3 (standart) MP3 (standart) HLS (adaptif)
Rate Limit 30 req/dakika 120 req/dakika 300 req/dakika

🔄 Müzik Dinleme Akışı

1️⃣ Stream URL Alma

1
Frontend → Backend: GET /api/muzibu/songs/{id}/stream
2
Backend: Kullanıcı tipini kontrol eder (auth()->user())
3
Backend: Premium kontrolü yapar (isPremium())
4
Response: Stream URL döner (signed URL - güvenlik için)
5
Response: preview_duration alanı ile limit bilgisi gelir (Guest/Üye için 30)

2️⃣ Müzik Çalma (Frontend)

1
Player: Stream URL ile müzik çalmaya başlar (HLS veya MP3)
2
Timer: Eğer preview_duration varsa, sayaç başlar
3
30. saniye: Guest/Üye için player otomatik durur, premium için devam eder
4
Her 5 saniyede: Progress tracking yapılır (backend'e sinyal gönderilir)

3️⃣ Analytics Kaydı

1
Frontend: 60+ saniye dinleme sonrası POST /api/muzibu/songs/{id}/track-progress çağrılır
2
Backend: muzibu_song_plays tablosuna kayıt ekler
3
Bilgiler: user_id, song_id, ip_address, device_type, created_at
4
Analytics: Daha sonra raporlama için kullanılır (en çok dinlenenler, günlük istatistik vb.)

⚠️ Önemli: Guest Kullanıcılar için Analytics Yok

Guest kullanıcılar için track-progress endpoint'i auth:sanctum middleware ile korunuyor. Guest'ler dinleme kaydı oluşturamazlar.

💳 Premium Üyelik Sistemi

Subscription Model

Premium üyelik, subscriptions tablosunda tutulur. Her subscription bir kullanıcıya (user_id) ve bir plana (plan_id) bağlıdır.

Subscription Durumları

active: Aktif abonelik - ends_at > now() kontrolü yapılır
🎁
trial: Deneme süresi - trial_ends_at > now() kontrolü yapılır
⏸️
expired: Süresi dolmuş abonelik - artık premium değil
cancelled: İptal edilmiş abonelik - artık premium değil
pending: Ödeme bekleyen abonelik - henüz aktif değil

Premium Kontrolü (isPremium Method)

Kontrol Sırası:

  1. Tenant Kontrolü: Sadece tenant 1001 (Muzibu) için çalışır, diğer tenant'lar için direkt false
  2. Cache Kontrolü: 1 saatlik cache varsa, oradan döner (performans için)
  3. Database Kontrolü: subscriptions tablosunda status = 'active' ve ends_at > now() sorgusu
  4. Fallback: Eski sistem için is_premium kolonu kontrolü (artık kullanılmıyor)

⚠️ Cache Sistemi

Premium kontrolü, her stream request'inde çağrıldığı için 1 saatlik cache kullanılıyor. Bu sayede database yükü azaltılıyor. Ancak bu, kullanıcı premium'a geçtikten sonra en fazla 1 saat gecikmeli güncelleme olabileceği anlamına gelir.

Çözüm: Subscription oluşturulunca/güncellenince cache temizlenir.

🎧 Müzik Stream Teknolojisi

HLS (HTTP Live Streaming)

Premium kullanıcılar için HLS streaming kullanılır. HLS, müzik dosyasını küçük parçalara böler ve adaptif bitrate ile kullanıcıya sunar. Bu sayede:

  • 📶 Adaptif kalite: İnternet hızına göre otomatik kalite ayarı
  • Hızlı başlangıç: Tüm dosya indirilmeden müzik başlar
  • 🔒 Güvenlik: Dosya direkt indirilemez, sadece stream edilir
  • 💾 Düşük bant genişliği: Sadece oynatılan kısım indirilir

MP3 Direct Stream

Guest ve normal üyeler için MP3 direct stream kullanılır. Basit HTTP stream ile müzik servis edilir. Frontend, 30. saniyede otomatik durdurur.

Lazy HLS Conversion

1
Şarkı ilk kez çalınmak istendiğinde, HLS'e dönüşmemiş mi kontrol edilir
2
Eğer dönüşmemişse, ConvertToHLSJob queue'ya eklenir
3
Kullanıcıya geçici olarak MP3 stream URL döndürülür
4
Job arka planda çalışır, FFmpeg ile şarkıyı HLS'e çevirir
5
Dönüşüm tamamlandıktan sonra, hls_converted = true işaretlenir
6
Bir sonraki çalışta HLS URL döndürülür

💡 Neden Lazy Loading?

Tüm şarkıları önceden HLS'e çevirmek hem disk alanı hem de işlemci açısından maliyetli. Lazy loading sayesinde, sadece gerçekten dinlenen şarkılar dönüştürülür.

🔐 Güvenlik & Rate Limiting

Signed URLs

Tüm stream URL'leri SignedUrlService ile imzalanır. Bu sayede:

  • 🔒 Tahmin edilemezlik: URL'ler hash içerir, tahmin edilemez
  • ⏱️ Zamanlı geçerlilik: URL'ler belirli süre sonra geçersiz olur (MP3: 30dk, HLS: 60dk)
  • 🚫 Kopyalanamaz: URL kopyalanıp paylaşılsa bile, süre dolunca geçersiz olur

Rate Limiting (throttle.user:stream)

Kullanıcı Tipi Request Limiti Açıklama
👤 Guest 30 req/dakika Bot koruması ve sunucu yükünü azaltma
🔐 Üye 120 req/dakika Normal kullanım için yeterli
⭐ Premium 300 req/dakika Yüksek kalite stream için yeterli

⚠️ Rate Limit Aşımı

Kullanıcı rate limit'i aşarsa, 429 Too Many Requests hatası döner. Frontend, bu durumda kullanıcıya uygun mesaj gösterir ve 1 dakika bekler.