From 6ba011de3a9063f2a33c15c70afd71e3fc77c086 Mon Sep 17 00:00:00 2001 From: Romain Biard Date: Tue, 24 Jan 2017 15:19:32 -0300 Subject: [PATCH] Methods getAdditionalParams & setAdditionalParams which allow the user to pass additional parameters to the encoding request (#284) * Modification of the format Video to add additional parameters based on user's desire * Update of the README * Working version of this feature. Still needs tests * Fixing the tests of FFMPeg\Media\Video * Setting up tests for the additionalParams feature * Correction des tests * Modifying tests. They work locally but not on Travis. * Still trying to understand why Travis is throwing errors when PHPUnit is not. * Add the additional params at the end of the command * Fixed the tests and the way we add the parameters * We remove log files --- README.md | 12 ++++ src/FFMpeg/Format/Video/DefaultVideo.php | 28 ++++++++ src/FFMpeg/Format/VideoInterface.php | 7 ++ src/FFMpeg/Media/Video.php | 9 +++ tests/Unit/Media/VideoTest.php | 87 ++++++++++++++++++++++-- 5 files changed, 136 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a7000cf..1296d3e 100644 --- a/README.md +++ b/README.md @@ -441,6 +441,18 @@ $video->save($format, 'video.avi'); The callback provided for the event can be any callable. +##### Add additional parameters + +You can add additional parameters to your encoding requests based on your video format. + +The argument of the setAdditionalParameters method is an array. + +```php +$format = new Format\Video\X264(); +$format->setAdditionalParameters(array('foo', 'bar')); +$video->save($format, 'video.avi'); +``` + ##### Create your own format The easiest way to create a format is to extend the abstract diff --git a/src/FFMpeg/Format/Video/DefaultVideo.php b/src/FFMpeg/Format/Video/DefaultVideo.php index b33965d..1abfa67 100644 --- a/src/FFMpeg/Format/Video/DefaultVideo.php +++ b/src/FFMpeg/Format/Video/DefaultVideo.php @@ -32,6 +32,9 @@ abstract class DefaultVideo extends DefaultAudio implements VideoInterface /** @var Integer */ protected $modulus = 16; + /** @var Array */ + protected $additionalParamaters; + /** * {@inheritdoc} */ @@ -94,6 +97,31 @@ abstract class DefaultVideo extends DefaultAudio implements VideoInterface return $this->modulus; } + /** + * {@inheritdoc} + */ + public function getAdditionalParameters() + { + return $this->additionalParamaters; + } + + /** + * Sets additional parameters. + * + * @param array $additionalParamaters + * @throws InvalidArgumentException + */ + public function setAdditionalParameters($additionalParamaters) + { + if (!is_array($additionalParamaters)) { + throw new InvalidArgumentException('Wrong additionalParamaters value'); + } + + $this->additionalParamaters = $additionalParamaters; + + return $this; + } + /** * {@inheritdoc} */ diff --git a/src/FFMpeg/Format/VideoInterface.php b/src/FFMpeg/Format/VideoInterface.php index fa6fb0c..329bff2 100644 --- a/src/FFMpeg/Format/VideoInterface.php +++ b/src/FFMpeg/Format/VideoInterface.php @@ -54,4 +54,11 @@ interface VideoInterface extends AudioInterface * @return array */ public function getAvailableVideoCodecs(); + + /** + * Returns the list of available video codecs for this format. + * + * @return array + */ + public function getAdditionalParameters(); } diff --git a/src/FFMpeg/Media/Video.php b/src/FFMpeg/Media/Video.php index bafe2bd..d43c9de 100644 --- a/src/FFMpeg/Media/Video.php +++ b/src/FFMpeg/Media/Video.php @@ -120,6 +120,15 @@ class Video extends Audio } } + // If the user passed some additional parameters + if ($format instanceof VideoInterface) { + if (null !== $format->getAdditionalParameters()) { + foreach ($format->getAdditionalParameters() as $additionalParameter) { + $commands[] = $additionalParameter; + } + } + } + $fs = FsManager::create(); $fsId = uniqid('ffmpeg-passes'); $passPrefix = $fs->createTemporaryDirectory(0777, 50, $fsId) . '/' . uniqid('pass-'); diff --git a/tests/Unit/Media/VideoTest.php b/tests/Unit/Media/VideoTest.php index 43af1bb..009a2f6 100644 --- a/tests/Unit/Media/VideoTest.php +++ b/tests/Unit/Media/VideoTest.php @@ -249,6 +249,29 @@ class VideoTest extends AbstractStreamableTestCase $format->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); + $format->expects($this->any()) + ->method('getAdditionalParameters') + ->will($this->returnValue(array('foo', 'bar'))); + + $format2 = $this->getMock('FFMpeg\Format\VideoInterface'); + $format2->expects($this->any()) + ->method('getExtraParams') + ->will($this->returnValue(array())); + $format2->expects($this->any()) + ->method('getKiloBitrate') + ->will($this->returnValue(663)); + $format2->expects($this->any()) + ->method('getAudioKiloBitrate') + ->will($this->returnValue(92)); + $format2->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); + $format2->expects($this->any()) + ->method('getPasses') + ->will($this->returnValue(2)); + $format2->expects($this->any()) + ->method('getAdditionalParameters') + ->will($this->returnValue(array('foo', 'bar'))); $audioFormat = $this->getMock('FFMpeg\Format\AudioInterface'); $audioFormat->expects($this->any()) @@ -289,6 +312,9 @@ class VideoTest extends AbstractStreamableTestCase $audioVideoFormat->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); + $audioVideoFormat->expects($this->any()) + ->method('getAdditionalParameters') + ->will($this->returnValue(array())); $audioVideoFormatSinglePass = $this->getMock('FFMpeg\Format\VideoInterface'); $audioVideoFormatSinglePass->expects($this->any()) @@ -312,6 +338,9 @@ class VideoTest extends AbstractStreamableTestCase $audioVideoFormatSinglePass->expects($this->any()) ->method('getPasses') ->will($this->returnValue(1)); + $audioVideoFormatSinglePass->expects($this->any()) + ->method('getAdditionalParameters') + ->will($this->returnValue(array())); $formatExtra = $this->getMock('FFMpeg\Format\VideoInterface'); $formatExtra->expects($this->any()) @@ -329,6 +358,29 @@ class VideoTest extends AbstractStreamableTestCase $formatExtra->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); + $formatExtra->expects($this->any()) + ->method('getAdditionalParameters') + ->will($this->returnValue(array())); + + $formatExtra2 = $this->getMock('FFMpeg\Format\VideoInterface'); + $formatExtra2->expects($this->any()) + ->method('getExtraParams') + ->will($this->returnValue(array('extra', 'param'))); + $formatExtra2->expects($this->any()) + ->method('getKiloBitrate') + ->will($this->returnValue(665)); + $formatExtra2->expects($this->any()) + ->method('getAudioKiloBitrate') + ->will($this->returnValue(92)); + $formatExtra2->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); + $formatExtra2->expects($this->any()) + ->method('getPasses') + ->will($this->returnValue(2)); + $formatExtra2->expects($this->any()) + ->method('getAdditionalParameters') + ->will($this->returnValue(array())); $listeners = array($this->getMock('Alchemy\BinaryDriver\Listeners\ListenerInterface')); @@ -353,6 +405,27 @@ class VideoTest extends AbstractStreamableTestCase ->method('getPasses') ->will($this->returnValue(2)); + $progressableFormat2 = $this->getMockBuilder('Tests\FFMpeg\Unit\Media\Prog') + ->disableOriginalConstructor()->getMock(); + $progressableFormat2->expects($this->any()) + ->method('getExtraParams') + ->will($this->returnValue(array())); + $progressableFormat2->expects($this->any()) + ->method('createProgressListener') + ->will($this->returnValue($listeners)); + $progressableFormat2->expects($this->any()) + ->method('getKiloBitrate') + ->will($this->returnValue(666)); + $progressableFormat2->expects($this->any()) + ->method('getAudioKiloBitrate') + ->will($this->returnValue(92)); + $progressableFormat2->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); + $progressableFormat2->expects($this->any()) + ->method('getPasses') + ->will($this->returnValue(2)); + $progressableAudioFormat = $this->getMockBuilder('Tests\FFMpeg\Unit\Media\AudioProg') ->disableOriginalConstructor()->getMock(); $progressableAudioFormat->expects($this->any()) @@ -379,14 +452,14 @@ class VideoTest extends AbstractStreamableTestCase '-y', '-i', __FILE__, '-b:v', '663k', '-refs', '6', '-coder', '1', '-sc_threshold', '40', '-flags', '+loop', '-me_range', '16', '-subq', '7', '-i_qfactor', '0.71', '-qcomp', '0.6', - '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', 2, 'foo', 'bar', '-pass', 1, '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, '-b:v', '663k', '-refs', '6', '-coder', '1', '-sc_threshold', '40', '-flags', '+loop', '-me_range', '16', '-subq', '7', '-i_qfactor', '0.71', '-qcomp', '0.6', - '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', 2, 'foo', 'bar', '-pass', 2, '-passlogfile', '/target/file', )), null, $format), array(false, array(array( @@ -436,7 +509,7 @@ class VideoTest extends AbstractStreamableTestCase '-threads', 24, '-b:v', '663k', '-refs', '6', '-coder', '1', '-sc_threshold', '40', '-flags', '+loop', '-me_range', '16', '-subq', '7', '-i_qfactor', '0.71', '-qcomp', '0.6', - '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', 2, 'foo', 'bar', '-pass', 1, '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, @@ -444,9 +517,9 @@ class VideoTest extends AbstractStreamableTestCase '-b:v', '663k', '-refs', '6', '-coder', '1', '-sc_threshold', '40', '-flags', '+loop', '-me_range', '16', '-subq', '7', '-i_qfactor', '0.71', '-qcomp', '0.6', - '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', 2, 'foo', 'bar', '-pass', 2, '-passlogfile', '/target/file', - )), null, $format), + )), null, $format2), array(true, array(array( '-y', '-i', __FILE__, 'extra', 'param', '-threads', 24, '-b:v', '665k', @@ -461,7 +534,7 @@ class VideoTest extends AbstractStreamableTestCase '-me_range', '16', '-subq', '7', '-i_qfactor', '0.71', '-qcomp', '0.6', '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', - )), null, $formatExtra), + )), null, $formatExtra2), array(false, array(array( '-y', '-i', __FILE__, '-b:v', '666k', '-refs', '6', '-coder', '1', '-sc_threshold', '40', '-flags', '+loop', @@ -475,7 +548,7 @@ class VideoTest extends AbstractStreamableTestCase '-me_range', '16', '-subq', '7', '-i_qfactor', '0.71', '-qcomp', '0.6', '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', - )), $listeners, $progressableFormat), + )), $listeners, $progressableFormat2), array(true, array(array( '-y', '-i', __FILE__, '-threads', 24, '-b:v', '666k',