Fix using rotate and resize filters at the same time (#78)

This commit is contained in:
Romain Neutron 2013-11-29 13:25:49 +01:00
commit fca866e1d8
8 changed files with 118 additions and 7 deletions

View file

@ -1,7 +1,11 @@
CHANGELOG
---------
* 0.4.2 (xx-xx-xx)
* 0.4.3 (11-xx-2013)
* Fix using rotate and resize filters at the same time (#78)
* 0.4.2 (11-29-2013)
* Add Rotate filter.
* Remove time_start metadata when using synchronize filter

View file

@ -50,6 +50,21 @@ abstract class AbstractData implements \Countable
return $this->properties[$property];
}
/**
* Sets the property value given its name.
*
* @param string $property
* @param mixed $value
*
* @return AbstractData
*/
public function set($property, $value)
{
$this->properties[$property] = $value;
return $this;
}
/**
* Returns all property names.
*

View file

@ -55,6 +55,16 @@ class RotateFilter implements VideoFilterInterface
*/
public function apply(Video $video, VideoInterface $format)
{
if (in_array($this->angle, array(self::ROTATE_90, self::ROTATE_270), true)) {
foreach ($video->getStreams()->videos() as $stream) {
if ($stream->has('width') && $stream->has('height')) {
$width = $stream->get('width');
$stream->set('width', $stream->get('height'));
$stream->set('height', $width);
}
}
}
return array('-vf', $this->angle, '-metadata:s:v:0', 'rotate=0');
}

View file

@ -96,9 +96,9 @@ class VideoFilters extends AudioFilters
return $this;
}
public function rotate($angle, $priority = 0)
public function rotate($angle)
{
$this->media->addFilter(new RotateFilter($angle, $priority));
$this->media->addFilter(new RotateFilter($angle, 30));
return $this;
}

View file

@ -16,12 +16,18 @@ use FFMpeg\FFProbe\DataMapping\StreamCollection;
abstract class AbstractStreamableMedia extends AbstractMediaType
{
private $streams;
/**
* @return StreamCollection
*/
public function getStreams()
{
return $this->ffprobe->streams($this->pathfile);
if (null === $this->streams) {
$this->streams = $this->ffprobe->streams($this->pathfile);
}
return $this->streams;
}
/**

View file

@ -2,6 +2,9 @@
namespace FFMpeg\Functional;
use FFMpeg\Coordinate\Dimension;
use FFMpeg\Filters\Video\ResizeFilter;
use FFMpeg\Filters\Video\RotateFilter;
use FFMpeg\Format\Video\X264;
use FFMpeg\Media\Video;
@ -54,4 +57,32 @@ class VideoTranscodeTest extends FunctionalTestCase
$this->setExpectedException('FFMpeg\Exception\RuntimeException');
$video->save(new X264('libvo_aacenc'), __DIR__ . '/output/output-x264.mp4');
}
public function testTranscodePortraitVideo()
{
$filename = __DIR__ . '/output/output-x264.mp4';
if (is_file($filename)) {
unlink(__DIR__ . '/output/output-x264.mp4');
}
$ffmpeg = $this->getFFMpeg();
$video = $ffmpeg->open(__DIR__ . '/../../files/portrait.MOV');
$video->filters()
->resize(new Dimension(320, 240), ResizeFilter::RESIZEMODE_INSET)
->rotate(RotateFilter::ROTATE_90);
$video->save(new X264('libvo_aacenc'), $filename);
$dimension = $ffmpeg->getFFProbe()
->streams($filename)
->videos()
->first()
->getDimensions();
$this->assertLessThan(1, $dimension->getRatio(false)->getValue());
$this->assertEquals(240, $dimension->getHeight());
$this->assertFileExists($filename);
unlink($filename);
}
}

View file

@ -2,18 +2,63 @@
namespace FFMpeg\Tests\Filters\Video;
use FFMpeg\FFProbe\DataMapping\Stream;
use FFMpeg\FFProbe\DataMapping\StreamCollection;
use FFMpeg\Filters\Video\RotateFilter;
use FFMpeg\Tests\TestCase;
class RotateFilterTest extends TestCase
{
public function testApply()
/**
* @dataProvider provide90degresTranspositions
*/
public function testApplyWithSizeTransformation($value)
{
$stream = new Stream(array('width' => 320, 'height' => 240, 'codec_type' => 'video'));
$streams = new StreamCollection(array($stream));
$video = $this->getVideoMock();
$video->expects($this->once())
->method('getStreams')
->will($this->returnValue($streams));
$format = $this->getMock('FFMpeg\Format\VideoInterface');
$filter = new RotateFilter(RotateFilter::ROTATE_90);
$this->assertEquals(array('-vf', RotateFilter::ROTATE_90, '-metadata:s:v:0', 'rotate=0'), $filter->apply($video, $format));
$filter = new RotateFilter($value);
$this->assertEquals(array('-vf', $value, '-metadata:s:v:0', 'rotate=0'), $filter->apply($video, $format));
$this->assertEquals(240, $stream->get('width'));
$this->assertEquals(320, $stream->get('height'));
}
public function provide90degresTranspositions()
{
return array(
array(RotateFilter::ROTATE_90),
array(RotateFilter::ROTATE_270),
);
}
/**
* @dataProvider provideDegresWithoutTranspositions
*/
public function testApplyWithoutSizeTransformation($value)
{
$video = $this->getVideoMock();
$video->expects($this->never())
->method('getStreams');
$format = $this->getMock('FFMpeg\Format\VideoInterface');
$filter = new RotateFilter($value);
$this->assertEquals(array('-vf', $value, '-metadata:s:v:0', 'rotate=0'), $filter->apply($video, $format));
}
public function provideDegresWithoutTranspositions()
{
return array(
array(RotateFilter::ROTATE_180),
);
}
/**

BIN
tests/files/portrait.MOV Normal file

Binary file not shown.