This package provides an integration with FFmpeg for Laravel 5.6. The storage of the files is handled by Laravel's Filesystem.

pascalbaljet fa26795dea Merge pull request #113 from ChiVincent/patch-1 %!s(int64=6) %!d(string=hai) anos
config 0a4e5494b7 Use nested array for laravel configures. %!s(int64=6) %!d(string=hai) anos
src 67aa0be62d Option to disable format sorting in HLS exporter. %!s(int64=6) %!d(string=hai) anos
tests 67aa0be62d Option to disable format sorting in HLS exporter. %!s(int64=6) %!d(string=hai) anos
.editorconfig 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos
.gitattributes 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos
.gitignore 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos
.scrutinizer.yml 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos
.travis.yml c9f231c0d9 Update .travis.yml %!s(int64=6) %!d(string=hai) anos
CHANGELOG.md 7e247af0ae Updated deps %!s(int64=6) %!d(string=hai) anos
CONTRIBUTING.md 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos
LICENSE.md 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos
README.md 7e247af0ae Updated deps %!s(int64=6) %!d(string=hai) anos
composer.json ddb7347853 Update composer.json %!s(int64=6) %!d(string=hai) anos
phpunit.xml.dist 71023a5e92 first commit %!s(int64=8) %!d(string=hai) anos

README.md

Laravel FFMpeg

Latest Version on Packagist Software License Build Status Quality Score Total Downloads

This package provides an integration with FFmpeg for Laravel 5.7. The storage of the files is handled by Laravel's Filesystem.

Features

Installation

This version of the package is only compatible with Laravel 5.7. If you're still using Laravel 5.1 - 5.5, please use version 1.3, for Laravel 5.6 use version 2.1. Mind that older versions are not supported anymore.

You can install the package via composer:

composer require pbmedia/laravel-ffmpeg

Add the Service Provider and Facade to your app.php config file if you're not using Package Discovery.


// Laravel 5: config/app.php

'providers' => [
    ...
    Pbmedia\LaravelFFMpeg\FFMpegServiceProvider::class,
    ...
];

'aliases' => [
    ...
    'FFMpeg' => Pbmedia\LaravelFFMpeg\FFMpegFacade::class
    ...
];

Publish the config file using the artisan CLI tool:

php artisan vendor:publish --provider="Pbmedia\LaravelFFMpeg\FFMpegServiceProvider"

Usage

Convert an audio or video file:

FFMpeg::fromDisk('songs')
    ->open('yesterday.mp3')
    ->export()
    ->toDisk('converted_songs')
    ->inFormat(new \FFMpeg\Format\Audio\Aac)
    ->save('yesterday.aac');

Instead of the fromDisk() method you can also use the fromFilesystem() method, where $filesystem is an instance of Illuminate\Contracts\Filesystem\Filesystem.

$media = FFMpeg::fromFilesystem($filesystem)->open('yesterday.mp3');

You can add filters through a Closure or by using PHP-FFMpeg's Filter objects:

FFMpeg::fromDisk('videos')
    ->open('steve_howe.mp4')
    ->addFilter(function ($filters) {
        $filters->resize(new \FFMpeg\Coordinate\Dimension(640, 480));
    })
    ->export()
    ->toDisk('converted_videos')
    ->inFormat(new \FFMpeg\Format\Video\X264)
    ->save('small_steve.mkv');

// or

$start = \FFMpeg\Coordinate\TimeCode::fromSeconds(5)
$clipFilter = new \FFMpeg\Filters\Video\ClipFilter($start);

FFMpeg::fromDisk('videos')
    ->open('steve_howe.mp4')
    ->addFilter($clipFilter)
    ->export()
    ->toDisk('converted_videos')
    ->inFormat(new \FFMpeg\Format\Video\X264)
    ->save('short_steve.mkv');

Sometimes you don't want to use the built-in filters. You can apply your own filter by providing a set of options. This can be an array or multiple strings as arguments:

FFMpeg::fromDisk('videos')
    ->open('steve_howe.mp4')
    ->addFilter(['-itsoffset', 1]);

// or

FFMpeg::fromDisk('videos')
    ->open('steve_howe.mp4')
    ->addFilter('-itsoffset', 1);

Chain multiple convertions:

// The 'fromDisk()' method is not required, the file will now
// be opened from the default 'disk', as specified in
// the config file.

