📋 Planlama 🎨 Leonardo AI

Muzibu Leonardo AI Görsel Üretim Entegrasyonu

📅 24 Aralık 2025 | Tenant 1001 (muzibu.com) | Müzik Platformu

📝 Basit Anlatım (Herkes İçin)

Ne Yapacağız?

Muzibu müzik platformunda kullanıcılar yeni playlist oluşturduğunda, şarkı yüklediklerinde veya albüm oluşturduklarında artık yapay zeka otomatik olarak profesyonel kapak görselleri üretecek.

🎯 Kullanıcı Deneyimi:

  • ✅ Playlist oluştur → Yapay zeka otomatik kapak tasarla
  • ✅ Şarkı yükle (görsel yoksa) → Yapay zeka kapak oluştur
  • ✅ Toplu şarkı yükle → Her şarkı için otomatik görsel
  • ⭐ Genre/Sektor/Album/Radio (tercihen) → Görsel yüklenmediyse AI üret

Neden Önemli?

  • 🎨 Profesyonel Görünüm: Her playlist ve şarkının kendine özgü kapak görseli olur
  • Zaman Tasarrufu: Kullanıcılar manuel görsel aramak zorunda kalmaz
  • 🎯 Tutarlılık: Tüm görseller aynı kalite standardında olur
  • 🚀 Kullanıcı Deneyimi: Platform daha modern ve profesyonel görünür

💡 Nasıl Çalışıyor?

Leonardo AI (yapay zeka görsel üretim servisi) playlist/şarkı adına göre otomatik olarak müzik temalı, sinematik, profesyonel görsel oluşturur. Sistem arka planda çalışır, kullanıcı hiçbir şey yapmasına gerek kalmadan görseller hazır olur.

🔧 Teknik Detaylar (Geliştiriciler İçin)

Mevcut Sistem Durumu:

  • LeonardoAIService mevccut (Blog AI için kullanılıyor)
  • GeneratePlaylistCover Job ZATEN VAR ama kullanılmıyor
  • AIPromptEnhancer 11 Altın Kural mevcut
  • MediaLibraryItem tenant-aware çalışıyor
  • ❌ Personal playlist create → Leonardo dispatch YOK
  • ❌ Song create → Media yoksa Leonardo YOK
  • ❌ Album bulk upload → Leonardo YOK

Etkilenen Dosyalar:

🔥 ZORUNLU (Her zaman Leonardo)

  • 📁 Modules/Muzibu/app/Services/PlaylistService.php
  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/SongManageComponent.php
  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/AlbumBulkUploadComponent.php
  • 📁 Modules/Muzibu/app/Jobs/GeneratePlaylistCover.php (mevcut)

⭐ TERCİHEN (Media yoksa)

  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/GenreManageComponent.php
  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/SectorManageComponent.php
  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/AlbumManageComponent.php
  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/RadioManageComponent.php
  • 📁 Modules/Muzibu/app/Http/Livewire/Admin/PlaylistManageComponent.php

Leonardo AI Prompt Stratejisi:

  • 🎼 Playlist: Dinamik tema algılama (Rock → Elektrik gitar, Jazz → Saksafon, Klasik → Orkestra)
  • 🎵 Song: Şarkı adı + Sanatçı + Tür kombinasyonu
  • 💿 Album: Albüm adı + Sanatçı + Tema
  • 🎸 Genre: Türe özgü enstrüman ve atmosfer
  • 🏢 Sektor: İş kolu teması (Ofis → Modern, Cafe → Rahat)
  • 📻 Radio: Radyo teması + Frekans görünümü

📊 Mevcut Durum Analizi

✅ Blog AI (Referans - Çalışıyor)

  • BlogAIContentWriter::generateBlogFromDraft()
  • • Leonardo AI ile görsel üretiyor
  • AIPromptEnhancer kullanıyor (11 Altın Kural)
  • MediaLibraryItem oluşturuyor
  • • Blog'a media_id atanıyor
  • • Queue: ai-supervisor

❌ Playlist (Eksik)

  • PlaylistService::createPlaylistWithSongs()
  • • RAW SQL ile playlist oluşturuyor
  • GeneratePlaylistCover Job VAR ama dispatch edilmiyor!
  • media_id field boş kalıyor
  • • Kullanıcı manuel görsel yüklüyor

