diff --git a/README.md b/README.md index 2a83bd8..692586c 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ $format->on('progress', function ($video, $format, $percentage) { $format -> setKiloBitrate(1000) + -> setAudioChannels(2) -> setAudioKiloBitrate(256); $video->save($format, 'video.avi'); @@ -246,6 +247,7 @@ $format->on('progress', function ($$audio, $format, $percentage) { }); $format + -> setAudioChannels(2) -> setAudioKiloBitrate(256); $audio->save($format, 'track.flac'); diff --git a/src/FFMpeg/Format/Audio/DefaultAudio.php b/src/FFMpeg/Format/Audio/DefaultAudio.php index 7e099e3..77673a8 100644 --- a/src/FFMpeg/Format/Audio/DefaultAudio.php +++ b/src/FFMpeg/Format/Audio/DefaultAudio.php @@ -27,6 +27,9 @@ abstract class DefaultAudio extends EventEmitter implements AudioInterface, Prog /** @var integer */ protected $audioKiloBitrate = 128; + /** @var integer */ + protected $audioChannels = null; + /** * {@inheritdoc} */ @@ -90,6 +93,31 @@ abstract class DefaultAudio extends EventEmitter implements AudioInterface, Prog return $this; } + /** + * {@inheritdoc} + */ + public function getAudioChannels() + { + return $this->audioChannels; + } + + /** + * Sets the channels value. + * + * @param integer $channels + * @throws InvalidArgumentException + */ + public function setAudioChannels($channels) + { + if ($channels < 1) { + throw new InvalidArgumentException('Wrong channels value'); + } + + $this->audioChannels = (int) $channels; + + return $this; + } + /** * {@inheritdoc} */ diff --git a/src/FFMpeg/Format/AudioInterface.php b/src/FFMpeg/Format/AudioInterface.php index 10e6854..1af29c0 100644 --- a/src/FFMpeg/Format/AudioInterface.php +++ b/src/FFMpeg/Format/AudioInterface.php @@ -19,6 +19,13 @@ interface AudioInterface extends FormatInterface */ public function getAudioKiloBitrate(); + /** + * Gets the audio channels value. + * + * @return integer + */ + public function getAudioChannels(); + /** * Returns the audio codec. * diff --git a/src/FFMpeg/Media/Audio.php b/src/FFMpeg/Media/Audio.php index 95854d3..25c8961 100644 --- a/src/FFMpeg/Media/Audio.php +++ b/src/FFMpeg/Media/Audio.php @@ -87,6 +87,10 @@ class Audio extends AbstractStreamableMedia $commands[] = '-b:a'; $commands[] = $format->getAudioKiloBitrate() . 'k'; } + if (null !== $format->getAudioChannels()) { + $commands[] = '-ac'; + $commands[] = $format->getAudioChannels(); + } $commands[] = $outputPathfile; try { diff --git a/src/FFMpeg/Media/Video.php b/src/FFMpeg/Media/Video.php index ae2996f..ec579ad 100644 --- a/src/FFMpeg/Media/Video.php +++ b/src/FFMpeg/Media/Video.php @@ -114,6 +114,10 @@ class Video extends Audio $commands[] = '-b:a'; $commands[] = $format->getAudioKiloBitrate() . 'k'; } + if (null !== $format->getAudioChannels()) { + $commands[] = '-ac'; + $commands[] = $format->getAudioChannels(); + } } $fs = FsManager::create(); diff --git a/tests/FFMpeg/Tests/Format/Audio/AudioTestCase.php b/tests/FFMpeg/Tests/Format/Audio/AudioTestCase.php index ff75478..d86c3fa 100644 --- a/tests/FFMpeg/Tests/Format/Audio/AudioTestCase.php +++ b/tests/FFMpeg/Tests/Format/Audio/AudioTestCase.php @@ -71,6 +71,34 @@ abstract class AudioTestCase extends TestCase $this->getFormat()->setAudioKiloBitrate(-10); } + public function testGetAudioChannels() + { + $this->assertInternalType('null', $this->getFormat()->getAudioChannels()); + } + + public function testSetAudioChannels() + { + $format = $this->getFormat(); + $format->setAudioChannels(2); + $this->assertEquals(2, $format->getAudioChannels()); + } + + /** + * @expectedException FFMpeg\Exception\InvalidArgumentException + */ + public function testSetInvalidChannels() + { + $this->getFormat()->setAudioChannels(0); + } + + /** + * @expectedException FFMpeg\Exception\InvalidArgumentException + */ + public function testSetNegativeChannels() + { + $this->getFormat()->setAudioChannels(-10); + } + public function testCreateProgressListener() { $media = $this->getMock('FFMpeg\Media\MediaTypeInterface'); diff --git a/tests/FFMpeg/Tests/Media/AudioTest.php b/tests/FFMpeg/Tests/Media/AudioTest.php index bca3967..a71bc48 100644 --- a/tests/FFMpeg/Tests/Media/AudioTest.php +++ b/tests/FFMpeg/Tests/Media/AudioTest.php @@ -187,6 +187,9 @@ class AudioTest extends AbstractStreamableTestCase $format->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(663)); + $format->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(5)); $audioFormat = $this->getMock('FFMpeg\Format\AudioInterface'); $audioFormat->expects($this->any()) @@ -195,6 +198,9 @@ class AudioTest extends AbstractStreamableTestCase $audioFormat->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(664)); + $audioFormat->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(5)); $audioFormat->expects($this->any()) ->method('getAudioCodec') ->will($this->returnValue('patati-patata-audio')); @@ -206,6 +212,9 @@ class AudioTest extends AbstractStreamableTestCase $formatExtra->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(665)); + $formatExtra->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(5)); $listeners = array($this->getMock('Alchemy\BinaryDriver\Listeners\ListenerInterface')); @@ -220,29 +229,36 @@ class AudioTest extends AbstractStreamableTestCase $progressableFormat->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(666)); + $progressableFormat->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(5)); return array( array(false, array( '-y', '-i', __FILE__, '-b:a', '663k', + '-ac', '5', '/target/file', ), null, $format), array(false, array( '-y', '-i', __FILE__, '-acodec', 'patati-patata-audio', '-b:a', '664k', + '-ac', '5', '/target/file', ), null, $audioFormat), array(false, array( '-y', '-i', __FILE__, 'extra', 'param', '-b:a', '665k', + '-ac', '5', '/target/file', ), null, $formatExtra), array(true, array( '-y', '-i', __FILE__, '-threads', 24, '-b:a', '663k', + '-ac', '5', '/target/file', ), null, $format), array(true, array( @@ -250,17 +266,20 @@ class AudioTest extends AbstractStreamableTestCase 'extra', 'param', '-threads', 24, '-b:a', '665k', + '-ac', '5', '/target/file', ), null, $formatExtra), array(false, array( '-y', '-i', __FILE__, '-b:a', '666k', + '-ac', '5', '/target/file', ), $listeners, $progressableFormat), array(true, array( '-y', '-i', __FILE__, '-threads', 24, '-b:a', '666k', + '-ac', '5', '/target/file', ), $listeners, $progressableFormat), ); diff --git a/tests/FFMpeg/Tests/Media/VideoTest.php b/tests/FFMpeg/Tests/Media/VideoTest.php index fa74adb..6eecc8c 100644 --- a/tests/FFMpeg/Tests/Media/VideoTest.php +++ b/tests/FFMpeg/Tests/Media/VideoTest.php @@ -243,6 +243,9 @@ class VideoTest extends AbstractStreamableTestCase $format->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $format->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $format->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); @@ -257,6 +260,9 @@ class VideoTest extends AbstractStreamableTestCase $audioFormat->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $audioFormat->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $audioFormat->expects($this->any()) ->method('getPasses') ->will($this->returnValue(1)); @@ -277,6 +283,9 @@ class VideoTest extends AbstractStreamableTestCase $audioVideoFormat->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $audioVideoFormat->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $audioVideoFormat->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); @@ -297,6 +306,9 @@ class VideoTest extends AbstractStreamableTestCase $audioVideoFormatSinglePass->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $audioVideoFormatSinglePass->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $audioVideoFormatSinglePass->expects($this->any()) ->method('getPasses') ->will($this->returnValue(1)); @@ -311,6 +323,9 @@ class VideoTest extends AbstractStreamableTestCase $formatExtra->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $formatExtra->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $formatExtra->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); @@ -331,6 +346,9 @@ class VideoTest extends AbstractStreamableTestCase $progressableFormat->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $progressableFormat->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $progressableFormat->expects($this->any()) ->method('getPasses') ->will($this->returnValue(2)); @@ -349,6 +367,9 @@ class VideoTest extends AbstractStreamableTestCase $progressableAudioFormat->expects($this->any()) ->method('getAudioKiloBitrate') ->will($this->returnValue(92)); + $progressableAudioFormat->expects($this->any()) + ->method('getAudioChannels') + ->will($this->returnValue(2)); $progressableAudioFormat->expects($this->any()) ->method('getPasses') ->will($this->returnValue(1)); @@ -358,14 +379,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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), null, $format), array(false, array(array( @@ -374,7 +395,7 @@ class VideoTest extends AbstractStreamableTestCase '-acodec', 'patati-patata-audio', '-b:v', '664k', '-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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, @@ -383,7 +404,7 @@ class VideoTest extends AbstractStreamableTestCase '-b:v', '664k', '-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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), null, $audioVideoFormat), array(false, array(array( @@ -392,7 +413,7 @@ class VideoTest extends AbstractStreamableTestCase '-acodec', 'patati-patata-audio', '-b:v', '664k', '-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', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '/target/file', )), null, $audioVideoFormatSinglePass), array(false, array(array( @@ -400,14 +421,14 @@ class VideoTest extends AbstractStreamableTestCase 'extra', 'param','-b:v', '665k', '-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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, 'extra', 'param', '-b:v', '665k', '-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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), null, $formatExtra), array(true, array(array( @@ -415,7 +436,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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, @@ -423,7 +444,7 @@ 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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), null, $format), array(true, array(array( @@ -431,28 +452,28 @@ class VideoTest extends AbstractStreamableTestCase 'extra', 'param', '-threads', 24, '-b:v', '665k', '-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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, 'extra', 'param', '-threads', 24, '-b:v', '665k', '-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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), null, $formatExtra), array(false, array(array( '-y', '-i', __FILE__, '-b:v', '666k', '-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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, '-b:v', '666k', '-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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), $listeners, $progressableFormat), array(true, array(array( @@ -460,7 +481,7 @@ class VideoTest extends AbstractStreamableTestCase '-threads', 24, '-b:v', '666k', '-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', '-pass', '1', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '1', '-passlogfile', '/target/file', ), array( '-y', '-i', __FILE__, @@ -468,19 +489,19 @@ class VideoTest extends AbstractStreamableTestCase '-b:v', '666k', '-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', '-pass', '2', '-passlogfile', + '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-ac', '2', '-pass', '2', '-passlogfile', '/target/file', )), $listeners, $progressableFormat), array(true, array(array( '-y', '-i', __FILE__, '-threads', 24, '-acodec', 'patati-patata-audio', - '-b:a', '92k', + '-b:a', '92k', '-ac', '2', '/target/file', )), null, $audioFormat), array(true, array(array( '-y', '-i', __FILE__, '-threads', 24, '-acodec', 'patati-patata-audio', - '-b:a', '92k', + '-b:a', '92k', '-ac', '2', '/target/file', )), $listeners, $progressableAudioFormat), );