FFMpeg::open('my_movie.mov')

    // export to FTP, converted in WMV
    ->export()
    ->toDisk('ftp')
    ->inFormat(new \FFMpeg\Format\Video\WMV)
    ->save('my_movie.wmv')

    // export to Amazon S3, converted in X264
    ->export()
    ->toDisk('s3')
    ->inFormat(new \FFMpeg\Format\Video\X264)
    ->save('my_movie.mkv');

    // you could even discard the 'toDisk()' method,
    // now the converted file will be saved to
    // the same disk as the source!
    ->export()
    ->inFormat(new FFMpeg\Format\Video\WebM)
    ->save('my_movie.webm')

    // optionally you could set the visibility
    // of the exported file
    ->export()
    ->inFormat(new FFMpeg\Format\Video\WebM)
    ->withVisibility('public')
    ->save('my_movie.webm')

Create a frame from a video:

FFMpeg::fromDisk('videos')
    ->open('steve_howe.mp4')
    ->getFrameFromSeconds(10)
    ->export()
    ->toDisk('thumnails')
    ->save('FrameAt10sec.png');

// Instead of the 'getFrameFromSeconds()' method, you could
// also use the 'getFrameFromString()' or the
// 'getFrameFromTimecode()' methods:

$media = FFMpeg::open('steve_howe.mp4');
$frame = $media->getFrameFromString('00:00:13.37');

// or

$timecode = new FMpeg\Coordinate\TimeCode(...);
$frame = $media->getFrameFromTimecode($timecode);

With the Media class you can determinate the duration of a file:

$media = FFMpeg::open('wwdc_2006.mp4');

$durationInSeconds = $media->getDurationInSeconds(); // returns an int
$durationInMiliseconds = $media->getDurationInMiliseconds(); // returns a float

When opening or saving files from or to a remote disk, temporary files will be created on your server. After you're done exporting or processing these files, you could clean them up by calling the cleanupTemporaryFiles() method:

FFMpeg::cleanupTemporaryFiles();

HLS

You can create a M3U8 playlist to do HLS. Exporting is currently only supported on local disks.

$lowBitrate = (new X264)->setKiloBitrate(250);
$midBitrate = (new X264)->setKiloBitrate(500);
$highBitrate = (new X264)->setKiloBitrate(1000);

FFMpeg::fromDisk('videos')
    ->open('steve_howe.mp4')
    ->exportForHLS()
    ->setSegmentLength(10) // optional
    ->addFormat($lowBitrate)
    ->addFormat($midBitrate)
    ->addFormat($highBitrate)
    ->save('adaptive_steve.m3u8');

As of version 1.2.0 the addFormat method of the HLS exporter takes an optional second parameter which can be a callback method. This allows you to add different filters per format:

$lowBitrate = (new X264)->setKiloBitrate(250);
$highBitrate = (new X264)->setKiloBitrate(1000);

FFMpeg::open('steve_howe.mp4')
    ->exportForHLS()
    ->addFormat($lowBitrate, function($media) {
        $media->addFilter(function ($filters) {
            $filters->resize(new \FFMpeg\Coordinate\Dimension(640, 480));
        });
    })
    ->addFormat($highBitrate, function($media) {
        $media->addFilter(function ($filters) {
            $filters->resize(new \FFMpeg\Coordinate\Dimension(1280, 960));
        });
    })
    ->save('adaptive_steve.m3u8');

As of version 1.3.0 you can monitor the transcoding progress of a HLS export. Use the onProgress method to provide a callback which gives you the completed percentage.

$exporter = FFMpeg::open('steve_howe.mp4')
    ->exportForHLS()
    ->onProgress(function ($percentage) {
        echo "$percentage % transcoded";
    });

As of version 2.1.0 you can disable the sorting of the added formats as most players choose the first format as the default one.

$exporter = FFMpeg::open('steve_howe.mp4')
    ->exportForHLS()
    ->dontSortFormats();

Advanced

The Media object you get when you 'open' a file, actually holds the Media object that belongs to the underlying driver. It handles dynamic method calls as you can see here. This way all methods of the underlying driver are still available to you.

// This gives you an instance of Pbmedia\LaravelFFMpeg\Media
$media = FFMpeg::fromDisk('videos')->open('video.mp4');

// The 'getStreams' method will be called on the underlying Media object since
// it doesn't exists on this object.
$codec = $media->getStreams()->first()->get('codec_name');

If you want direct access to the underlying object, call the object as a function (invoke):

// This gives you an instance of Pbmedia\LaravelFFMpeg\Media
$media = FFMpeg::fromDisk('videos')->open('video.mp4');

// This gives you an instance of FFMpeg\Media\MediaTypeInterface
$baseMedia = $media();

Example app

Here's a blogpost that will help you get started with this package:

https://pascalbaljetmedia.com/en/blog/how-to-use-ffmpeg-in-your-laravel-projects

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email pascal@pascalbaljetmedia.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.