b2in/app/Console/Commands/GenerateVideoThumbnails.php
Kevin Adametz 6c6d683b9a Display CMS Optimierungen 29-05-2026
- Mediathek: Video-Vorschaubilder statt Icons (FFmpeg-Thumbnails + Backfill-Command), Kategorie "Sonstiges"
- B2in Media-Picker zeigt alle Medientypen, Typ wird automatisch erkannt; Thumbnail-Preview vor allen Medien-URL-Feldern
- B2in Marke/Footer: Footer ein/aus, Logo+Claim frei positionierbar (Ecken) mit Constraints, separate Anzeige-Schalter
- Angebote-Modul dynamisch: kein Slide-Typ mehr, einheitliches Detail-Layout mit ein-/ausblendbaren Bloecken, Logo/Brand pro Slide, Streichpreis-Option
- Player: leere Module stoppen Endlosschleife, dynamische Layout-Anpassung bei verstecktem Footer/Header
- Fix: Script-Ladereihenfolge (Livewire vor Flux), entfernte stale public/flux/flux.js, Modal-Crash beim Aktualisieren behoben

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 15:57:33 +00:00

59 lines
1.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Console\Commands;
use App\Models\DisplayMedia;
use App\Services\DisplayMediaService;
use Illuminate\Console\Command;
class GenerateVideoThumbnails extends Command
{
protected $signature = 'display-media:generate-video-thumbnails
{--force : Regenerate posters even if a thumbnail already exists}';
protected $description = 'Generate poster frames for uploaded display media videos using ffmpeg';
public function handle(DisplayMediaService $service): int
{
$query = DisplayMedia::query()
->where('type', 'video')
->where('source_type', 'upload');
if (! $this->option('force')) {
$query->whereNull('thumbnail_path');
}
$videos = $query->get();
if ($videos->isEmpty()) {
$this->info('Keine Videos zum Verarbeiten gefunden.');
return self::SUCCESS;
}
$this->info(sprintf('%d Video(s) werden verarbeitet...', $videos->count()));
$generated = 0;
$failed = 0;
foreach ($videos as $video) {
$thumbnailPath = $service->generateVideoThumbnail($video);
if ($thumbnailPath !== null) {
$video->update(['thumbnail_path' => $thumbnailPath]);
$this->line(" <info>✓</info> {$video->getDisplayName()}");
$generated++;
} else {
$this->warn("{$video->getDisplayName()} (Poster konnte nicht erzeugt werden)");
$failed++;
}
}
$this->newLine();
$this->info(sprintf('Fertig: %d erzeugt, %d fehlgeschlagen.', $generated, $failed));
return self::SUCCESS;
}
}