pbmedia/laravel-ffmpeg
Laravel 10 integration for FFmpeg via PHP-FFMpeg with seamless Laravel Filesystem/config/logging support. Create HLS (encrypted/rotating keys), thumbnails/frames, mosaics/sprites, VTT previews, watermarks, concat, multi I/O, complex filters and timelapses.
Installation:
composer require pbmedia/laravel-ffmpeg
Publish the config file:
php artisan vendor:publish --provider="PBMedia\FFMpeg\FFMpegServiceProvider" --tag="config"
Configure FFmpeg Path:
Update .env with the path to your FFmpeg binary (e.g., FFMPEG_BINARY=/usr/bin/ffmpeg).
For Windows, use FFMPEG_BINARY=C:\ffmpeg\bin\ffmpeg.exe.
First Use Case: Convert a video file to MP3:
use PBMedia\FFMpeg\Support\FFMpeg;
$ffmpeg = FFMpeg::getInstance();
$video = $ffmpeg->open('path/to/video.mp4');
$video->saveAsAudio('path/to/output.mp3');
Key Configs:
Check config/ffmpeg.php for default settings like:
timeout (default: 30 seconds)ffmpeg_binary (auto-detected or manually set)threads (default: 12)Video Processing:
$video = FFMpeg::getInstance()->open('input.mp4');
$video->filters()
->addFilter('scale', '640:480')
->save('output.avi');
$video->frame(FFProbeAnalysis::TIMECODES)->save('frame.jpg');
Audio Extraction:
$ffmpeg->open('video.mp4')->saveAsAudio('audio.mp3', ['-acodec', 'libmp3lame']);
Thumbnail Generation:
$video->getFrameAtSecond(10)->save('thumbnail.jpg');
Batch Processing: Use Laravel queues for long-running tasks:
dispatch(new ProcessVideoJob('video.mp4', 'output.mp3'));
Laravel Filesystem:
Leverage Storage::disk('public')->path() for dynamic paths:
$path = Storage::disk('public')->path('videos/' . $video->id . '.mp4');
Validation: Check if FFmpeg is available before processing:
if (!FFMpeg::getInstance()->probe('dummy.mp4')) {
throw new \Exception('FFmpeg not available');
}
Custom FFmpeg Commands:
Use the FFMpeg facade directly for advanced use cases:
$ffmpeg = FFMpeg::getInstance();
$ffmpeg->execute(['-i', 'input.mp4', '-vf', 'scale=320:240', 'output.mp4']);
Event Listeners:
Trigger events post-processing (e.g., VideoProcessed):
event(new VideoProcessed($outputPath));
FFmpeg Binary Path:
.env config.which ffmpeg (Linux/Mac) or where ffmpeg (Windows) to debug.Timeout Errors:
FFMpeg\Exceptions\FFMpegException.timeout in config/ffmpeg.php or process in chunks.Memory Limits:
Allowed memory size exhausted for large files.-threads in FFmpeg commands or increase PHP memory limit (memory_limit in php.ini).Codec Support:
.mkv).$video->save('output.mp4', ['-c:v', 'libx264', '-c:a', 'aac']);
Windows Line Endings:
/) or str_replace for paths:
$path = str_replace('\\', '/', $path);
Log FFmpeg Commands:
Enable debug mode in config/ffmpeg.php:
'debug' => env('FFMPEG_DEBUG', false),
Logs will appear in storage/logs/ffmpeg.log.
Check FFmpeg Version:
$ffmpeg = FFMpeg::getInstance();
$version = $ffmpeg->getFFmpegVersion();
Validate Input Files:
Use FFMpeg::getInstance()->probe() to verify file accessibility:
if (!$ffmpeg->probe('nonexistent.mp4')) {
Log::error('File not found or unreadable');
}
Custom Filters:
Extend the PBMedia\FFMpeg\Filters\FilterInterface for reusable filters:
class CustomFilter implements FilterInterface {
public function apply(FFMpeg $ffmpeg, $arguments) {
return $ffmpeg->execute(['-vf', 'custom_filter=' . $arguments]);
}
}
Queueable Jobs: Create a job for async processing:
class ProcessVideoJob implements ShouldQueue {
use Dispatchable, InteractsWithQueue, Queueable;
public function handle() {
$ffmpeg = FFMpeg::getInstance();
$ffmpeg->open('video.mp4')->save('output.mp4');
}
}
Service Provider Binding: Bind custom FFmpeg configurations in a service provider:
$this->app->singleton('ffmpeg', function () {
$ffmpeg = FFMpeg::getInstance();
$ffmpeg->setTimeout(60); // Custom timeout
return $ffmpeg;
});
Laravel Nova Integration: Use the package in Nova tools for media management:
Nova::tools(function (Tools $tools) {
$tools->add('MediaProcessor', MediaProcessor::make());
});
Reuse FFmpeg Instances:
Cache the FFMpeg instance to avoid reinitialization:
$ffmpeg = app('ffmpeg');
Stream Processing:
Use -f segment for live streaming:
$ffmpeg->execute(['-i', 'input.mp4', '-f', 'segment', '-segment_time', '10', 'output_%03d.mp4']);
Parallel Processing:
Use Laravel's parallel helper for batch jobs:
parallel([
fn() => ProcessVideoJob::dispatch('video1.mp4'),
fn() => ProcessVideoJob::dispatch('video2.mp4'),
]);
How can I help you explore Laravel packages today?