❌ Song Create (Eksik)

  • SongManageComponent::save()
  • • Eloquent ile Song oluşturuyor
  • media_id field var ama kullanılmıyor
  • • HLS conversion dispatch ediliyor ama Leonardo YOK
  • • Kullanıcı görsel seçmezse boş kalıyor

❌ Album Bulk Upload (Eksik)

  • AlbumBulkUploadComponent::startUpload()
  • • Her dosya için Song oluşturuyor (loop)
  • • Leonardo entegrasyonu YOK
  • • Toplu şarkılar görsel olmadan kalıyor

🎯 Entegrasyon Planı

1 Kişisel Playlist Leonardo Entegrasyonu

📍 Nerede: PlaylistService.php

Metod: createPlaylistWithSongs()

// Playlist oluşturulduktan sonra (satır ~245)
if ($playlist) {
    // Leonardo AI Job dispatch et
    GeneratePlaylistCover::dispatch(
        $playlist->playlist_id,
        $data['title'],
        null, // songTitle
        null, // artistName
        $userId,
        tenant('id')
    );

    Log::info('🎨 Playlist Leonardo job dispatched', [
        'playlist_id' => $playlist->playlist_id
    ]);
}

🔄 Job İşlemi:

  • • Job: GeneratePlaylistCover (ZATEN MEVCUT!)
  • • Queue: muzibu_my_playlist
  • • Timeout: 180 saniye
  • • Leonardo ile görsel üret → MediaLibraryItem oluştur → Playlist'e ata
  • • AI credit düş (1 kredi)

2 Song Create Leonardo Entegrasyonu

📍 Nerede: SongManageComponent.php

Metod: save() (satır ~578-594)

// Yeni song oluşturduktan sonra (satır ~594)
} else {
    $song = Song::query()->create($data);
    $this->songId = $song->song_id;
    log_activity($song, 'eklendi');

    // HLS conversion
    if ($song->file_path) {
        \Modules\Muzibu\App\Jobs\ConvertToHLSJob::dispatch($song);
    }

    // 🎨 LEONARDO AI: Media yoksa otomatik görsel üret
    if (!$song->media_id) {
        \Modules\Muzibu\App\Jobs\GenerateSongCover::dispatch(
            $song->song_id,
            $song->title,
            $song->album?->artist?->title,
            $song->genre?->title,
            tenant('id')
        );
        Log::info('🎨 Song Leonardo job dispatched', [
            'song_id' => $song->song_id
        ]);
    }

    $toast = [...];
}

⚠️ Yeni Job Gerekli:

  • • Job: GenerateSongCover (YENİ OLUŞTURULACAK!)
  • • Queue: muzibu_my_playlist
  • • Referans: GeneratePlaylistCover Job'undan kopyala
  • • Prompt: Şarkı adı + Sanatçı + Genre

3 Album Bulk Upload Leonardo Entegrasyonu

📍 Nerede: AlbumBulkUploadComponent.php

Metod: startUpload() (satır ~305 sonrası)

// Song oluşturulduktan sonra (satır ~305 sonrası)
Log::info('✅ Bulk upload - Song oluşturuldu', [...]);

// HLS conversion job'u kuyruğa ekle
\Modules\Muzibu\App\Jobs\ConvertToHLSJob::dispatch($song);

// 🎨 LEONARDO AI: Otomatik görsel üret
\Modules\Muzibu\App\Jobs\GenerateSongCover::dispatch(
    $song->song_id,
    $file['title'],
    $this->album->artist?->title,
    Genre::find($genreId)?->title,
    tenant('id')
);
Log::info('🎨 Bulk song Leonardo job dispatched', [
    'song_id' => $song->song_id
]);

$this->uploadedFiles[$index]['status'] = 'completed';

4 Genre/Sektor/Album/Radio (Tercihen - Media Yoksa)

⭐ Stratejisi:

  • • Admin panel'de save sonrası kontrol et: if (!$model->media_id)
  • • Media seçilmediyse Leonardo Job dispatch et
  • • Job: GenerateGenericMuzibyCover (universal job)
  • • Prompt parametrik: type (genre/sektor/album/radio) + title

🔧 Uygulama:

