🎵 Muzibu Player - Refactor & Optimization Plan

📅 Tarih: 2025-11-28 | 🎯 Mevcut Durum: %68 Complete | 👤 Focus: Player Code Quality & Security

✅ ZATEN ÇALIŞAN ÖZELLİKLER

Howler.js 2.2.4, HLS.js Streaming, Crossfade (6s/1s), Queue Management, Volume Control, Repeat/Shuffle, Responsive Design, 30s Preview, Premium System - TÜM CORE ÖZELLİKLER AKTİF!

⚠️ ANA PROBLEM

player.blade.php = 2,685 satır monolithic kod! İyileştirme değil, MODÜLER REFACTOR gerekiyor.

Stream endpoint güvenliksiz! Herkes konsol ile şarkı indirebilir.

📋 İŞ PLANI - 3 FAZ

🔴 FAZ 1: CODE REFACTORING (ÖNCELİKLİ)

CRITICAL

Amaç: 2,685 satırlık player.blade.php'yi modüler hale getir

1.1 - Mevcut Kod Yapısı Analizi

Dosya: resources/views/themes/muzibu/player.blade.php

Satır Aralığı İçerik Satır Sayısı Hedef Dosya
1-380 Auth Modal (Login/Register) ~380 components/auth-modal.blade.php
383-476 Player UI Bar ~93 components/player-bar.blade.php
478-567 Queue Panel ~89 components/queue-panel.blade.php
570-1080 CSS Styles ~510 css/player.css
1082-2685 JavaScript ~1,603 js/player/*.js (modüler)

1.2 - Yeni Modüler Yapı

Hedef Klasör Yapısı:

public/themes/muzibu/js/player/
├── core/
│   ├── audio-engine.js         # Howler.js + HLS.js wrapper
│   ├── crossfade.js            # Crossfade logic
│   └── stream-security.js      # Token + signed URL
├── features/
│   ├── queue-manager.js        # Queue operations
│   ├── favorites.js            # Like/unlike
│   ├── volume-control.js       # Volume + mute
│   ├── repeat-shuffle.js       # Repeat/shuffle modes
│   └── spa-navigation.js       # History API
├── ui/
│   ├── player-ui.js            # Progress bar, buttons
│   ├── queue-ui.js             # Drag & drop
│   └── modals.js               # Auth, limits modals
└── utils/
    ├── api-client.js           # Fetch wrapper
    ├── formatters.js           # Time, duration
    └── debounce.js             # Performance utils

1.3 - Alpine.js Store Kurulumu

Modüller arası state paylaşımı için merkezi store

// public/themes/muzibu/js/player-store.js
document.addEventListener('alpine:init', () => {
    Alpine.store('player', {
        // Audio state
        isPlaying: false,
        currentSong: null,
        currentTime: 0,
        duration: 0,
        volume: 0.8,
        isMuted: false,

        // Queue state
        queue: [],
        queueIndex: 0,

        // Playback state
        repeatMode: 'off', // off|all|one
        isShuffled: false,
        isCrossfading: false,

        // User state
        isLoggedIn: false,
        isPremium: false,

        // Methods (delegated to modules)
        play() { playerCore.play() },
        pause() { playerCore.pause() },
        next() { queueManager.next() },
        prev() { queueManager.prev() }
    });
});

1.4 - Howler.js + HLS.js Integration

Dosya: js/player/core/audio-engine.js

// Dual audio system - exactly as currently working
class AudioEngine {
    constructor() {
        this.howl = null;          // Current Howler instance
        this.howlNext = null;      // Next track for crossfade
        this.hlsPlayer = null;     // HLS.js instance
        this.hlsPlayerNext = null; // Next HLS for crossfade
        this.audioElement = document.getElementById('hlsAudio');
        this.audioElementNext = document.getElementById('hlsAudioNext');
    }

    // Load with automatic format detection
    async loadSong(streamUrl, streamType) {
        if (streamType === 'hls') {
            return this.loadHLS(streamUrl);
        } else {
            return this.loadHowler(streamUrl);
        }
    }

    loadHowler(url) {
        this.howl = new Howl({
            src: [url],
            html5: true,
            pool: 5,
            volume: Alpine.store('player').volume,
            onplay: () => this.onPlayCallback(),
            onend: () => this.onEndCallback(),
            onload: () => this.onLoadCallback()
        });
        return this.howl;
    }

    loadHLS(url) {
        if (!Hls.isSupported()) {
            // Safari native HLS
            this.audioElement.src = url;
            return;
        }

        this.hlsPlayer = new Hls({
            enableWorker: true,
            lowLatencyMode: false
        });

        this.hlsPlayer.loadSource(url);
        this.hlsPlayer.attachMedia(this.audioElement);
    }

    // Crossfade to next track
    crossfade(nextUrl, nextType, duration = 6000) {
        // Implementation matches current crossfade logic
    }
}

1.5 - Blade Component Breakdown

Strategy: Auth modal zaten ayrıldı, diğerleri de ayrılacak

Component Yeni Dosya Status
Auth Modal components/auth-modal.blade.php ✅ ZATEN AYRI
Player Bar components/player-bar.blade.php 🔄 YAPILACAK
Queue Panel components/queue-panel.blade.php 🔄 YAPILACAK
Player CSS css/player.css 🔄 YAPILACAK

🟠 FAZ 2: SECURITY IMPLEMENTATION

HIGH PRIORITY

Problem: `/api/muzibu/songs/{id}/stream` endpoint açık - konsol ile şarkı indirme mümkün!

2.1 - Bearer Token Authentication

Dosya: SongStreamController.php

// Laravel Sanctum token generation
Route::middleware(['auth:sanctum'])->group(function() {
    Route::get('/songs/{id}/stream', [SongStreamController::class, 'stream']);
});

// Frontend: Add token to requests
fetch(`/api/muzibu/songs/${songId}/stream`, {
    headers: {
        'Authorization': `Bearer ${window.userToken}`,
        'X-Requested-With': 'XMLHttpRequest'
    }
});

2.2 - Signed URLs (HMAC-SHA256)

URL'ler 5 dakika sonra expire olacak, IP-bound

// Backend - generate signed URL
public function generateSignedStreamUrl($songId, $userId) {
    $timestamp = time();
    $ipAddress = request()->ip();
    $secret = config('app.stream_secret');

    $signature = hash_hmac('sha256',
        "{$songId}:{$userId}:{$timestamp}:{$ipAddress}",
        $secret
    );

    return url("/api/muzibu/songs/{$songId}/stream?" . http_build_query([
        't' => $timestamp,
        'u' => $userId,
        's' => $signature
    ]));
}

// Frontend kullanımı
const signedUrl = await fetch(`/api/muzibu/songs/${songId}/signed-url`).json();
audioEngine.loadSong(signedUrl.url, signedUrl.type);

2.3 - Rate Limiting

IP bazlı throttling: 60 request/minute

// routes/api.php
Route::middleware('throttle:60,1')->group(function() {
    Route::get('/songs/{id}/stream', ...);
    Route::post('/songs/{id}/track-progress', ...);
});

2.4 - HLS + AES-128 Encryption (İleri Seviye)

Segment şifreleme, dynamic key rotation

// FFmpeg HLS conversion with encryption
ffmpeg -i input.mp3 \
  -hls_key_info_file keyinfo.txt \
  -hls_time 10 \
  -hls_list_size 0 \
  -hls_segment_filename 'segment_%03d.ts' \
  output.m3u8

// keyinfo.txt format:
// key_url
// key_file_path
// initialization_vector

Not: Bu advanced feature, optional olabilir.

🟡 FAZ 3: ENHANCEMENT FEATURES

MEDIUM PRIORITY

Player experience iyileştirmeleri (optional)

3.1 - WaveSurfer.js Integration

Real-time waveform visualization

// js/player/features/waveform.js
import WaveSurfer from 'wavesurfer.js';

const wavesurfer = WaveSurfer.create({
    container: '#waveform',
    waveColor: '#1db954',
    progressColor: '#ffffff',
    height: 80,
    responsive: true
});

// Sync with Howler.js
howl.on('play', () => wavesurfer.play());
howl.on('pause', () => wavesurfer.pause());
howl.on('seek', (pos) => wavesurfer.seekTo(pos));

3.2 - Dynamic Theme (Color Thief)

Album art'tan renk çıkarma

// Backend precalculation
use ColorThief\ColorThief;

$dominantColor = ColorThief::getColor($albumCoverPath);
$palette = ColorThief::getPalette($albumCoverPath, 5);

// DB'ye kaydet
$song->update([
    'theme_color' => "rgb({$dominantColor[0]}, {$dominantColor[1]}, {$dominantColor[2]})"
]);

// Frontend kullanımı
document.body.style.setProperty('--player-accent', song.theme_color);

3.3 - 10-Band Equalizer (Premium Feature)

Web Audio API ile profesyonel EQ

class Equalizer {
    constructor(audioContext) {
        this.context = audioContext;
        this.bands = [60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000];
        this.filters = this.createFilters();
    }

    createFilters() {
        return this.bands.map((freq, i) => {
            const filter = this.context.createBiquadFilter();
            filter.type = (i === 0) ? 'lowshelf' :
                         (i === this.bands.length - 1) ? 'highshelf' :
                         'peaking';
            filter.frequency.value = freq;
            filter.Q.value = 1;
            filter.gain.value = 0;
            return filter;
        });
    }

    setBand(index, gain) {
        this.filters[index].gain.value = gain;
    }
}

🎯 İMPLEMENTATION ROADMAP

Faz Task Estimated Time Priority
1 Mevcut player.blade.php analizi 30 min CRITICAL
1 Alpine Store kurulumu 1 hour CRITICAL
1 audio-engine.js extraction 2 hours CRITICAL
1 queue-manager.js extraction 1.5 hours CRITICAL
1 Diğer modüllerin extraction'ı 3 hours CRITICAL
1 Blade componentlere ayırma 2 hours HIGH
1 CSS dosyasına taşıma 1 hour HIGH
2 Bearer token authentication 1 hour HIGH
2 Signed URLs implementation 2 hours HIGH
2 Rate limiting setup 30 min HIGH
2 HLS AES-128 encryption 4 hours MEDIUM
3 WaveSurfer.js integration 2 hours MEDIUM
3 Color Thief theme system 1.5 hours MEDIUM
3 10-band equalizer 3 hours LOW

Total Estimated Time: ~24 hours

📝 ÖNEMLI NOTLAR

⚠️ DİKKAT EDİLMESİ GEREKENLER

  • Hiçbir migration oluşturma! Mevcut sistem çalışıyor, sadece kod düzenlemesi yapılacak
  • Users tablosuna dokunma! Universal tablo, tenant-aware değil
  • Mevcut özellikler bozulmamalı! Howler.js + HLS.js + Crossfade çalışıyor, sadece refactor
  • player.blade.php yedeğini al! 2,685 satır kodu parçalayacağız
  • Tenant 1001 kontrolü: Tüm yeni features sadece muzibu.com için

✅ İLKELER

  • Modüler kod: Her modül tek bir sorumluluğa sahip
  • Alpine.js Store: Merkezi state yönetimi
  • Progressive Enhancement: Eski tarayıcılar için fallback
  • Performance: Debounce, throttle, lazy loading kullan
  • Security First: Token + Signed URL + Rate Limit

🚀 BAŞLANGIÇ STRATEJİSİ

Adım 1: Git Checkpoint

git add .
git commit -m "🔧 CHECKPOINT: Before player refactoring (2,685 lines → modular)"

Adım 2: Klasör Yapısı Oluştur

mkdir -p public/themes/muzibu/js/player/{core,features,ui,utils}
mkdir -p public/themes/muzibu/css/player/
mkdir -p resources/views/themes/muzibu/components/player/

Adım 3: Alpine Store Kur

// player-store.js oluştur ve app.blade.php'ye ekle
<script src="{{ asset('themes/muzibu/js/player-store.js') }}"></script>

Adım 4: İlk Modülü Çıkar (audio-engine.js)

En kritik kısım - Howler.js + HLS.js logic

Adım 5: Test Et!

// Kontrol listesi:
✓ Şarkı çalıyor mu?
✓ Crossfade çalışıyor mu?
✓ Queue next/prev çalışıyor mu?
✓ Volume control çalışıyor mu?
✓ Repeat/shuffle çalışıyor mu?