composer require tonymans33/video-optimizer
php artisan vendor:publish --provider="TonyMans33\VideoOptimizer\VideoOptimizerServiceProvider" --tag="video-optimizer-config"
.env:
FFMPEG_BINARY=/usr/bin/ffmpeg
FFMPEG_FFMPEG_PATH=/usr/bin/ffmpeg
FFMPEG_FFPROBE_PATH=/usr/bin/ffprobe
config/video-optimizer.php:
'enabled' => env('VIDEO_OPTIMIZER_ENABLED', true),
Add the OptimizeVideo trait to your Filament resource or form component:
use TonyMans33\VideoOptimizer\Traits\OptimizeVideo;
class VideoResource extends Resource
{
use OptimizeVideo;
// ...
}
Now, videos uploaded via Filament forms will automatically be optimized before saving.
use Filament\Forms\Components\FileUpload;
use TonyMans33\VideoOptimizer\Traits\OptimizeVideo;
class VideoForm
{
use OptimizeVideo;
public function form(Form $form): Form
{
return $form
->schema([
FileUpload::make('video')
->label('Upload Video')
->image()
->imagePreviewHeight('200'),
]);
}
}
use Spatie\MediaLibrary\HasMedia;
use TonyMans33\VideoOptimizer\Traits\OptimizeSpatieMedia;
class VideoModel extends Model implements HasMedia
{
use OptimizeSpatieMedia;
// ...
}
Override defaults in config/video-optimizer.php:
'formats' => [
'webm' => [
'enabled' => true,
'quality' => 'medium', // low, medium, high
'crf' => 28, // Custom CRF value (overrides quality if set)
],
'mp4' => [
'enabled' => false,
'quality' => 'high',
],
],
use TonyMans33\VideoOptimizer\Facades\VideoOptimizer;
$optimizedPath = VideoOptimizer::optimize(
$originalPath,
'webm',
'high'
);
Check if optimization succeeded:
$optimizedPath = VideoOptimizer::optimize($path, 'webm');
if ($optimizedPath->isOptimized()) {
// Success
} else {
// Fallback to original
$originalPath = $optimizedPath->getOriginalPath();
}
For large files, offload processing to a queue:
use TonyMans33\VideoOptimizer\Jobs\OptimizeVideoJob;
OptimizeVideoJob::dispatch($originalPath, 'webm', 'medium')
->onQueue('optimizations');
FFmpeg Not Installed:
FFmpegNotFoundException..env. Verify with:
ffmpeg -version
php artisan video-optimizer:check to validate setup.File Size Limits:
max_execution_time and memory_limit or use queueing.Unsupported Formats:
'allowed_extensions' => ['mp4', 'mov', 'avi', 'mkv'],
Filament Caching Issues:
php artisan filament:cache-clear
Log FFmpeg Output:
Enable verbose logging in config/video-optimizer.php:
'debug' => true,
Check logs at storage/logs/laravel.log.
Test Locally: Use Docker or a local FFmpeg setup to replicate production:
docker run --rm -it jrottenberg/ffmpeg
Validate Config: Run the config validator:
php artisan video-optimizer:validate
Custom FFmpeg Commands: Override the default command builder in a service provider:
VideoOptimizer::extend(function ($optimizer) {
$optimizer->setCustomCommand(function ($path, $format, $quality) {
return "ffmpeg -i {$path} -c:v libvpx-vp9 -b:v 1M -c:a libopus output.{$format}";
});
});
Post-Optimization Hooks: Add callbacks for post-processing:
'hooks' => [
'after_optimize' => function ($originalPath, $optimizedPath, $format) {
// Example: Generate thumbnails
ThumbnailGenerator::generate($optimizedPath);
},
],
Dynamic Quality Settings: Pass dynamic quality settings per upload:
FileUpload::make('video')
->extraAttributes([
'data-video-quality' => 'high',
]),
Then access in a custom optimizer:
$quality = $request->input('data.video_quality', 'medium');
optimized_videos) and cache their paths.foreach ($videos as $video) {
OptimizeVideoJob::dispatch($video->path)->delay(now()->addMinutes(1));
}
How can I help you explore Laravel packages today?