Her Livewire ManageComponent'te save() metoduna aynı pattern eklenecek. Universal job ile tüm content type'ları tek job'dan yönetilebilir.

Yapılacaklar Adım Adım

1

Playlist Leonardo Job Dispatch

Modules/Muzibu/app/Services/PlaylistService.phpcreatePlaylistWithSongs()

  • • Playlist oluşturulduktan sonra GeneratePlaylistCover::dispatch() ekle
  • • Parametreler: playlistId, title, userId, tenantId
  • • Log ekle: "Playlist Leonardo job dispatched"
2

GenerateSongCover Job Oluştur

Modules/Muzibu/app/Jobs/GenerateSongCover.php (YENİ DOSYA)

  • GeneratePlaylistCover Job'unu referans al
  • • Prompt: Şarkı adı + Sanatçı + Genre kombinasyonu
  • • Queue: muzibu_my_playlist
  • • Timeout: 180 saniye
  • • Tenant-aware: tenantId geç, tenant() restore et
3

Song Create Leonardo Dispatch

Modules/Muzibu/app/Http/Livewire/Admin/SongManageComponent.phpsave()

  • • Yeni song oluşturulduğunda (else bloğunda)
  • • Kontrol: if (!$song->media_id)
  • GenerateSongCover::dispatch() ekle
  • • HLS job'dan sonra ekle
4

Album Bulk Upload Leonardo

Modules/Muzibu/app/Http/Livewire/Admin/AlbumBulkUploadComponent.phpstartUpload()

  • • Her song oluşturulduktan sonra (loop içinde)
  • • HLS job'dan sonra GenerateSongCover::dispatch() ekle
  • • Album artist ve genre bilgisini geç
5

Genre/Sektor/Album/Radio (Tercihen)

Her ManageComponentsave()

  • GenerateGenericMuzibyCover Job oluştur (universal)
  • • Save sonrası: if (!$model->media_id) kontrol et
  • • Dispatch: type + title parametreleri
  • • Prompt: Type'a göre tema farklılaştır (Genre → Enstrüman, Sektor → İş kolu)
6

Test & Debug

  • ✅ Kişisel playlist oluştur → Leonardo job kuyruğa girdi mi?
  • ✅ Horizon'da job işleniyor mu?
  • ✅ MediaLibraryItem oluşuyor mu?
  • ✅ Playlist/Song'a media_id atanıyor mu?
  • ✅ Görsel frontend'de görünüyor mu?
  • ✅ AI credit düşüyor mu?
  • ✅ Log kayıtları doğru mu?

⚠️ Dikkat Edilecek Noktalar

🚨 Tenant Context

  • • Job'lara tenant('id') geçir
  • • Job handle() başında tenancy()->initialize($this->tenantId)
  • • MediaLibraryItem tenant disk kullanıyor mu kontrol et

⚡ Queue & Timeout

  • • Queue: muzibu_my_playlist (mevcut)
  • • Timeout: 180 saniye (Leonardo wait süresi)
  • • Horizon process count: maxProcesses=2 yeterli

💰 AI Credit Kontrolü

  • • Her görsel = 1 kredi
  • • Job başında: ai_can_use_credits(1)
  • • İşlem sonrası: ai_use_credits(1, ...)
  • • Log'a provider + model bilgisi kaydet

🎨 Prompt Quality

  • AIPromptEnhancer kullan (11 Altın Kural)
  • • Dinamik tema algılama (Rock/Jazz/Klasik)
  • • Tenant context: sector='music', site_name='Muzibu'

📄 Referans Dosyalar

✅ Mevcut (Referans Al)

  • 📁 app/Services/Media/LeonardoAIService.php
  • 📁 Modules/AI/app/Services/AIPromptEnhancer.php
  • 📁 Modules/Muzibu/app/Jobs/GeneratePlaylistCover.php
  • 📁 Modules/Blog/app/Services/BlogAIContentWriter.php

🔧 Değiştirilecek

  • 📝 Modules/Muzibu/app/Services/PlaylistService.php
  • 📝 Modules/Muzibu/app/Http/Livewire/Admin/SongManageComponent.php
  • 📝 Modules/Muzibu/app/Http/Livewire/Admin/AlbumBulkUploadComponent.php