diff --git a/.gitignore b/.gitignore index c85f162..2b7fb77 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ composer.phar composer.lock phpunit.xml +sami.phar diff --git a/README.md b/README.md index c0fb38d..5232627 100644 --- a/README.md +++ b/README.md @@ -217,12 +217,28 @@ Resizes a video to a given size. $video->filters()->resize($dimension, $mode, $useStandards); ``` -The resize filter takes three parameters : +The resize filter takes three parameters: - `$dimension`, an instance of `FFMpeg\Coordinate\Dimension` - `$mode`, one of the constants `FFMpeg\Filters\Video\ResizeFilter::RESIZEMODE_*` constants - `$useStandards`, a boolean to force the use of the nearest aspect ratio standard. +If you want a video in a non-standard ratio, you can use the padding filter to resize your video in the desired size, and wrap it into black bars. + +```php +$video->filters()->pad($dimension); +``` + +The pad filter takes one parameter: + +- `$dimension`, an instance of `FFMpeg\Coordinate\Dimension` + +Don't forget to save it afterwards. + +```php +$video->save(new FFMpeg\Format\Video\X264(), $new_file); +``` + ###### Watermark Watermark a video with a given image. diff --git a/composer.json b/composer.json index 7e2babf..c7a79b4 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,11 @@ "name": "Patrik Karisch", "email": "patrik@karisch.guru", "homepage": "http://www.karisch.guru" + }, + { + "name": "Romain Biard", + "email": "romain.biard@gmail.com", + "homepage": "https://www.strime.io/" } ], "require": { diff --git a/src/FFMpeg/Filters/Video/PadFilter.php b/src/FFMpeg/Filters/Video/PadFilter.php new file mode 100644 index 0000000..df19a2d --- /dev/null +++ b/src/FFMpeg/Filters/Video/PadFilter.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FFMpeg\Filters\Video; + +use FFMpeg\Coordinate\Dimension; +use FFMpeg\Exception\RuntimeException; +use FFMpeg\Media\Video; +use FFMpeg\Format\VideoInterface; + +class PadFilter implements VideoFilterInterface +{ + /** @var Dimension */ + private $dimension; + /** @var integer */ + private $priority; + + public function __construct(Dimension $dimension, $priority = 0) + { + $this->dimension = $dimension; + $this->priority = $priority; + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return $this->priority; + } + + /** + * @return Dimension + */ + public function getDimension() + { + return $this->dimension; + } + + /** + * {@inheritdoc} + */ + public function apply(Video $video, VideoInterface $format) + { + $commands = array(); + + $commands[] = '-vf'; + $commands[] = 'scale=iw*min(' . $this->dimension->getWidth() . '/iw\,' . $this->dimension->getHeight() .'/ih):ih*min(' . $this->dimension->getWidth() . '/iw\,' . $this->dimension->getHeight() .'/ih),pad=' . $this->dimension->getWidth() . ':' . $this->dimension->getHeight() . ':(' . $this->dimension->getWidth() . '-iw)/2:(' . $this->dimension->getHeight() .'-ih)/2'; + + return $commands; + } +} diff --git a/src/FFMpeg/Filters/Video/VideoFilters.php b/src/FFMpeg/Filters/Video/VideoFilters.php index 00a99d9..0eac3f3 100644 --- a/src/FFMpeg/Filters/Video/VideoFilters.php +++ b/src/FFMpeg/Filters/Video/VideoFilters.php @@ -98,6 +98,20 @@ class VideoFilters extends AudioFilters return $this; } + /** + * Adds padding (black bars) to a video. + * + * @param Dimension $dimension + * + * @return VideoFilters + */ + public function pad(Dimension $dimension) + { + $this->media->addFilter(new PadFilter($dimension)); + + return $this; + } + public function rotate($angle) { $this->media->addFilter(new RotateFilter($angle, 30)); @@ -132,4 +146,18 @@ class VideoFilters extends AudioFilters return $this; } + + /** + * Applies a custom filter: -vf foo bar + * + * @param string $parameters + * + * @return VideoFilters + */ + public function custom($parameters) + { + $this->media->addFilter(new CustomFilter($parameters)); + + return $this; + } } diff --git a/tests/Unit/Filters/Video/PadFilterTest.php b/tests/Unit/Filters/Video/PadFilterTest.php new file mode 100644 index 0000000..1d7c85a --- /dev/null +++ b/tests/Unit/Filters/Video/PadFilterTest.php @@ -0,0 +1,44 @@ +getVideoMock(); + $pathfile = '/path/to/file'.mt_rand(); + + $format = $this->getMock('FFMpeg\Format\VideoInterface'); + + $streams = new StreamCollection(array( + new Stream(array( + 'codec_type' => 'video', + 'width' => $width, + 'height' => $height, + )) + )); + + $filter = new PadFilter($dimension); + $this->assertEquals($expected, $filter->apply($video, $format)); + } + + public function provideDimensions() + { + return array( + array(new Dimension(1000, 800), 640, 480, array('-vf', 'scale=iw*min(1000/iw\,800/ih):ih*min(1000/iw\,800/ih),pad=1000:800:(1000-iw)/2:(800-ih)/2')), + array(new Dimension(300, 600), 640, 480, array('-vf', 'scale=iw*min(300/iw\,600/ih):ih*min(300/iw\,600/ih),pad=300:600:(300-iw)/2:(600-ih)/2')), + array(new Dimension(100, 900), 640, 480, array('-vf', 'scale=iw*min(100/iw\,900/ih):ih*min(100/iw\,900/ih),pad=100:900:(100-iw)/2:(900-ih)/2')), + array(new Dimension(1200, 200), 640, 480, array('-vf', 'scale=iw*min(1200/iw\,200/ih):ih*min(1200/iw\,200/ih),pad=1200:200:(1200-iw)/2:(200-ih)/2')), + ); + } +}