Add filter priorities
This commit is contained in:
parent
5ecb6f1cfe
commit
890cbce1f9
10 changed files with 156 additions and 33 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
34
src/FFMpeg/Filters/Audio/SimpleFilter.php
Normal file
34
src/FFMpeg/Filters/Audio/SimpleFilter.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,4 +13,10 @@ namespace FFMpeg\Filters;
|
||||||
|
|
||||||
interface FilterInterface
|
interface FilterInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns the priority of the filter.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getPriority();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue