Add filter priorities

This commit is contained in:
Romain Neutron 2013-06-26 00:21:12 +02:00
commit 890cbce1f9
10 changed files with 156 additions and 33 deletions

View file

@ -18,10 +18,21 @@ class AudioResamplableFilter implements AudioFilterInterface
{ {
/** @var string */ /** @var string */
private $rate; private $rate;
/** @var integer */
private $priority;
public function __construct($rate) public function __construct($rate, $priority = 0)
{ {
$this->rate = $rate; $this->rate = $rate;
$this->priority = $priority;
}
/**
* {@inheritdoc}
*/
public function getPriority()
{
return $this->priority;
} }
/** /**

View file

@ -0,0 +1,34 @@
<?php
namespace FFMpeg\Filters\Audio;
use FFMpeg\Media\Audio;
use FFMpeg\Format\AudioInterface;
class SimpleFilter implements AudioFilterInterface
{
private $params;
private $priority;
public function __construct(array $params, $priority = 0)
{
$this->params = $params;
$this->priority = $priority;
}
/**
* {@inheritdoc}
*/
public function getPriority()
{
return $this->priority;
}
/**
* {@inheritdoc}
*/
public function apply(Audio $audio, AudioInterface $format)
{
return $this->params;
}
}

View file

@ -13,4 +13,10 @@ namespace FFMpeg\Filters;
interface FilterInterface interface FilterInterface
{ {
/**
* Returns the priority of the filter.
*
* @return integer
*/
public function getPriority();
} }

View file

@ -13,6 +13,7 @@ namespace FFMpeg\Filters;
class FiltersCollection implements \Countable, \IteratorAggregate class FiltersCollection implements \Countable, \IteratorAggregate
{ {
private $sorted;
private $filters = array(); private $filters = array();
/** /**
@ -22,7 +23,8 @@ class FiltersCollection implements \Countable, \IteratorAggregate
*/ */
public function add(FilterInterface $filter) public function add(FilterInterface $filter)
{ {
$this->filters[] = $filter; $this->filters[$filter->getPriority()][] = $filter;
$this->sorted = null;
return $this; return $this;
} }
@ -32,7 +34,11 @@ class FiltersCollection implements \Countable, \IteratorAggregate
*/ */
public function count() public function count()
{ {
return count($this->filters); if (0 === count($this->filters)) {
return 0;
}
return count(call_user_func_array('array_merge', $this->filters));
} }
/** /**
@ -40,6 +46,11 @@ class FiltersCollection implements \Countable, \IteratorAggregate
*/ */
public function getIterator() public function getIterator()
{ {
return new \ArrayIterator($this->filters); if (null === $this->sorted) {
krsort($this->filters);
$this->sorted = call_user_func_array('array_merge', $this->filters);
}
return new \ArrayIterator($this->sorted);
} }
} }

View file

@ -28,12 +28,23 @@ class ResizeFilter implements VideoFilterInterface
private $mode; private $mode;
/** @var Boolean */ /** @var Boolean */
private $forceStandards; private $forceStandards;
/** @var integer */
private $priority;
public function __construct(Dimension $dimension, $mode = self::RESIZEMODE_FIT, $forceStandards = true) public function __construct(Dimension $dimension, $mode = self::RESIZEMODE_FIT, $forceStandards = true, $priority = 0)
{ {
$this->dimension = $dimension; $this->dimension = $dimension;
$this->mode = $mode; $this->mode = $mode;
$this->forceStandards = $forceStandards; $this->forceStandards = $forceStandards;
$this->priority = $priority;
}
/**
* {@inheritdoc}
*/
public function getPriority()
{
return $this->priority;
} }
/** /**

View file

@ -19,6 +19,21 @@ use FFMpeg\Media\Video;
*/ */
class SynchronizeFilter implements VideoFilterInterface class SynchronizeFilter implements VideoFilterInterface
{ {
private $priority;
public function __construct($priority = 12)
{
$this->priority = $priority;
}
/**
* {@inheritdoc}
*/
public function getPriority()
{
return $this->priority;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View file

@ -19,11 +19,21 @@ class VideoResampleFilter implements VideoFilterInterface
{ {
private $rate; private $rate;
private $gop; private $gop;
private $priority;
public function __construct(FrameRate $rate, $gop) public function __construct(FrameRate $rate, $gop, $priority = 0)
{ {
$this->rate = $rate; $this->rate = $rate;
$this->gop = $gop; $this->gop = $gop;
$this->priority = $priority;
}
/**
* {@inheritdoc}
*/
public function getPriority()
{
return $this->priority;
} }
/** /**

View file

@ -14,6 +14,7 @@ namespace FFMpeg\Media;
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
use FFMpeg\Filters\Audio\AudioFilters; use FFMpeg\Filters\Audio\AudioFilters;
use FFMpeg\Format\FormatInterface; use FFMpeg\Format\FormatInterface;
use FFMpeg\Filters\Audio\SimpleFilter;
use FFMpeg\Exception\RuntimeException; use FFMpeg\Exception\RuntimeException;
use FFMpeg\Exception\InvalidArgumentException; use FFMpeg\Exception\InvalidArgumentException;
use FFMpeg\Filters\Audio\AudioFilterInterface; use FFMpeg\Filters\Audio\AudioFilterInterface;
@ -66,22 +67,21 @@ class Audio extends AbstractStreamableMedia
$listeners = $format->createProgressListener($this, $this->ffprobe, 1, 1); $listeners = $format->createProgressListener($this, $this->ffprobe, 1, 1);
} }
$commands = array_merge(array('-y', '-i', $this->pathfile), $format->getExtraParams()); $commands = array('-y', '-i', $this->pathfile);
$this->addFilter(new SimpleFilter($format->getExtraParams(), 10));
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) {
$this->addFilter(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads'))));
}
if (null !== $format->getAudioCodec()) {
$this->addFilter(new SimpleFilter(array('-acodec', $format->getAudioCodec())));
}
foreach ($this->filters as $filter) { foreach ($this->filters as $filter) {
$commands = array_merge($commands, $filter->apply($this, $format)); $commands = array_merge($commands, $filter->apply($this, $format));
} }
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) {
$commands[] = '-threads';
$commands[] = $this->driver->getConfiguration()->get('ffmpeg.threads');
}
if (null !== $format->getAudioCodec()) {
$commands[] = '-acodec';
$commands[] = $format->getAudioCodec();
}
$commands[] = '-b:a'; $commands[] = '-b:a';
$commands[] = $format->getAudioKiloBitrate() . 'k'; $commands[] = $format->getAudioKiloBitrate() . 'k';
$commands[] = $outputPathfile; $commands[] = $outputPathfile;

View file

@ -13,6 +13,7 @@ namespace FFMpeg\Media;
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
use FFMpeg\Coordinate\TimeCode; use FFMpeg\Coordinate\TimeCode;
use FFMpeg\Filters\Audio\SimpleFilter;
use FFMpeg\Exception\RuntimeException; use FFMpeg\Exception\RuntimeException;
use FFMpeg\Filters\Video\VideoFilters; use FFMpeg\Filters\Video\VideoFilters;
use FFMpeg\Filters\FilterInterface; use FFMpeg\Filters\FilterInterface;
@ -56,26 +57,24 @@ class Video extends Audio
*/ */
public function save(FormatInterface $format, $outputPathfile) public function save(FormatInterface $format, $outputPathfile)
{ {
$commands = array_merge(array('-y', '-i', $this->pathfile), $format->getExtraParams()); $commands = array('-y', '-i', $this->pathfile);
$this->addFilter(new SimpleFilter($format->getExtraParams(), 10));
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) {
$this->addFilter(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads'))));
}
if (null !== $format->getVideoCodec()) {
$this->addFilter(new SimpleFilter(array('-vcodec', $format->getVideoCodec())));
}
if (null !== $format->getAudioCodec()) {
$this->addFilter(new SimpleFilter(array('-acodec', $format->getAudioCodec())));
}
foreach ($this->filters as $filter) { foreach ($this->filters as $filter) {
$commands = array_merge($commands, $filter->apply($this, $format)); $commands = array_merge($commands, $filter->apply($this, $format));
} }
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) {
$commands[] = '-threads';
$commands[] = $this->driver->getConfiguration()->get('ffmpeg.threads');
}
if (null !== $format->getVideoCodec()) {
$commands[] = '-vcodec';
$commands[] = $format->getVideoCodec();
}
if (null !== $format->getAudioCodec()) {
$commands[] = '-acodec';
$commands[] = $format->getAudioCodec();
}
$commands[] = '-b:v'; $commands[] = '-b:v';
$commands[] = $format->getKiloBitrate() . 'k'; $commands[] = $format->getKiloBitrate() . 'k';
$commands[] = '-refs'; $commands[] = '-refs';

View file

@ -3,8 +3,10 @@
namespace FFMpeg\Tests\Filters; namespace FFMpeg\Tests\Filters;
use FFMpeg\Filters\FiltersCollection; use FFMpeg\Filters\FiltersCollection;
use FFMpeg\Filters\Audio\SimpleFilter;
use FFMpeg\Tests\TestCase;
class FiltersCollectionTest extends \PHPUnit_Framework_TestCase class FiltersCollectionTest extends TestCase
{ {
public function testCount() public function testCount()
{ {
@ -27,4 +29,28 @@ class FiltersCollectionTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('\ArrayIterator', $coll->getIterator()); $this->assertInstanceOf('\ArrayIterator', $coll->getIterator());
$this->assertCount(2, $coll->getIterator()); $this->assertCount(2, $coll->getIterator());
} }
public function testIteratorSort()
{
$coll = new FiltersCollection();
$coll->add(new SimpleFilter(array('a')));
$coll->add(new SimpleFilter(array('1'), 12));
$coll->add(new SimpleFilter(array('b')));
$coll->add(new SimpleFilter(array('2'), 12));
$coll->add(new SimpleFilter(array('c')));
$coll->add(new SimpleFilter(array('3'), 10));
$coll->add(new SimpleFilter(array('d')));
$coll->add(new SimpleFilter(array('4'), -2));
$coll->add(new SimpleFilter(array('e')));
$data = array();
$video = $this->getVideoMock();
$format = $this->getMock('FFMpeg\Format\AudioInterface');
foreach ($coll as $filter) {
$data = array_merge($data, $filter->apply($video, $format));
}
$this->assertEquals(array('1', '2', '3', 'a', 'b', 'c', 'd', 'e', '4'), $data);
}
} }