[BC] Upgraded dependencies, dropped support for anything below PHP 8.0. (#849)
* GitHub actions + style fixes + updated packages * Fixed workflows dir * Support for PHP 8.1 (#1) * Update README.md * Revert some changes from upstream
This commit is contained in:
parent
72c946dc7d
commit
111c153428
335 changed files with 4394 additions and 28116 deletions
83
tests/FFMpeg/Unit/Coordinate/AspectRatioTest.php
Normal file
83
tests/FFMpeg/Unit/Coordinate/AspectRatioTest.php
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Coordinate;
|
||||
|
||||
use FFMpeg\Coordinate\AspectRatio;
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AspectRatioTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideDimensionsAndExpectedratio
|
||||
*/
|
||||
public function testFromDimensions($width, $height, $strategy, $expected, $calculatedWidth, $calculatedHeight, $modulus = 2)
|
||||
{
|
||||
$ratio = AspectRatio::create(new Dimension($width, $height), $strategy);
|
||||
$this->assertEquals($expected, $ratio->getValue());
|
||||
|
||||
$this->assertEquals($calculatedHeight, $ratio->calculateHeight(240, $modulus));
|
||||
$this->assertEquals($calculatedWidth, $ratio->calculateWidth(320, $modulus));
|
||||
}
|
||||
|
||||
public function provideDimensionsAndExpectedratio()
|
||||
{
|
||||
return [
|
||||
//AR_5_4
|
||||
[720, 576, false, 5 / 4, 400, 192],
|
||||
[720, 577, false, 5 / 4, 400, 192],
|
||||
[720, 620, false, 720 / 620, 372, 206],
|
||||
[720, 576, true, 5 / 4, 400, 192],
|
||||
//AR_ROTATED_4_5
|
||||
[576, 720, false, 4 / 5, 256, 300],
|
||||
[576, 720, true, 4 / 5, 256, 300],
|
||||
//AR_4_3
|
||||
[320, 240, false, 4 / 3, 426, 180],
|
||||
[320, 240, true, 4 / 3, 426, 180],
|
||||
//AR_ROTATED_3_4
|
||||
[240, 320, false, 3 / 4, 240, 320],
|
||||
[240, 320, true, 3 / 4, 240, 320],
|
||||
//AR_16_9
|
||||
[1920, 1080, false, 16 / 9, 568, 136],
|
||||
[1920, 1080, true, 16 / 9, 568, 136],
|
||||
[1280, 720, false, 16 / 9, 568, 136],
|
||||
[1280, 720, true, 16 / 9, 568, 136],
|
||||
[3840, 2160, false, 16 / 9, 568, 136],
|
||||
[3840, 2160, true, 16 / 9, 568, 136],
|
||||
// modulus 4
|
||||
[1920, 1080, false, 16 / 9, 568, 136, 4],
|
||||
[1920, 1080, true, 16 / 9, 568, 136, 4],
|
||||
[1280, 720, false, 16 / 9, 568, 136, 4],
|
||||
[1280, 720, true, 16 / 9, 568, 136, 4],
|
||||
[3840, 2160, false, 16 / 9, 568, 136, 4],
|
||||
[3840, 2160, true, 16 / 9, 568, 136, 4],
|
||||
// modulus 16
|
||||
[1920, 1080, false, 16 / 9, 576, 128, 16],
|
||||
[1920, 1080, true, 16 / 9, 576, 128, 16],
|
||||
[1280, 720, false, 16 / 9, 576, 128, 16],
|
||||
[1280, 720, true, 16 / 9, 576, 128, 16],
|
||||
[3840, 2160, false, 16 / 9, 576, 128, 16],
|
||||
[3840, 2160, true, 16 / 9, 576, 128, 16],
|
||||
//AR_ROTATED_9_16
|
||||
[1080, 1920, false, 9 / 16, 180, 426],
|
||||
[1080, 1920, true, 9 / 16, 180, 426],
|
||||
[720, 1280, false, 9 / 16, 180, 426],
|
||||
[720, 1280, true, 9 / 16, 180, 426],
|
||||
[2160, 3840, false, 9 / 16, 180, 426],
|
||||
[2160, 3840, true, 9 / 16, 180, 426],
|
||||
//AR_3_2
|
||||
[360, 240, false, 3 / 2, 480, 160],
|
||||
[360, 240, true, 3 / 2, 480, 160],
|
||||
//AR_ROTATED_2_3
|
||||
[240, 360, false, 2 / 3, 214, 360],
|
||||
[240, 360, true, 2 / 3, 214, 360],
|
||||
//AR_5_3
|
||||
//AR_ROTATED_3_5
|
||||
//AR_1_1
|
||||
//AR_1_DOT_85_1
|
||||
//AR_ROTATED_1_DOT_85
|
||||
//AR_2_DOT_39_1
|
||||
//AR_ROTATED_2_DOT_39
|
||||
];
|
||||
}
|
||||
}
|
||||
38
tests/FFMpeg/Unit/Coordinate/DimensionTest.php
Normal file
38
tests/FFMpeg/Unit/Coordinate/DimensionTest.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Coordinate;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class DimensionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideInvalidDimensions
|
||||
*/
|
||||
public function testInvalidDimensions($width, $height)
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
new Dimension($width, $height);
|
||||
}
|
||||
|
||||
public function provideInvalidDimensions()
|
||||
{
|
||||
return [
|
||||
[320, 0],
|
||||
[320, -10],
|
||||
[0, 240],
|
||||
[-10, 240],
|
||||
[0, 0],
|
||||
[0, -10],
|
||||
[-10, 0],
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetters()
|
||||
{
|
||||
$dimension = new Dimension(320, 240);
|
||||
$this->assertEquals(320, $dimension->getWidth());
|
||||
$this->assertEquals(240, $dimension->getHeight());
|
||||
}
|
||||
}
|
||||
31
tests/FFMpeg/Unit/Coordinate/FrameRateTest.php
Normal file
31
tests/FFMpeg/Unit/Coordinate/FrameRateTest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Coordinate;
|
||||
|
||||
use FFMpeg\Coordinate\FrameRate;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class FrameRateTest extends TestCase
|
||||
{
|
||||
public function testGetter()
|
||||
{
|
||||
$fr = new FrameRate(23.997);
|
||||
$this->assertEquals(23.997, $fr->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidFrameRates
|
||||
*/
|
||||
public function testInvalidFrameRate($value)
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
new FrameRate($value);
|
||||
}
|
||||
|
||||
public function provideInvalidFrameRates()
|
||||
{
|
||||
return [
|
||||
[0], [-1.5], [-2],
|
||||
];
|
||||
}
|
||||
}
|
||||
23
tests/FFMpeg/Unit/Coordinate/PointTest.php
Normal file
23
tests/FFMpeg/Unit/Coordinate/PointTest.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Coordinate;
|
||||
|
||||
use FFMpeg\Coordinate\Point;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class PointTest extends TestCase
|
||||
{
|
||||
public function testGetters()
|
||||
{
|
||||
$point = new Point(4, 25);
|
||||
$this->assertEquals(4, $point->getX());
|
||||
$this->assertEquals(25, $point->getY());
|
||||
}
|
||||
|
||||
public function testDynamicPointGetters()
|
||||
{
|
||||
$point = new Point('t*100', 't', true);
|
||||
$this->assertEquals('t*100', $point->getX());
|
||||
$this->assertEquals('t', $point->getY());
|
||||
}
|
||||
}
|
||||
58
tests/FFMpeg/Unit/Coordinate/TimeCodeTest.php
Normal file
58
tests/FFMpeg/Unit/Coordinate/TimeCodeTest.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Coordinate;
|
||||
|
||||
use FFMpeg\Coordinate\TimeCode;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class TimeCodeTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTimecodes
|
||||
*/
|
||||
public function testFromString($timecode, $expected)
|
||||
{
|
||||
$tc = TimeCode::fromString($timecode);
|
||||
$this->assertEquals((string) $tc, $expected);
|
||||
}
|
||||
|
||||
public function provideTimeCodes()
|
||||
{
|
||||
return [
|
||||
['1:02:04:05:20', '26:04:05.20'],
|
||||
['1:02:04:05.20', '26:04:05.20'],
|
||||
['02:04:05:20', '02:04:05.20'],
|
||||
['02:04:05.20', '02:04:05.20'],
|
||||
['00:00:05.20', '00:00:05.20'],
|
||||
['00:00:00.00', '00:00:00.00'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testFromInvalidString()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
TimeCode::fromString('lalali lala');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSeconds
|
||||
*/
|
||||
public function testFromSeconds($seconds, $expected)
|
||||
{
|
||||
$tc = TimeCode::fromSeconds($seconds);
|
||||
$this->assertEquals($expected, (string) $tc);
|
||||
}
|
||||
|
||||
public function provideSeconds()
|
||||
{
|
||||
return [
|
||||
[0.467, '00:00:00.47'],
|
||||
[12.467, '00:00:12.47'],
|
||||
[59.867, '00:00:59.87'],
|
||||
[72.467, '00:01:12.47'],
|
||||
[3599.467, '00:59:59.47'],
|
||||
[3600.467, '01:00:00.47'],
|
||||
[86422.467, '24:00:22.47'],
|
||||
];
|
||||
}
|
||||
}
|
||||
49
tests/FFMpeg/Unit/Driver/FFMpegDriverTest.php
Normal file
49
tests/FFMpeg/Unit/Driver/FFMpegDriverTest.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Driver;
|
||||
|
||||
use Alchemy\BinaryDriver\Configuration;
|
||||
use FFMpeg\Driver\FFMpegDriver;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class FFMpegDriverTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$executableFinder = new ExecutableFinder();
|
||||
|
||||
$found = false;
|
||||
foreach (['avconv', 'ffmpeg'] as $name) {
|
||||
if (null !== $executableFinder->find($name)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->markTestSkipped('Neither ffmpeg or avconv found');
|
||||
}
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
$logger = $this->getLoggerMock();
|
||||
$ffmpeg = FFMpegDriver::create($logger, []);
|
||||
$this->assertInstanceOf('FFMpeg\Driver\FFMpegDriver', $ffmpeg);
|
||||
$this->assertEquals($logger, $ffmpeg->getProcessRunner()->getLogger());
|
||||
}
|
||||
|
||||
public function testCreateWithConfig()
|
||||
{
|
||||
$conf = new Configuration();
|
||||
$ffmpeg = FFMpegDriver::create($this->getLoggerMock(), $conf);
|
||||
$this->assertEquals($conf, $ffmpeg->getConfiguration());
|
||||
}
|
||||
|
||||
public function testCreateFailureThrowsAnException()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\ExecutableNotFoundException');
|
||||
FFMpegDriver::create($this->getLoggerMock(), ['ffmpeg.binaries' => '/path/to/nowhere']);
|
||||
}
|
||||
}
|
||||
49
tests/FFMpeg/Unit/Driver/FFProbeDriverTest.php
Normal file
49
tests/FFMpeg/Unit/Driver/FFProbeDriverTest.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Driver;
|
||||
|
||||
use Alchemy\BinaryDriver\Configuration;
|
||||
use FFMpeg\Driver\FFProbeDriver;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class FFProbeDriverTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$executableFinder = new ExecutableFinder();
|
||||
|
||||
$found = false;
|
||||
foreach (['avprobe', 'ffprobe'] as $name) {
|
||||
if (null !== $executableFinder->find($name)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->markTestSkipped('Neither ffprobe or avprobe found');
|
||||
}
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
$logger = $this->getLoggerMock();
|
||||
$ffprobe = FFProbeDriver::create([], $logger);
|
||||
$this->assertInstanceOf('FFMpeg\Driver\FFProbeDriver', $ffprobe);
|
||||
$this->assertEquals($logger, $ffprobe->getProcessRunner()->getLogger());
|
||||
}
|
||||
|
||||
public function testCreateWithConfig()
|
||||
{
|
||||
$conf = new Configuration();
|
||||
$ffprobe = FFProbeDriver::create($conf, $this->getLoggerMock());
|
||||
$this->assertEquals($conf, $ffprobe->getConfiguration());
|
||||
}
|
||||
|
||||
public function testCreateFailureThrowsAnException()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\ExecutableNotFoundException');
|
||||
FFProbeDriver::create(['ffprobe.binaries' => '/path/to/nowhere']);
|
||||
}
|
||||
}
|
||||
110
tests/FFMpeg/Unit/FFMpegTest.php
Normal file
110
tests/FFMpeg/Unit/FFMpegTest.php
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit;
|
||||
|
||||
use FFMpeg\FFMpeg;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
|
||||
class FFMpegTest extends TestCase
|
||||
{
|
||||
public function testOpenInvalid()
|
||||
{
|
||||
$this->expectException(
|
||||
'\FFMpeg\Exception\RuntimeException',
|
||||
'Unable to probe "/path/to/unknown/file"'
|
||||
);
|
||||
$ffmpeg = new FFMpeg($this->getFFMpegDriverMock(), $this->getFFProbeMock());
|
||||
$ffmpeg->open('/path/to/unknown/file');
|
||||
}
|
||||
|
||||
public function testOpenAudio()
|
||||
{
|
||||
$streams = $this->getStreamCollectionMock();
|
||||
$streams->expects($this->once())
|
||||
->method('audios')
|
||||
->will($this->returnValue(new StreamCollection([new Stream([])])));
|
||||
$streams->expects($this->once())
|
||||
->method('videos')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('streams')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$ffmpeg = new FFMpeg($this->getFFMpegDriverMock(), $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\Media\Audio', $ffmpeg->open(__FILE__));
|
||||
}
|
||||
|
||||
public function testOpenVideo()
|
||||
{
|
||||
$streams = $this->getStreamCollectionMock();
|
||||
$streams->expects($this->once())
|
||||
->method('videos')
|
||||
->will($this->returnValue(new StreamCollection([new Stream([])])));
|
||||
$streams->expects($this->never())
|
||||
->method('audios');
|
||||
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('streams')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$ffmpeg = new FFMpeg($this->getFFMpegDriverMock(), $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\Media\Video', $ffmpeg->open(__FILE__));
|
||||
}
|
||||
|
||||
public function testOpenUnknown()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('streams')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue(new StreamCollection()));
|
||||
|
||||
$ffmpeg = new FFMpeg($this->getFFMpegDriverMock(), $ffprobe);
|
||||
$ffmpeg->open(__FILE__);
|
||||
}
|
||||
|
||||
public function testCreateWithoutLoggerOrProbe()
|
||||
{
|
||||
$this->assertInstanceOf('FFMpeg\FFMpeg', FFMpeg::create());
|
||||
}
|
||||
|
||||
public function testCreateWithLoggerAndProbe()
|
||||
{
|
||||
$logger = $this->getLoggerMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$ffmpeg = FFMpeg::create(['timeout' => 42], $logger, $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\FFMpeg', $ffmpeg);
|
||||
|
||||
$this->assertSame($logger, $ffmpeg->getFFMpegDriver()->getProcessRunner()->getLogger());
|
||||
$this->assertSame($ffprobe, $ffmpeg->getFFProbe());
|
||||
$this->assertSame(42, $ffmpeg->getFFMpegDriver()->getProcessBuilderFactory()->getTimeout());
|
||||
}
|
||||
|
||||
public function testGetSetFFProbe()
|
||||
{
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$ffmpeg = new FFMpeg($this->getFFMpegDriverMock(), $ffprobe);
|
||||
$this->assertSame($ffprobe, $ffmpeg->getFFProbe());
|
||||
$anotherFFProbe = $this->getFFProbeMock();
|
||||
$ffmpeg->setFFProbe($anotherFFProbe);
|
||||
$this->assertSame($anotherFFProbe, $ffmpeg->getFFProbe());
|
||||
}
|
||||
|
||||
public function testGetSetDriver()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffmpeg = new FFMpeg($driver, $this->getFFProbeMock());
|
||||
$this->assertSame($driver, $ffmpeg->getFFMpegDriver());
|
||||
$anotherDriver = $this->getFFMpegDriverMock();
|
||||
$ffmpeg->setFFMpegDriver($anotherDriver);
|
||||
$this->assertSame($anotherDriver, $ffmpeg->getFFMpegDriver());
|
||||
}
|
||||
}
|
||||
52
tests/FFMpeg/Unit/FFProbe/DataMapping/AbstractDataTest.php
Normal file
52
tests/FFMpeg/Unit/FFProbe/DataMapping/AbstractDataTest.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\FFProbe\DataMapping;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\AbstractData;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AbstractDataTest extends TestCase
|
||||
{
|
||||
public function testHas()
|
||||
{
|
||||
$imp = new Implementation(['key1' => 'value1', 'key2' => 'value2']);
|
||||
|
||||
$this->assertTrue($imp->has('key1'));
|
||||
$this->assertTrue($imp->has('key2'));
|
||||
$this->assertFalse($imp->has('value1'));
|
||||
$this->assertFalse($imp->has('key3'));
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$imp = new Implementation(['key1' => 'value1', 'key2' => 'value2']);
|
||||
|
||||
$this->assertEquals('value1', $imp->get('key1'));
|
||||
$this->assertEquals('value2', $imp->get('key2'));
|
||||
}
|
||||
|
||||
public function testGetDefault()
|
||||
{
|
||||
$imp = new Implementation(['key1' => 'value1', 'key2' => 'value2']);
|
||||
$this->assertSame('yololo', $imp->get('key3', 'yololo'));
|
||||
}
|
||||
|
||||
public function testKeys()
|
||||
{
|
||||
$imp = new Implementation(['key1' => 'value1', 'key2' => 'value2']);
|
||||
|
||||
$this->assertEquals(['key1', 'key2'], $imp->keys());
|
||||
}
|
||||
|
||||
public function testAll()
|
||||
{
|
||||
$values = ['key1' => 'value1', 'key2' => 'value2'];
|
||||
$imp = new Implementation($values);
|
||||
|
||||
$this->assertEquals($values, $imp->all());
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation extends AbstractData
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\FFProbe\DataMapping;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class StreamCollectionTest extends TestCase
|
||||
{
|
||||
public function testAdd()
|
||||
{
|
||||
$stream = $this->getStreamMock();
|
||||
|
||||
$collection = new StreamCollection();
|
||||
$this->assertEquals([], $collection->all());
|
||||
$collection->add($stream);
|
||||
$this->assertEquals([$stream], $collection->all());
|
||||
$collection->add($stream);
|
||||
$this->assertEquals([$stream, $stream], $collection->all());
|
||||
}
|
||||
|
||||
public function testVideos()
|
||||
{
|
||||
$audio = $this->getStreamMock();
|
||||
$audio->expects($this->once())
|
||||
->method('isVideo')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$video = $this->getStreamMock();
|
||||
$video->expects($this->once())
|
||||
->method('isVideo')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$collection = new StreamCollection([$audio, $video]);
|
||||
$videos = $collection->videos();
|
||||
|
||||
$this->assertInstanceOf('FFMpeg\FFProbe\DataMapping\StreamCollection', $videos);
|
||||
$this->assertCount(1, $videos);
|
||||
$this->assertEquals([$video], $videos->all());
|
||||
}
|
||||
|
||||
public function testAudios()
|
||||
{
|
||||
$audio = $this->getStreamMock();
|
||||
$audio->expects($this->once())
|
||||
->method('isAudio')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$video = $this->getStreamMock();
|
||||
$video->expects($this->once())
|
||||
->method('isAudio')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$collection = new StreamCollection([$audio, $video]);
|
||||
$audios = $collection->audios();
|
||||
|
||||
$this->assertInstanceOf('FFMpeg\FFProbe\DataMapping\StreamCollection', $audios);
|
||||
$this->assertCount(1, $audios);
|
||||
$this->assertEquals([$audio], $audios->all());
|
||||
}
|
||||
|
||||
public function testCount()
|
||||
{
|
||||
$stream = $this->getStreamMock();
|
||||
|
||||
$collection = new StreamCollection([$stream]);
|
||||
$this->assertCount(1, $collection);
|
||||
}
|
||||
|
||||
public function testGetIterator()
|
||||
{
|
||||
$audio = $this->getStreamMock();
|
||||
$video = $this->getStreamMock();
|
||||
|
||||
$collection = new StreamCollection([$audio, $video]);
|
||||
$this->assertInstanceOf('\Iterator', $collection->getIterator());
|
||||
$this->assertCount(2, $collection->getIterator());
|
||||
}
|
||||
|
||||
public function testFirst()
|
||||
{
|
||||
$stream1 = $this->getStreamMock();
|
||||
$stream2 = $this->getStreamMock();
|
||||
|
||||
$coll = new StreamCollection([$stream1, $stream2]);
|
||||
|
||||
$this->assertSame($stream1, $coll->first());
|
||||
}
|
||||
}
|
||||
136
tests/FFMpeg/Unit/FFProbe/DataMapping/StreamTest.php
Normal file
136
tests/FFMpeg/Unit/FFProbe/DataMapping/StreamTest.php
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\FFProbe\DataMapping;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class StreamTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideAudioCases
|
||||
*/
|
||||
public function testIsAudio($isAudio, $properties)
|
||||
{
|
||||
$stream = new Stream($properties);
|
||||
$this->assertTrue($isAudio === $stream->isAudio());
|
||||
}
|
||||
|
||||
public function provideAudioCases()
|
||||
{
|
||||
return [
|
||||
[true, ['codec_type' => 'audio']],
|
||||
[false, ['codec_type' => 'video']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideVideoCases
|
||||
*/
|
||||
public function testIsVideo($isVideo, $properties)
|
||||
{
|
||||
$stream = new Stream($properties);
|
||||
$this->assertTrue($isVideo === $stream->isVideo());
|
||||
}
|
||||
|
||||
public function provideVideoCases()
|
||||
{
|
||||
return [
|
||||
[true, ['codec_type' => 'video']],
|
||||
[false, ['codec_type' => 'audio']],
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetDimensionsFromAudio()
|
||||
{
|
||||
$this->expectException(
|
||||
'\FFMpeg\Exception\LogicException',
|
||||
'Dimensions can only be retrieved from video streams.'
|
||||
);
|
||||
$stream = new Stream(['codec_type' => 'audio']);
|
||||
$stream->getDimensions();
|
||||
}
|
||||
|
||||
public function testGetDimensionsFromVideo()
|
||||
{
|
||||
$stream = new Stream(['codec_type' => 'video', 'width' => 960, 'height' => 720]);
|
||||
$this->assertEquals(new Dimension(960, 720), $stream->getDimensions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidPropertiesForDimensionsExtraction
|
||||
*/
|
||||
public function testUnableToGetDimensionsFromVideo($properties)
|
||||
{
|
||||
$this->expectException(
|
||||
'\FFMpeg\Exception\RuntimeException',
|
||||
'Unable to extract dimensions.'
|
||||
);
|
||||
$stream = new Stream(['codec_type' => 'video', 'width' => 960]);
|
||||
$stream->getDimensions();
|
||||
}
|
||||
|
||||
public function provideInvalidPropertiesForDimensionsExtraction()
|
||||
{
|
||||
return [
|
||||
['codec_type' => 'video', 'width' => 960],
|
||||
['codec_type' => 'video', 'height' => 960],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePropertiesForDimensionsExtraction
|
||||
*/
|
||||
public function testGetDimensionsFromVideoWithDisplayRatio($data)
|
||||
{
|
||||
$stream = new Stream([
|
||||
'codec_type' => 'video',
|
||||
'width' => $data['width'],
|
||||
'height' => $data['height'],
|
||||
'sample_aspect_ratio' => $data['sar'],
|
||||
'display_aspect_ratio' => $data['dar'],
|
||||
]);
|
||||
$this->assertEquals(new Dimension($data['result_width'], $data['result_height']), $stream->getDimensions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidRatios
|
||||
*/
|
||||
public function testGetDimensionsFromVideoWithInvalidDisplayRatio($invalidRatio)
|
||||
{
|
||||
$stream = new Stream(['codec_type' => 'video', 'width' => 960, 'height' => 720, 'sample_aspect_ratio' => $invalidRatio, 'display_aspect_ratio' => '16:9']);
|
||||
$this->assertEquals(new Dimension(960, 720), $stream->getDimensions());
|
||||
}
|
||||
|
||||
public function provideInvalidRatios()
|
||||
{
|
||||
return [['0:1'], ['2:1:3']];
|
||||
}
|
||||
|
||||
public function providePropertiesForDimensionsExtraction()
|
||||
{
|
||||
return [
|
||||
[
|
||||
['width' => '960', 'height' => '720',
|
||||
'sar' => '4:3', 'dar' => '16:9',
|
||||
'result_width' => '1280', 'result_height' => '720', ],
|
||||
],
|
||||
[
|
||||
['width' => '1920', 'height' => '1080',
|
||||
'sar' => '1:1', 'dar' => '16:9',
|
||||
'result_width' => '1920', 'result_height' => '1080', ],
|
||||
],
|
||||
[
|
||||
['width' => '640', 'height' => '480',
|
||||
'sar' => '75:74', 'dar' => '50:37',
|
||||
'result_width' => '649', 'result_height' => '480', ],
|
||||
],
|
||||
[
|
||||
['width' => '720', 'height' => '576',
|
||||
'sar' => '52:28', 'dar' => '16:9',
|
||||
'result_width' => '1337', 'result_height' => '752', ],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
42
tests/FFMpeg/Unit/FFProbe/MapperTest.php
Normal file
42
tests/FFMpeg/Unit/FFProbe/MapperTest.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\FFProbe;
|
||||
|
||||
use FFMpeg\FFProbe;
|
||||
use FFMpeg\FFProbe\DataMapping\Format;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\FFProbe\Mapper;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class MapperTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideMappings
|
||||
*/
|
||||
public function testMap($type, $data, $expected)
|
||||
{
|
||||
$mapper = new Mapper();
|
||||
$this->assertEquals($expected, $mapper->map($type, $data));
|
||||
}
|
||||
|
||||
public function testMapInvalidArgument()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$mapper = new Mapper();
|
||||
$mapper->map('cool type', 'data');
|
||||
}
|
||||
|
||||
public function provideMappings()
|
||||
{
|
||||
$format = json_decode(file_get_contents(__DIR__.'/../../fixtures/ffprobe/show_format.json'), true);
|
||||
$streams = json_decode(file_get_contents(__DIR__.'/../../fixtures/ffprobe/show_streams.json'), true);
|
||||
|
||||
return [
|
||||
[FFProbe::TYPE_FORMAT, $format, new Format($format['format'])],
|
||||
[FFProbe::TYPE_STREAMS, $streams, new StreamCollection(array_map(function ($streamData) {
|
||||
return new Stream($streamData);
|
||||
}, $streams['streams']))],
|
||||
];
|
||||
}
|
||||
}
|
||||
132
tests/FFMpeg/Unit/FFProbe/OptionsTesterTest.php
Normal file
132
tests/FFMpeg/Unit/FFProbe/OptionsTesterTest.php
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\FFProbe;
|
||||
|
||||
use FFMpeg\FFProbe\OptionsTester;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class OptionsTesterTest extends TestCase
|
||||
{
|
||||
public function testHasOptionWithOldFFProbe()
|
||||
{
|
||||
$this->expectException(
|
||||
'\FFMpeg\Exception\RuntimeException',
|
||||
'Your FFProbe version is too old and does not support `-help` option, please upgrade.'
|
||||
);
|
||||
$cache = $this->getCacheMock();
|
||||
|
||||
$executionFailerExceptionMock = $this->getMockBuilder('Alchemy\BinaryDriver\Exception\ExecutionFailureException')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$ffprobe = $this->getFFProbeDriverMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('command')
|
||||
->with(['-help', '-loglevel', 'quiet'])
|
||||
->will($this->throwException($executionFailerExceptionMock));
|
||||
|
||||
$tester = new OptionsTester($ffprobe, $cache);
|
||||
$tester->has('-print_format');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideOptions
|
||||
*/
|
||||
public function testHasOptionWithCacheEmpty($isPresent, $data, $optionName)
|
||||
{
|
||||
$cache = $this->getCacheMock();
|
||||
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('getItem')
|
||||
->will($this->returnValue(new CacheItem));
|
||||
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('hasItem')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('save');
|
||||
|
||||
$ffprobe = $this->getFFProbeDriverMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('command')
|
||||
->with(['-help', '-loglevel', 'quiet'])
|
||||
->will($this->returnValue($data));
|
||||
|
||||
$tester = new OptionsTester($ffprobe, $cache);
|
||||
$this->assertTrue($isPresent === $tester->has($optionName));
|
||||
}
|
||||
|
||||
public function provideOptions()
|
||||
{
|
||||
$data = file_get_contents(__DIR__ . '/../../fixtures/ffprobe/help.raw');
|
||||
|
||||
return [
|
||||
[true, $data, '-print_format'],
|
||||
[false, $data, '-another_print_format'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideOptions
|
||||
*/
|
||||
public function testHasOptionWithHelpCacheLoaded($isPresent, $data, $optionName)
|
||||
{
|
||||
$cache = $this->getCacheMock();
|
||||
|
||||
$cacheItem = new CacheItem;
|
||||
$cacheItem->set($data);
|
||||
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('getItem')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
$this->returnValue($cacheItem),
|
||||
$this->returnValue(new CacheItem)
|
||||
);
|
||||
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('hasItem')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
$this->returnValue(false),
|
||||
$this->returnValue(true)
|
||||
);
|
||||
$cache->expects($this->once())
|
||||
->method('save');
|
||||
|
||||
$ffprobe = $this->getFFProbeDriverMock();
|
||||
$ffprobe->expects($this->never())
|
||||
->method('command');
|
||||
|
||||
$tester = new OptionsTester($ffprobe, $cache);
|
||||
$this->assertTrue($isPresent === $tester->has($optionName));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideOptions
|
||||
*/
|
||||
public function testHasOptionWithCacheFullyLoaded($isPresent, $data, $optionName)
|
||||
{
|
||||
$cache = $this->getCacheMock();
|
||||
|
||||
$cacheItem = new CacheItem();
|
||||
$cacheItem->set($isPresent);
|
||||
|
||||
$cache->expects($this->once())
|
||||
->method('getItem')
|
||||
->with(md5('option-' . $optionName))
|
||||
->will($this->returnValue($cacheItem));
|
||||
|
||||
$cache->expects($this->once())
|
||||
->method('hasItem')
|
||||
->with(md5('option-' . $optionName))
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$ffprobe = $this->getFFProbeDriverMock();
|
||||
$ffprobe->expects($this->never())
|
||||
->method('command');
|
||||
|
||||
$tester = new OptionsTester($ffprobe, $cache);
|
||||
$this->assertTrue($isPresent === $tester->has($optionName));
|
||||
}
|
||||
}
|
||||
40
tests/FFMpeg/Unit/FFProbe/OutputParserTest.php
Normal file
40
tests/FFMpeg/Unit/FFProbe/OutputParserTest.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\FFProbe;
|
||||
|
||||
use FFMpeg\FFProbe;
|
||||
use FFMpeg\FFProbe\OutputParser;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class OutputParserTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTypeDataAndOutput
|
||||
*/
|
||||
public function testParse($type, $data, $expectedOutput)
|
||||
{
|
||||
$parser = new OutputParser();
|
||||
$this->assertEquals($expectedOutput, $parser->parse($type, $data));
|
||||
}
|
||||
|
||||
public function testParseWithInvalidArgument()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$parser = new OutputParser();
|
||||
$parser->parse('comme ca', 'data');
|
||||
}
|
||||
|
||||
public function provideTypeDataAndOutput()
|
||||
{
|
||||
$expectedFormat = json_decode(file_get_contents(__DIR__.'/../../fixtures/ffprobe/show_format.json'), true);
|
||||
$expectedStreams = json_decode(file_get_contents(__DIR__.'/../../fixtures/ffprobe/show_streams.json'), true);
|
||||
|
||||
$rawFormat = file_get_contents(__DIR__.'/../../fixtures/ffprobe/show_format.raw');
|
||||
$rawStreams = file_get_contents(__DIR__.'/../../fixtures/ffprobe/show_streams.raw');
|
||||
|
||||
return [
|
||||
[FFProbe::TYPE_FORMAT, $rawFormat, $expectedFormat],
|
||||
[FFProbe::TYPE_STREAMS, $rawStreams, $expectedStreams],
|
||||
];
|
||||
}
|
||||
}
|
||||
301
tests/FFMpeg/Unit/FFProbeTest.php
Normal file
301
tests/FFMpeg/Unit/FFProbeTest.php
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit;
|
||||
|
||||
use Alchemy\BinaryDriver\Configuration;
|
||||
use Alchemy\BinaryDriver\ConfigurationInterface;
|
||||
use FFMpeg\FFProbe;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
|
||||
class FFProbeTest extends TestCase
|
||||
{
|
||||
public function testGetSetParser()
|
||||
{
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
$parser = $this->getFFProbeParserMock();
|
||||
|
||||
$ffprobe->setParser($parser);
|
||||
$this->assertSame($parser, $ffprobe->getParser());
|
||||
}
|
||||
|
||||
public function testGetSetFFProbeDriver()
|
||||
{
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
$driver = $this->getFFProbeDriverMock();
|
||||
|
||||
$ffprobe->setFFProbeDriver($driver);
|
||||
$this->assertSame($driver, $ffprobe->getFFProbeDriver());
|
||||
}
|
||||
|
||||
public function testGetSetFFProbeMapper()
|
||||
{
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
$mapper = $this->getFFProbeMapperMock();
|
||||
|
||||
$ffprobe->setMapper($mapper);
|
||||
$this->assertSame($mapper, $ffprobe->getMapper());
|
||||
}
|
||||
|
||||
public function testGetSetOptionsTester()
|
||||
{
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
$tester = $this->getFFProbeOptionsTesterMock();
|
||||
|
||||
$ffprobe->setOptionsTester($tester);
|
||||
$this->assertSame($tester, $ffprobe->getOptionsTester());
|
||||
}
|
||||
|
||||
public function testGetSetCache()
|
||||
{
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
$cache = $this->getCacheMock();
|
||||
|
||||
$ffprobe->setCache($cache);
|
||||
$this->assertSame($cache, $ffprobe->getCache());
|
||||
}
|
||||
|
||||
public function provideDataWhitoutCache()
|
||||
{
|
||||
$stream = $this->getStreamMock();
|
||||
$format = $this->getFormatMock();
|
||||
|
||||
return [
|
||||
[$stream, 'streams', ['-show_streams', '-print_format'], FFProbe::TYPE_STREAMS, [__FILE__, '-show_streams', '-print_format', 'json'], false],
|
||||
[$format, 'format', ['-show_format', '-print_format'], FFProbe::TYPE_FORMAT, [__FILE__, '-show_format', '-print_format', 'json'], false],
|
||||
[$stream, 'streams', ['-show_streams'], FFProbe::TYPE_STREAMS, [__FILE__, '-show_streams'], true],
|
||||
[$format, 'format', ['-show_format'], FFProbe::TYPE_FORMAT, [__FILE__, '-show_format'], true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDataWhitoutCache
|
||||
*/
|
||||
public function testProbeWithoutCache($output, $method, $commands, $type, $caughtCommands, $isRaw)
|
||||
{
|
||||
$pathfile = __FILE__;
|
||||
$data = ['key' => 'value'];
|
||||
$rawData = 'raw data';
|
||||
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
|
||||
$mapper = $this->getFFProbeMapperMock();
|
||||
$mapper->expects($this->once())
|
||||
->method('map')
|
||||
->with($type, $data)
|
||||
->will($this->returnValue($output));
|
||||
|
||||
$parser = $this->getFFProbeParserMock();
|
||||
|
||||
if ($isRaw) {
|
||||
$parser->expects($this->once())
|
||||
->method('parse')
|
||||
->with($type, $rawData)
|
||||
->will($this->returnValue($data));
|
||||
} else {
|
||||
$parser->expects($this->never())
|
||||
->method('parse');
|
||||
}
|
||||
|
||||
$tester = $this->getFFProbeOptionsTesterMockWithOptions($commands);
|
||||
|
||||
$cache = $this->getCacheMock();
|
||||
$cache->expects($this->once())
|
||||
->method('hasItem')
|
||||
->will($this->returnValue(false));
|
||||
$cache->expects($this->once())
|
||||
->method('getItem')
|
||||
->will($this->returnValue(new CacheItem));
|
||||
$cache->expects($this->once())
|
||||
->method('save')
|
||||
->with($this->anything());
|
||||
|
||||
$driver = $this->getFFProbeDriverMock();
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($caughtCommands)
|
||||
->will($this->returnValue($isRaw ? $rawData : json_encode($data)));
|
||||
|
||||
$ffprobe->setOptionsTester($tester)
|
||||
->setCache($cache)
|
||||
->setMapper($mapper)
|
||||
->setFFProbeDriver($driver)
|
||||
->setParser($parser);
|
||||
|
||||
$this->assertEquals($output, call_user_func([$ffprobe, $method], $pathfile));
|
||||
}
|
||||
|
||||
public function provideDataForInvalidJson()
|
||||
{
|
||||
$stream = $this->getStreamMock();
|
||||
$format = $this->getFormatMock();
|
||||
|
||||
return [
|
||||
[$stream, 'streams', ['-show_streams', '-print_format'], FFProbe::TYPE_STREAMS, [__FILE__, '-show_streams', '-print_format', 'json']],
|
||||
[$format, 'format', ['-show_format', '-print_format'], FFProbe::TYPE_FORMAT, [__FILE__, '-show_format', '-print_format', 'json']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDataForInvalidJson
|
||||
*/
|
||||
public function testProbeWithWrongJson($output, $method, $commands, $type, $caughtCommands)
|
||||
{
|
||||
$pathfile = __FILE__;
|
||||
$data = ['key' => 'value'];
|
||||
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
|
||||
$mapper = $this->getFFProbeMapperMock();
|
||||
$mapper->expects($this->once())
|
||||
->method('map')
|
||||
->with($this->isType('string'), 'good data parsed')
|
||||
->will($this->returnValue($output));
|
||||
|
||||
$parser = $this->getFFProbeParserMock();
|
||||
$parser->expects($this->once())
|
||||
->method('parse')
|
||||
->with($this->isType('string', json_encode($data).'lala'))
|
||||
->will($this->returnValue('good data parsed'));
|
||||
|
||||
$tester = $this->getFFProbeOptionsTesterMockWithOptions($commands);
|
||||
|
||||
$cache = $this->getCacheMock();
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('hasItem')
|
||||
->will($this->returnValue(false));
|
||||
$cache->expects($this->once())
|
||||
->method('getItem')
|
||||
->will($this->returnValue(new CacheItem));
|
||||
|
||||
$driver = $this->getFFProbeDriverMock();
|
||||
$driver->expects($this->exactly(2))
|
||||
->method('command')
|
||||
->will($this->returnValue(json_encode($data).'lala'));
|
||||
|
||||
$ffprobe->setOptionsTester($tester)
|
||||
->setCache($cache)
|
||||
->setMapper($mapper)
|
||||
->setFFProbeDriver($driver)
|
||||
->setParser($parser);
|
||||
|
||||
$this->assertEquals($output, call_user_func([$ffprobe, $method], $pathfile));
|
||||
}
|
||||
|
||||
public function provideProbingDataWithCache()
|
||||
{
|
||||
$stream = $this->getStreamMock();
|
||||
$format = $this->getFormatMock();
|
||||
|
||||
return [
|
||||
[$stream, 'streams'],
|
||||
[$format, 'format'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideProbingDataWithCache
|
||||
*/
|
||||
public function testProbeWithCache($output, $method)
|
||||
{
|
||||
$pathfile = __FILE__;
|
||||
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
|
||||
$mapper = $this->getFFProbeMapperMock();
|
||||
$mapper->expects($this->never())
|
||||
->method('map');
|
||||
|
||||
$tester = $this->getFFProbeOptionsTesterMock();
|
||||
|
||||
$cacheItem = new CacheItem;
|
||||
$cacheItem->set($output);
|
||||
|
||||
$cache = $this->getCacheMock();
|
||||
$cache->expects($this->once())
|
||||
->method('hasItem')
|
||||
->will($this->returnValue(true));
|
||||
$cache->expects($this->once())
|
||||
->method('getItem')
|
||||
->will($this->returnValue($cacheItem));
|
||||
$cache->expects($this->never())
|
||||
->method('save');
|
||||
|
||||
$driver = $this->getFFProbeDriverMock();
|
||||
$driver->expects($this->never())
|
||||
->method('command');
|
||||
|
||||
$ffprobe->setOptionsTester($tester)
|
||||
->setCache($cache)
|
||||
->setMapper($mapper)
|
||||
->setFFProbeDriver($driver);
|
||||
|
||||
$this->assertEquals($output, call_user_func([$ffprobe, $method], $pathfile));
|
||||
}
|
||||
|
||||
public function provideProbeMethod()
|
||||
{
|
||||
return [
|
||||
['streams'],
|
||||
['format'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideProbeMethod
|
||||
*/
|
||||
public function testProbeWithoutShowStreamsAvailable($method)
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\RuntimeException');
|
||||
$pathfile = __FILE__;
|
||||
|
||||
$ffprobe = new FFProbe($this->getFFProbeDriverMock(), $this->getCacheMock());
|
||||
$ffprobe->setOptionsTester($this->getFFProbeOptionsTesterMock());
|
||||
call_user_func([$ffprobe, $method], $pathfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideCreateOptions
|
||||
*/
|
||||
public function testCreate($logger, $conf, $cache)
|
||||
{
|
||||
$finder = new ExecutableFinder();
|
||||
|
||||
$found = false;
|
||||
foreach (['avprobe', 'ffprobe'] as $name) {
|
||||
if (null !== $finder->find($name)) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->markTestSkipped('Unable to find avprobe or ffprobe on system');
|
||||
}
|
||||
|
||||
$ffprobe = FFProbe::create();
|
||||
$this->assertInstanceOf('FFMpeg\FFprobe', $ffprobe);
|
||||
|
||||
$ffprobe = FFProbe::create($conf, $logger, $cache);
|
||||
$this->assertInstanceOf('FFMpeg\FFprobe', $ffprobe);
|
||||
|
||||
if (null !== $cache) {
|
||||
$this->assertSame($cache, $ffprobe->getCache());
|
||||
}
|
||||
if (null !== $logger) {
|
||||
$this->assertSame($logger, $ffprobe->getFFProbeDriver()->getProcessRunner()->getLogger());
|
||||
}
|
||||
if ($conf instanceof ConfigurationInterface) {
|
||||
$this->assertSame($conf, $ffprobe->getFFProbeDriver()->getConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
public function provideCreateOptions()
|
||||
{
|
||||
return [
|
||||
[null, ['key' => 'value'], null],
|
||||
[$this->getLoggerMock(), ['key' => 'value'], null],
|
||||
[null, new Configuration(), null],
|
||||
[null, ['key' => 'value'], $this->getCacheMock()],
|
||||
];
|
||||
}
|
||||
}
|
||||
48
tests/FFMpeg/Unit/Filters/Audio/AudioClipTest.php
Normal file
48
tests/FFMpeg/Unit/Filters/Audio/AudioClipTest.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Audio;
|
||||
|
||||
use FFMpeg\Coordinate\TimeCode;
|
||||
use FFMpeg\Filters\Audio\AudioFilters;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AudioClipTest extends TestCase
|
||||
{
|
||||
public function testClipping()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$audio = $this->getAudioMock();
|
||||
$audio->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AudioClipFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filters = new AudioFilters($audio);
|
||||
|
||||
$filters->clip(TimeCode::fromSeconds(5));
|
||||
$this->assertEquals([0 => '-ss', 1 => '00:00:05.00', 2 => '-acodec', 3 => 'copy'], $capturedFilter->apply($audio, $format));
|
||||
}
|
||||
|
||||
public function testClippingWithDuration()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$audio = $this->getAudioMock();
|
||||
$audio->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AudioClipFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filters = new AudioFilters($audio);
|
||||
|
||||
$filters->clip(TimeCode::fromSeconds(5), TimeCode::fromSeconds(5));
|
||||
$this->assertEquals([0 => '-ss', 1 => '00:00:05.00', 2 => '-t', 3 => '00:00:05.00', 4 => '-acodec', 5 => 'copy'], $capturedFilter->apply($audio, $format));
|
||||
}
|
||||
}
|
||||
26
tests/FFMpeg/Unit/Filters/Audio/AudioFiltersTest.php
Normal file
26
tests/FFMpeg/Unit/Filters/Audio/AudioFiltersTest.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Audio;
|
||||
|
||||
use FFMpeg\Filters\Audio\AudioFilters;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AudioFiltersTest extends TestCase
|
||||
{
|
||||
public function testResample()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$audio = $this->getAudioMock();
|
||||
$audio->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AudioResamplableFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
|
||||
$filters = new AudioFilters($audio);
|
||||
$filters->resample(8000);
|
||||
$this->assertEquals(8000, $capturedFilter->getRate());
|
||||
}
|
||||
}
|
||||
64
tests/FFMpeg/Unit/Filters/Audio/AudioMetadataTest.php
Normal file
64
tests/FFMpeg/Unit/Filters/Audio/AudioMetadataTest.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Audio;
|
||||
|
||||
use FFMpeg\Filters\Audio\AudioFilters;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AudioMetadataTest extends TestCase
|
||||
{
|
||||
public function testAddMetadata()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$audio = $this->getAudioMock();
|
||||
$audio->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AddMetadataFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filters = new AudioFilters($audio);
|
||||
$filters->addMetadata(['title' => 'Hello World']);
|
||||
$this->assertEquals([0 => '-metadata', 1 => 'title=Hello World'], $capturedFilter->apply($audio, $format));
|
||||
}
|
||||
|
||||
public function testAddArtwork()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$audio = $this->getAudioMock();
|
||||
$audio->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AddMetadataFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filters = new AudioFilters($audio);
|
||||
$filters->addMetadata(['genre' => 'Some Genre', 'artwork' => '/path/to/file.jpg']);
|
||||
$this->assertEquals([0 => '-i', 1 => '/path/to/file.jpg', 2 => '-map', 3 => '0', 4 => '-map', 5 => '1', 6 => '-metadata', 7 => 'genre=Some Genre'], $capturedFilter->apply($audio, $format));
|
||||
$this->assertEquals([0 => '-i', 1 => '/path/to/file.jpg', 2 => '-map', 3 => '0', 4 => '-map', 5 => '1', 6 => '-metadata', 7 => 'genre=Some Genre'], $capturedFilter->apply($audio, $format));
|
||||
}
|
||||
|
||||
public function testRemoveMetadata()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$audio = $this->getAudioMock();
|
||||
$audio->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AddMetadataFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filters = new AudioFilters($audio);
|
||||
$filters->addMetadata();
|
||||
$this->assertEquals([0 => '-map_metadata', 1 => '-1', 2 => '-vn'], $capturedFilter->apply($audio, $format));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Audio;
|
||||
|
||||
use FFMpeg\Filters\Audio\AudioResamplableFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AudioResamplableFilterTest extends TestCase
|
||||
{
|
||||
public function testGetRate()
|
||||
{
|
||||
$filter = new AudioResamplableFilter(500);
|
||||
$this->assertEquals(500, $filter->getRate());
|
||||
}
|
||||
|
||||
public function testApply()
|
||||
{
|
||||
$audio = $this->getAudioMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filter = new AudioResamplableFilter(500);
|
||||
$this->assertEquals(['-ac', 2, '-ar', 500], $filter->apply($audio, $format));
|
||||
}
|
||||
}
|
||||
18
tests/FFMpeg/Unit/Filters/Audio/CustomFilterTest.php
Normal file
18
tests/FFMpeg/Unit/Filters/Audio/CustomFilterTest.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Audio;
|
||||
|
||||
use FFMpeg\Filters\Audio\CustomFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class CustomFilterTest extends TestCase
|
||||
{
|
||||
public function testApplyCustomFilter()
|
||||
{
|
||||
$audio = $this->getAudioMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
$filter = new CustomFilter('whatever i put would end up as a filter');
|
||||
$this->assertEquals(['-af', 'whatever i put would end up as a filter'], $filter->apply($audio, $format));
|
||||
}
|
||||
}
|
||||
62
tests/FFMpeg/Unit/Filters/FiltersCollectionTest.php
Normal file
62
tests/FFMpeg/Unit/Filters/FiltersCollectionTest.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters;
|
||||
|
||||
use FFMpeg\Filters\Audio\SimpleFilter;
|
||||
use FFMpeg\Filters\FiltersCollection;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class FiltersCollectionTest extends TestCase
|
||||
{
|
||||
public function testCount()
|
||||
{
|
||||
$coll = new FiltersCollection();
|
||||
$this->assertCount(0, $coll);
|
||||
|
||||
$coll->add($this->getMockBuilder('FFMpeg\Filters\FilterInterface')->getMock());
|
||||
$this->assertCount(1, $coll);
|
||||
|
||||
$coll->add($this->getMockBuilder('FFMpeg\Filters\FilterInterface')->getMock());
|
||||
$this->assertCount(2, $coll);
|
||||
}
|
||||
|
||||
public function testIterator()
|
||||
{
|
||||
$coll = new FiltersCollection();
|
||||
$coll->add($this->getMockBuilder('FFMpeg\Filters\FilterInterface')->getMock());
|
||||
$coll->add($this->getMockBuilder('FFMpeg\Filters\FilterInterface')->getMock());
|
||||
|
||||
$this->assertInstanceOf('\ArrayIterator', $coll->getIterator());
|
||||
$this->assertCount(2, $coll->getIterator());
|
||||
}
|
||||
|
||||
public function testEmptyIterator()
|
||||
{
|
||||
$coll = new FiltersCollection();
|
||||
$this->assertInstanceOf('\ArrayIterator', $coll->getIterator());
|
||||
}
|
||||
|
||||
public function testIteratorSort()
|
||||
{
|
||||
$coll = new FiltersCollection();
|
||||
$coll->add(new SimpleFilter(['a']));
|
||||
$coll->add(new SimpleFilter(['1'], 12));
|
||||
$coll->add(new SimpleFilter(['b']));
|
||||
$coll->add(new SimpleFilter(['2'], 12));
|
||||
$coll->add(new SimpleFilter(['c']));
|
||||
$coll->add(new SimpleFilter(['3'], 10));
|
||||
$coll->add(new SimpleFilter(['d']));
|
||||
$coll->add(new SimpleFilter(['4'], -2));
|
||||
$coll->add(new SimpleFilter(['e']));
|
||||
|
||||
$data = [];
|
||||
$video = $this->getVideoMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
|
||||
foreach ($coll as $filter) {
|
||||
$data = array_merge($data, $filter->apply($video, $format));
|
||||
}
|
||||
|
||||
$this->assertEquals(['1', '2', '3', 'a', 'b', 'c', 'd', 'e', '4'], $data);
|
||||
}
|
||||
}
|
||||
17
tests/FFMpeg/Unit/Filters/Frame/CustomFrameFilterTest.php
Normal file
17
tests/FFMpeg/Unit/Filters/Frame/CustomFrameFilterTest.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Frame;
|
||||
|
||||
use FFMpeg\Filters\Frame\CustomFrameFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class CustomFrameFilterTest extends TestCase
|
||||
{
|
||||
public function testApplyCustomFrameFilter()
|
||||
{
|
||||
$frame = $this->getFrameMock();
|
||||
|
||||
$filter = new CustomFrameFilter('whatever i put would end up as a filter');
|
||||
$this->assertEquals(['-vf', 'whatever i put would end up as a filter'], $filter->apply($frame));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Frame;
|
||||
|
||||
use FFMpeg\Coordinate\TimeCode;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Frame\DisplayRatioFixerFilter;
|
||||
use FFMpeg\Media\Frame;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class DisplayRatioFixerFilterTest extends TestCase
|
||||
{
|
||||
public function testApply()
|
||||
{
|
||||
$stream = new Stream(['codec_type' => 'video', 'width' => 960, 'height' => 720]);
|
||||
$streams = new StreamCollection([$stream]);
|
||||
|
||||
$video = $this->getVideoMock(__FILE__);
|
||||
$video->expects($this->once())
|
||||
->method('getStreams')
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$frame = new Frame($video, $this->getFFMpegDriverMock(), $this->getFFProbeMock(), new TimeCode(0, 0, 0, 0));
|
||||
$filter = new DisplayRatioFixerFilter();
|
||||
$this->assertEquals(['-s', '960x720'], $filter->apply($frame));
|
||||
}
|
||||
}
|
||||
21
tests/FFMpeg/Unit/Filters/Frame/FrameFiltersTest.php
Normal file
21
tests/FFMpeg/Unit/Filters/Frame/FrameFiltersTest.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Frame;
|
||||
|
||||
use FFMpeg\Filters\Frame\FrameFilters;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class FrameFiltersTest extends TestCase
|
||||
{
|
||||
public function testResize()
|
||||
{
|
||||
$frame = $this->getFrameMock();
|
||||
$filters = new FrameFilters($frame);
|
||||
|
||||
$frame->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Frame\DisplayRatioFixerFilter'));
|
||||
|
||||
$filters->fixDisplayRatio();
|
||||
}
|
||||
}
|
||||
38
tests/FFMpeg/Unit/Filters/Video/CropFilterTest.php
Normal file
38
tests/FFMpeg/Unit/Filters/Video/CropFilterTest.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\Coordinate\Point;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Video\CropFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class CropFilterTest extends TestCase
|
||||
{
|
||||
public function testCommandParamsAreCorrectAndStreamIsUpdated()
|
||||
{
|
||||
$stream = new Stream(['width' => 320, 'height' => 240, 'codec_type' => 'video']);
|
||||
$streams = new StreamCollection([$stream]);
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
$video->expects($this->once())
|
||||
->method('getStreams')
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$dimension = new Dimension(200, 150);
|
||||
$point = new Point(25, 35);
|
||||
$filter = new CropFilter($point, $dimension);
|
||||
$expected = [
|
||||
'-filter:v',
|
||||
'crop='.$dimension->getWidth().':'.$dimension->getHeight().':'.$point->getX().':'.$point->getY(),
|
||||
];
|
||||
$this->assertEquals($expected, $filter->apply($video, $format));
|
||||
|
||||
$this->assertEquals(200, $stream->get('width'));
|
||||
$this->assertEquals(150, $stream->get('height'));
|
||||
}
|
||||
}
|
||||
18
tests/FFMpeg/Unit/Filters/Video/CustomFilterTest.php
Normal file
18
tests/FFMpeg/Unit/Filters/Video/CustomFilterTest.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Filters\Video\CustomFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class CustomFilterTest extends TestCase
|
||||
{
|
||||
public function testApplyCustomFilter()
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$filter = new CustomFilter('whatever i put would end up as a filter');
|
||||
$this->assertEquals(['-vf', 'whatever i put would end up as a filter'], $filter->apply($video, $format));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Video\ExtractMultipleFramesFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class ExtractMultipleFramesFilterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFrameRates
|
||||
*/
|
||||
public function testApply($frameRate, $frameFileType, $destinationFolder, $duration, $modulus, $expected)
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$pathfile = '/path/to/file'.mt_rand();
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getModulus')
|
||||
->will($this->returnValue($modulus));
|
||||
|
||||
$streams = new StreamCollection([
|
||||
new Stream([
|
||||
'codec_type' => 'video',
|
||||
'duration' => $duration,
|
||||
]),
|
||||
]);
|
||||
|
||||
$video->expects($this->once())
|
||||
->method('getStreams')
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$filter = new ExtractMultipleFramesFilter($frameRate, $destinationFolder);
|
||||
$filter->setFrameFileType($frameFileType);
|
||||
$this->assertEquals($expected, $filter->apply($video, $format));
|
||||
}
|
||||
|
||||
public function provideFrameRates()
|
||||
{
|
||||
return [
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_SEC, 'jpg', '/', 100, 2, ['-vf', 'fps=1/1', '/frame-%03d.jpg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_2SEC, 'jpg', '/', 100, 2, ['-vf', 'fps=1/2', '/frame-%02d.jpg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_5SEC, 'jpg', '/', 100, 2, ['-vf', 'fps=1/5', '/frame-%02d.jpg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, 'jpg', '/', 100, 2, ['-vf', 'fps=1/10', '/frame-%02d.jpg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_30SEC, 'jpg', '/', 100, 2, ['-vf', 'fps=1/30', '/frame-%02d.jpg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_60SEC, 'jpg', '/', 100, 2, ['-vf', 'fps=1/60', '/frame-%02d.jpg']],
|
||||
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_SEC, 'jpeg', '/', 100, 2, ['-vf', 'fps=1/1', '/frame-%03d.jpeg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_2SEC, 'jpeg', '/', 100, 2, ['-vf', 'fps=1/2', '/frame-%02d.jpeg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_5SEC, 'jpeg', '/', 100, 2, ['-vf', 'fps=1/5', '/frame-%02d.jpeg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, 'jpeg', '/', 100, 2, ['-vf', 'fps=1/10', '/frame-%02d.jpeg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_30SEC, 'jpeg', '/', 100, 2, ['-vf', 'fps=1/30', '/frame-%02d.jpeg']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_60SEC, 'jpeg', '/', 100, 2, ['-vf', 'fps=1/60', '/frame-%02d.jpeg']],
|
||||
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_SEC, 'png', '/', 100, 2, ['-vf', 'fps=1/1', '/frame-%03d.png']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_2SEC, 'png', '/', 100, 2, ['-vf', 'fps=1/2', '/frame-%02d.png']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_5SEC, 'png', '/', 100, 2, ['-vf', 'fps=1/5', '/frame-%02d.png']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, 'png', '/', 100, 2, ['-vf', 'fps=1/10', '/frame-%02d.png']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_30SEC, 'png', '/', 100, 2, ['-vf', 'fps=1/30', '/frame-%02d.png']],
|
||||
[ExtractMultipleFramesFilter::FRAMERATE_EVERY_60SEC, 'png', '/', 100, 2, ['-vf', 'fps=1/60', '/frame-%02d.png']],
|
||||
];
|
||||
}
|
||||
|
||||
public function testInvalidFrameFileType()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$filter = new ExtractMultipleFramesFilter('1/1', '/');
|
||||
$filter->setFrameFileType('webm');
|
||||
}
|
||||
}
|
||||
44
tests/FFMpeg/Unit/Filters/Video/FrameRateFilterTest.php
Normal file
44
tests/FFMpeg/Unit/Filters/Video/FrameRateFilterTest.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Coordinate\FrameRate;
|
||||
use FFMpeg\Filters\Video\FrameRateFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class FrameRateFilterTest extends TestCase
|
||||
{
|
||||
public function testApplyWithAFormatThatSupportsBFrames()
|
||||
{
|
||||
$framerate = new FrameRate(54);
|
||||
$gop = 42;
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('supportBFrames')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$expected = ['-r', 54, '-b_strategy', '1', '-bf', '3', '-g', 42];
|
||||
|
||||
$filter = new FrameRateFilter($framerate, $gop);
|
||||
$this->assertEquals($expected, $filter->apply($video, $format));
|
||||
}
|
||||
|
||||
public function testApplyWithAFormatThatDoesNotSupportsBFrames()
|
||||
{
|
||||
$framerate = new FrameRate(54);
|
||||
$gop = 42;
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('supportBFrames')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$expected = ['-r', 54];
|
||||
|
||||
$filter = new FrameRateFilter($framerate, $gop);
|
||||
$this->assertEquals($expected, $filter->apply($video, $format));
|
||||
}
|
||||
}
|
||||
44
tests/FFMpeg/Unit/Filters/Video/PadFilterTest.php
Normal file
44
tests/FFMpeg/Unit/Filters/Video/PadFilterTest.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Video\PadFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class PadFilterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideDimensions
|
||||
*/
|
||||
public function testApply(Dimension $dimension, $width, $height, $expected)
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$pathfile = '/path/to/file'.mt_rand();
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$streams = new StreamCollection([
|
||||
new Stream([
|
||||
'codec_type' => 'video',
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
]),
|
||||
]);
|
||||
|
||||
$filter = new PadFilter($dimension);
|
||||
$this->assertEquals($expected, $filter->apply($video, $format));
|
||||
}
|
||||
|
||||
public function provideDimensions()
|
||||
{
|
||||
return [
|
||||
[new Dimension(1000, 800), 640, 480, ['-vf', 'scale=iw*min(1000/iw\,800/ih):ih*min(1000/iw\,800/ih),pad=1000:800:(1000-iw)/2:(800-ih)/2']],
|
||||
[new Dimension(300, 600), 640, 480, ['-vf', 'scale=iw*min(300/iw\,600/ih):ih*min(300/iw\,600/ih),pad=300:600:(300-iw)/2:(600-ih)/2']],
|
||||
[new Dimension(100, 900), 640, 480, ['-vf', 'scale=iw*min(100/iw\,900/ih):ih*min(100/iw\,900/ih),pad=100:900:(100-iw)/2:(900-ih)/2']],
|
||||
[new Dimension(1200, 200), 640, 480, ['-vf', 'scale=iw*min(1200/iw\,200/ih):ih*min(1200/iw\,200/ih),pad=1200:200:(1200-iw)/2:(200-ih)/2']],
|
||||
];
|
||||
}
|
||||
}
|
||||
75
tests/FFMpeg/Unit/Filters/Video/ResizeFilterTest.php
Normal file
75
tests/FFMpeg/Unit/Filters/Video/ResizeFilterTest.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Video\ResizeFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class ResizeFilterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideDimensions
|
||||
*/
|
||||
public function testApply(Dimension $dimension, $mode, $width, $height, $modulus, $expected, $forceStandards = true)
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$pathfile = '/path/to/file'.mt_rand();
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getModulus')
|
||||
->will($this->returnValue($modulus));
|
||||
|
||||
$streams = new StreamCollection([
|
||||
new Stream([
|
||||
'codec_type' => 'video',
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
]),
|
||||
]);
|
||||
|
||||
$video->expects($this->once())
|
||||
->method('getStreams')
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$filter = new ResizeFilter($dimension, $mode, $forceStandards);
|
||||
$this->assertEquals($expected, $filter->apply($video, $format));
|
||||
}
|
||||
|
||||
public function provideDimensions()
|
||||
{
|
||||
return [
|
||||
[new Dimension(320, 240), ResizeFilter::RESIZEMODE_FIT, 640, 480, 2, ['-vf', '[in]scale=320:240 [out]']],
|
||||
[new Dimension(320, 240), ResizeFilter::RESIZEMODE_INSET, 640, 480, 2, ['-vf', '[in]scale=320:240 [out]']],
|
||||
[new Dimension(320, 240), ResizeFilter::RESIZEMODE_SCALE_HEIGHT, 640, 480, 2, ['-vf', '[in]scale=320:240 [out]']],
|
||||
[new Dimension(320, 240), ResizeFilter::RESIZEMODE_SCALE_WIDTH, 640, 480, 2, ['-vf', '[in]scale=320:240 [out]']],
|
||||
|
||||
[new Dimension(640, 480), ResizeFilter::RESIZEMODE_FIT, 320, 240, 2, ['-vf', '[in]scale=640:480 [out]']],
|
||||
[new Dimension(640, 480), ResizeFilter::RESIZEMODE_INSET, 320, 240, 2, ['-vf', '[in]scale=640:480 [out]']],
|
||||
[new Dimension(640, 480), ResizeFilter::RESIZEMODE_SCALE_HEIGHT, 320, 240, 2, ['-vf', '[in]scale=640:480 [out]']],
|
||||
[new Dimension(640, 480), ResizeFilter::RESIZEMODE_SCALE_WIDTH, 320, 240, 2, ['-vf', '[in]scale=640:480 [out]']],
|
||||
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_FIT, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_INSET, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_SCALE_HEIGHT, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_SCALE_WIDTH, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_FIT, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_INSET, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_SCALE_HEIGHT, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
[new Dimension(640, 360), ResizeFilter::RESIZEMODE_SCALE_WIDTH, 1280, 720, 2, ['-vf', '[in]scale=640:360 [out]']],
|
||||
|
||||
// test non standard dimension
|
||||
[new Dimension(700, 150), ResizeFilter::RESIZEMODE_INSET, 123, 456, 2, ['-vf', '[in]scale=62:150 [out]'], true],
|
||||
[new Dimension(700, 150), ResizeFilter::RESIZEMODE_INSET, 123, 456, 2, ['-vf', '[in]scale=40:150 [out]'], false],
|
||||
|
||||
[new Dimension(320, 320), ResizeFilter::RESIZEMODE_FIT, 640, 480, 2, ['-vf', '[in]scale=320:320 [out]']],
|
||||
[new Dimension(320, 320), ResizeFilter::RESIZEMODE_INSET, 640, 480, 2, ['-vf', '[in]scale=320:240 [out]']],
|
||||
[new Dimension(320, 320), ResizeFilter::RESIZEMODE_SCALE_HEIGHT, 640, 480, 2, ['-vf', '[in]scale=320:240 [out]']],
|
||||
[new Dimension(320, 320), ResizeFilter::RESIZEMODE_SCALE_WIDTH, 640, 480, 2, ['-vf', '[in]scale=426:320 [out]']],
|
||||
];
|
||||
}
|
||||
}
|
||||
72
tests/FFMpeg/Unit/Filters/Video/RotateFilterTest.php
Normal file
72
tests/FFMpeg/Unit/Filters/Video/RotateFilterTest.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Video\RotateFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class RotateFilterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provide90degresTranspositions
|
||||
*/
|
||||
public function testApplyWithSizeTransformation($value)
|
||||
{
|
||||
$stream = new Stream(['width' => 320, 'height' => 240, 'codec_type' => 'video']);
|
||||
$streams = new StreamCollection([$stream]);
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
$video->expects($this->once())
|
||||
->method('getStreams')
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$filter = new RotateFilter($value);
|
||||
$this->assertEquals(['-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 [
|
||||
[RotateFilter::ROTATE_90],
|
||||
[RotateFilter::ROTATE_270],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDegresWithoutTranspositions
|
||||
*/
|
||||
public function testApplyWithoutSizeTransformation($value)
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$video->expects($this->never())
|
||||
->method('getStreams');
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$filter = new RotateFilter($value);
|
||||
$this->assertEquals(['-vf', $value, '-metadata:s:v:0', 'rotate=0'], $filter->apply($video, $format));
|
||||
}
|
||||
|
||||
public function provideDegresWithoutTranspositions()
|
||||
{
|
||||
return [
|
||||
[RotateFilter::ROTATE_180],
|
||||
];
|
||||
}
|
||||
|
||||
public function testApplyInvalidAngle()
|
||||
{
|
||||
$this->expectException(
|
||||
'\FFMpeg\Exception\InvalidArgumentException',
|
||||
'Invalid angle value.'
|
||||
);
|
||||
new RotateFilter('90');
|
||||
}
|
||||
}
|
||||
18
tests/FFMpeg/Unit/Filters/Video/SynchronizeFilterTest.php
Normal file
18
tests/FFMpeg/Unit/Filters/Video/SynchronizeFilterTest.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Filters\Video\SynchronizeFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class SynchronizeFilterTest extends TestCase
|
||||
{
|
||||
public function testApply()
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$filter = new SynchronizeFilter();
|
||||
$this->assertEquals(['-async', '1', '-metadata:s:v:0', 'start_time=0'], $filter->apply($video, $format));
|
||||
}
|
||||
}
|
||||
79
tests/FFMpeg/Unit/Filters/Video/VideoFiltersTest.php
Normal file
79
tests/FFMpeg/Unit/Filters/Video/VideoFiltersTest.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\Filters\Video\ResizeFilter;
|
||||
use FFMpeg\Filters\Video\VideoFilters;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class VideoFiltersTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideResizeOptions
|
||||
*/
|
||||
public function testResize($mode, $forceStandards)
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
$filters = new VideoFilters($video);
|
||||
$dimension = $this->getDimensionMock();
|
||||
|
||||
$video->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Video\ResizeFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
|
||||
$filters->resize($dimension, $mode, $forceStandards);
|
||||
|
||||
$this->assertSame($mode, $capturedFilter->getMode());
|
||||
$this->assertSame($forceStandards, $capturedFilter->areStandardsForced());
|
||||
$this->assertSame($dimension, $capturedFilter->getDimension());
|
||||
}
|
||||
|
||||
public function provideResizeOptions()
|
||||
{
|
||||
return [
|
||||
[ResizeFilter::RESIZEMODE_FIT, true],
|
||||
[ResizeFilter::RESIZEMODE_SCALE_WIDTH, true],
|
||||
[ResizeFilter::RESIZEMODE_SCALE_HEIGHT, false],
|
||||
[ResizeFilter::RESIZEMODE_INSET, false],
|
||||
];
|
||||
}
|
||||
|
||||
public function testResample()
|
||||
{
|
||||
$capturedFilter = null;
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
$filters = new VideoFilters($video);
|
||||
$framerate = $this->getFramerateMock();
|
||||
$gop = 42;
|
||||
|
||||
$video->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Video\FrameRateFilter'))
|
||||
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
|
||||
$capturedFilter = $filter;
|
||||
}));
|
||||
|
||||
$filters->framerate($framerate, $gop);
|
||||
|
||||
$this->assertSame($framerate, $capturedFilter->getFramerate());
|
||||
$this->assertSame($gop, $capturedFilter->getGOP());
|
||||
}
|
||||
|
||||
public function testSynchronize()
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$filters = new VideoFilters($video);
|
||||
|
||||
$video->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Video\SynchronizeFilter'));
|
||||
|
||||
$filters->synchronize();
|
||||
}
|
||||
}
|
||||
62
tests/FFMpeg/Unit/Filters/Video/WatermarkFilterTest.php
Normal file
62
tests/FFMpeg/Unit/Filters/Video/WatermarkFilterTest.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Video;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Video\WatermarkFilter;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class WatermarkFilterTest extends TestCase
|
||||
{
|
||||
public function testApplyWatermark()
|
||||
{
|
||||
$stream = new Stream(['width' => 320, 'height' => 240, 'codec_type' => 'video']);
|
||||
$streams = new StreamCollection([$stream]);
|
||||
|
||||
$video = $this->getVideoMock();
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
$filter = new WatermarkFilter(__DIR__.'/../../../files/watermark.png');
|
||||
$this->assertEquals(['-vf', 'movie='.__DIR__.'/../../../files/watermark.png [watermark]; [in][watermark] overlay=0:0 [out]'], $filter->apply($video, $format));
|
||||
|
||||
// check size of video is unchanged
|
||||
$this->assertEquals(320, $stream->get('width'));
|
||||
$this->assertEquals(240, $stream->get('height'));
|
||||
}
|
||||
|
||||
public function testDifferentCoordinaates()
|
||||
{
|
||||
$video = $this->getVideoMock();
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
|
||||
// test position absolute
|
||||
$filter = new WatermarkFilter(__DIR__.'/../../../files/watermark.png', [
|
||||
'position' => 'absolute',
|
||||
'x' => 10, 'y' => 5,
|
||||
]);
|
||||
$this->assertEquals(['-vf', 'movie='.__DIR__.'/../../../files/watermark.png [watermark]; [in][watermark] overlay=10:5 [out]'], $filter->apply($video, $format));
|
||||
|
||||
// test position relative
|
||||
$filter = new WatermarkFilter(__DIR__.'/../../../files/watermark.png', [
|
||||
'position' => 'relative',
|
||||
'bottom' => 10, 'left' => 5,
|
||||
]);
|
||||
$this->assertEquals(['-vf', 'movie='.__DIR__.'/../../../files/watermark.png [watermark]; [in][watermark] overlay=5:main_h - 10 - overlay_h [out]'], $filter->apply($video, $format));
|
||||
|
||||
// test position relative
|
||||
$filter = new WatermarkFilter(__DIR__.'/../../../files/watermark.png', [
|
||||
'position' => 'relative',
|
||||
'bottom' => 5, 'right' => 4,
|
||||
]);
|
||||
$this->assertEquals(['-vf', 'movie='.__DIR__.'/../../../files/watermark.png [watermark]; [in][watermark] overlay=main_w - 4 - overlay_w:main_h - 5 - overlay_h [out]'], $filter->apply($video, $format));
|
||||
|
||||
// test position relative
|
||||
$filter = new WatermarkFilter(__DIR__.'/../../../files/watermark.png', [
|
||||
'position' => 'relative',
|
||||
'left' => 5, 'top' => 11,
|
||||
]);
|
||||
$this->assertEquals(['-vf', 'movie='.__DIR__.'/../../../files/watermark.png [watermark]; [in][watermark] overlay=5:11 [out]'], $filter->apply($video, $format));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Waveform;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\Stream;
|
||||
use FFMpeg\FFProbe\DataMapping\StreamCollection;
|
||||
use FFMpeg\Filters\Waveform\WaveformDownmixFilter;
|
||||
use FFMpeg\Media\Waveform;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class WaveformDownmixFilterTest extends TestCase
|
||||
{
|
||||
public function testApply()
|
||||
{
|
||||
$stream = new Stream(['codec_type' => 'audio', 'width' => 960, 'height' => 720]);
|
||||
$streams = new StreamCollection([$stream]);
|
||||
|
||||
$audio = $this->getAudioMock(__FILE__);
|
||||
$audio->expects($this->once())
|
||||
->method('getStreams')
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$waveform = new Waveform($audio, $this->getFFMpegDriverMock(), $this->getFFProbeMock(), 640, 120);
|
||||
$filter = new WaveformDownmixFilter(true);
|
||||
$this->assertEquals(['"aformat=channel_layouts=mono"'], $filter->apply($waveform));
|
||||
}
|
||||
}
|
||||
21
tests/FFMpeg/Unit/Filters/Waveform/WaveformFiltersTest.php
Normal file
21
tests/FFMpeg/Unit/Filters/Waveform/WaveformFiltersTest.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Filters\Waveform;
|
||||
|
||||
use FFMpeg\Filters\Waveform\WaveformFilters;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class WaveformFiltersTest extends TestCase
|
||||
{
|
||||
public function testResize()
|
||||
{
|
||||
$Waveform = $this->getWaveformMock();
|
||||
$filters = new WaveformFilters($Waveform);
|
||||
|
||||
$Waveform->expects($this->once())
|
||||
->method('addFilter')
|
||||
->with($this->isInstanceOf('FFMpeg\Filters\Waveform\WaveformDownmixFilter'));
|
||||
|
||||
$filters->setDownmix();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Audio/AacTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Audio/AacTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Audio;
|
||||
|
||||
use FFMpeg\Format\Audio\Aac;
|
||||
|
||||
class AacTest extends AudioTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new Aac();
|
||||
}
|
||||
}
|
||||
118
tests/FFMpeg/Unit/Format/Audio/AudioTestCase.php
Normal file
118
tests/FFMpeg/Unit/Format/Audio/AudioTestCase.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Audio;
|
||||
|
||||
use FFMpeg\Format\Audio\DefaultAudio;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
abstract class AudioTestCase extends TestCase
|
||||
{
|
||||
public function testExtraParams()
|
||||
{
|
||||
$extraParams = $this->getFormat()->getExtraParams();
|
||||
|
||||
$this->assertIsArray($extraParams);
|
||||
|
||||
foreach ($extraParams as $param) {
|
||||
$this->assertScalar($param);
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetAudioCodec()
|
||||
{
|
||||
$this->assertScalar($this->getFormat()->getAudioCodec());
|
||||
$this->assertContains($this->getFormat()->getAudioCodec(), $this->getFormat()->getAvailableAudioCodecs());
|
||||
}
|
||||
|
||||
public function testSetAudioCodec()
|
||||
{
|
||||
$format = $this->getFormat();
|
||||
|
||||
foreach ($format->getAvailableAudioCodecs() as $codec) {
|
||||
$format->setAudioCodec($codec);
|
||||
$this->assertEquals($codec, $format->getAudioCodec());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetInvalidAudioCodec()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$this->getFormat()->setAudioCodec('invalid-random-audio-codec');
|
||||
}
|
||||
|
||||
public function testGetAvailableAudioCodecs()
|
||||
{
|
||||
$this->assertGreaterThan(0, count($this->getFormat()->getAvailableAudioCodecs()));
|
||||
}
|
||||
|
||||
public function testGetAudioKiloBitrate()
|
||||
{
|
||||
$this->assertIsInt($this->getFormat()->getAudioKiloBitrate());
|
||||
}
|
||||
|
||||
public function testSetAudioKiloBitrate()
|
||||
{
|
||||
$format = $this->getFormat();
|
||||
$format->setAudioKiloBitrate(256);
|
||||
$this->assertEquals(256, $format->getAudioKiloBitrate());
|
||||
}
|
||||
|
||||
public function testSetInvalidKiloBitrate()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$this->getFormat()->setAudioKiloBitrate(0);
|
||||
}
|
||||
|
||||
public function testSetNegativeKiloBitrate()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$this->getFormat()->setAudioKiloBitrate(-10);
|
||||
}
|
||||
|
||||
public function testGetAudioChannels()
|
||||
{
|
||||
$this->assertNull($this->getFormat()->getAudioChannels());
|
||||
}
|
||||
|
||||
public function testSetAudioChannels()
|
||||
{
|
||||
$format = $this->getFormat();
|
||||
$format->setAudioChannels(2);
|
||||
$this->assertEquals(2, $format->getAudioChannels());
|
||||
}
|
||||
|
||||
public function testSetInvalidChannels()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$this->getFormat()->setAudioChannels(0);
|
||||
}
|
||||
|
||||
public function testSetNegativeChannels()
|
||||
{
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$this->getFormat()->setAudioChannels(-10);
|
||||
}
|
||||
|
||||
public function testCreateProgressListener()
|
||||
{
|
||||
$media = $this->getMockBuilder('FFMpeg\Media\MediaTypeInterface')->getMock();
|
||||
$media->expects($this->any())
|
||||
->method('getPathfile')
|
||||
->will($this->returnValue(__FILE__));
|
||||
$format = $this->getFormat();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
foreach ($format->createProgressListener($media, $ffprobe, 1, 3) as $listener) {
|
||||
$this->assertInstanceOf('FFMpeg\Format\ProgressListener\AudioProgressListener', $listener);
|
||||
$this->assertSame($ffprobe, $listener->getFFProbe());
|
||||
$this->assertSame(__FILE__, $listener->getPathfile());
|
||||
$this->assertSame(1, $listener->getCurrentPass());
|
||||
$this->assertSame(3, $listener->getTotalPass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DefaultAudio
|
||||
*/
|
||||
abstract public function getFormat();
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Audio/FlacTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Audio/FlacTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Audio;
|
||||
|
||||
use FFMpeg\Format\Audio\Flac;
|
||||
|
||||
class FlacTest extends AudioTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new Flac();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Audio/Mp3Test.php
Normal file
13
tests/FFMpeg/Unit/Format/Audio/Mp3Test.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Audio;
|
||||
|
||||
use FFMpeg\Format\Audio\Mp3;
|
||||
|
||||
class Mp3Test extends AudioTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new Mp3();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Audio/VorbisTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Audio/VorbisTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Audio;
|
||||
|
||||
use FFMpeg\Format\Audio\Vorbis;
|
||||
|
||||
class VorbisTest extends AudioTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new Vorbis();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Audio/WavTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Audio/WavTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Audio;
|
||||
|
||||
use FFMpeg\Format\Audio\Wav;
|
||||
|
||||
class WavTest extends AudioTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new Wav();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\ProgressListener;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\Format;
|
||||
use FFMpeg\Format\ProgressListener\AudioProgressListener;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class AudioProgressListenerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testHandle(
|
||||
$size,
|
||||
$duration,
|
||||
$data,
|
||||
$expectedPercent,
|
||||
$expectedRemaining,
|
||||
$expectedRate,
|
||||
$data2,
|
||||
$expectedPercent2,
|
||||
$expectedRemaining2,
|
||||
$expectedRate2,
|
||||
$currentPass,
|
||||
$totalPass
|
||||
) {
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('format')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue(new Format([
|
||||
'size' => $size,
|
||||
'duration' => $duration,
|
||||
])));
|
||||
|
||||
$listener = new AudioProgressListener($ffprobe, __FILE__, $currentPass, $totalPass);
|
||||
$phpunit = $this;
|
||||
$n = 0;
|
||||
$listener->on('progress', function ($percent, $remaining, $rate) use (&$n, $phpunit, $expectedPercent, $expectedRemaining, $expectedRate, $expectedPercent2, $expectedRemaining2, $expectedRate2) {
|
||||
if (0 === $n) {
|
||||
$phpunit->assertEquals($expectedPercent, $percent);
|
||||
$phpunit->assertEquals($expectedRemaining, $remaining);
|
||||
$phpunit->assertEquals($expectedRate, $rate);
|
||||
} elseif (1 === $n) {
|
||||
$phpunit->assertEquals($expectedPercent2, $percent);
|
||||
$phpunit->assertEquals($expectedRemaining2, $remaining);
|
||||
$phpunit->assertLessThan($expectedRate2 + 3, $rate);
|
||||
$phpunit->assertGreaterThan($expectedRate2 - 3, $rate);
|
||||
}
|
||||
++$n;
|
||||
});
|
||||
// first one does not trigger progress event
|
||||
$listener->handle('any-type'.mt_rand(), $data);
|
||||
sleep(1);
|
||||
$listener->handle('any-type'.mt_rand(), $data);
|
||||
sleep(1);
|
||||
$listener->handle('any-type'.mt_rand(), $data2);
|
||||
$this->assertEquals(2, $n);
|
||||
}
|
||||
|
||||
public function provideData()
|
||||
{
|
||||
return [
|
||||
[
|
||||
2894412,
|
||||
180.900750,
|
||||
'size= 712kB time=00:00:45.50 bitrate= 128.1kbits/s',
|
||||
25,
|
||||
0,
|
||||
0,
|
||||
'size= 1274kB time=00:01:29.32 bitrate= 142.8kbits/s',
|
||||
49,
|
||||
2,
|
||||
563,
|
||||
1,
|
||||
1,
|
||||
],
|
||||
[
|
||||
2894412,
|
||||
180.900750,
|
||||
'size= 712kB time=00:00:45.50 bitrate= 128.1kbits/s',
|
||||
12,
|
||||
0,
|
||||
0,
|
||||
'size= 1274kB time=00:01:29.32 bitrate= 142.8kbits/s',
|
||||
24,
|
||||
2,
|
||||
563,
|
||||
1,
|
||||
2,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\ProgressListener;
|
||||
|
||||
use FFMpeg\FFProbe\DataMapping\Format;
|
||||
use FFMpeg\Format\ProgressListener\VideoProgressListener;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class VideoProgressListenerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testHandle(
|
||||
$size,
|
||||
$duration,
|
||||
$newVideoDuration,
|
||||
$data,
|
||||
$expectedPercent,
|
||||
$expectedRemaining,
|
||||
$expectedRate,
|
||||
$data2,
|
||||
$expectedPercent2,
|
||||
$expectedRemaining2,
|
||||
$expectedRate2,
|
||||
$currentPass,
|
||||
$totalPass
|
||||
) {
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$ffprobe->expects($this->once())
|
||||
->method('format')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue(new Format([
|
||||
'size' => $size,
|
||||
'duration' => $duration,
|
||||
])));
|
||||
|
||||
$listener = new VideoProgressListener($ffprobe, __FILE__, $currentPass, $totalPass, $newVideoDuration);
|
||||
$phpunit = $this;
|
||||
$n = 0;
|
||||
$listener->on('progress', function ($percent, $remaining, $rate) use (&$n, $phpunit, $expectedPercent, $expectedRemaining, $expectedRate, $expectedPercent2, $expectedRemaining2, $expectedRate2) {
|
||||
if (0 === $n) {
|
||||
$phpunit->assertEquals($expectedPercent, $percent);
|
||||
$phpunit->assertEquals($expectedRemaining, $remaining);
|
||||
$phpunit->assertEquals($expectedRate, $rate);
|
||||
} elseif (1 === $n) {
|
||||
$phpunit->assertEquals($expectedPercent2, $percent);
|
||||
$phpunit->assertEquals($expectedRemaining2, $remaining);
|
||||
$phpunit->assertLessThan($expectedRate2 + 10, $rate);
|
||||
$phpunit->assertGreaterThan($expectedRate2 - 10, $rate);
|
||||
}
|
||||
++$n;
|
||||
});
|
||||
// first one does not trigger progress event
|
||||
$listener->handle('any-type'.mt_rand(), $data);
|
||||
sleep(1);
|
||||
$listener->handle('any-type'.mt_rand(), $data);
|
||||
sleep(1);
|
||||
$listener->handle('any-type'.mt_rand(), $data2);
|
||||
$this->assertEquals(2, $n);
|
||||
}
|
||||
|
||||
public function provideData()
|
||||
{
|
||||
return [
|
||||
[
|
||||
147073958,
|
||||
281.147533,
|
||||
281.147533,
|
||||
'frame= 206 fps=202 q=10.0 size= 571kB time=00:00:07.12 bitrate= 656.8kbits/s dup=9 drop=0',
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
'frame= 854 fps=113 q=20.0 size= 4430kB time=00:00:33.04 bitrate=1098.5kbits/s dup=36 drop=0',
|
||||
11,
|
||||
32,
|
||||
3868,
|
||||
1,
|
||||
1,
|
||||
],
|
||||
[
|
||||
147073958,
|
||||
281.147533,
|
||||
281.147533,
|
||||
'frame= 206 fps=202 q=10.0 size= 571kB time=00:00:07.12 bitrate= 656.8kbits/s dup=9 drop=0',
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
'frame= 854 fps=113 q=20.0 size= 4430kB time=00:00:33.04 bitrate=1098.5kbits/s dup=36 drop=0',
|
||||
5,
|
||||
32,
|
||||
3868,
|
||||
1,
|
||||
2,
|
||||
],
|
||||
[
|
||||
147073958,
|
||||
281.147533,
|
||||
35,
|
||||
'frame= 206 fps=202 q=10.0 size= 571kB time=00:00:07.12 bitrate= 656.8kbits/s dup=9 drop=0',
|
||||
60,
|
||||
0,
|
||||
0,
|
||||
'frame= 854 fps=113 q=20.0 size= 4430kB time=00:00:33.04 bitrate=1098.5kbits/s dup=36 drop=0',
|
||||
97,
|
||||
0,
|
||||
3868,
|
||||
2,
|
||||
2,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
16
tests/FFMpeg/Unit/Format/Video/InitialParametersTest.php
Normal file
16
tests/FFMpeg/Unit/Format/Video/InitialParametersTest.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use FFMpeg\Format\Video\X264;
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
class InitialParametersTest extends TestCase
|
||||
{
|
||||
public function testApplyInitialParameters()
|
||||
{
|
||||
$format = new X264();
|
||||
$format->setInitialParameters(['-acodec', 'libopus']);
|
||||
$this->assertEquals(['-acodec', 'libopus'], $format->getInitialParameters());
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Video/OggTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Video/OggTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use FFMpeg\Format\Video\Ogg;
|
||||
|
||||
class OggTest extends VideoTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new Ogg();
|
||||
}
|
||||
}
|
||||
90
tests/FFMpeg/Unit/Format/Video/VideoTestCase.php
Normal file
90
tests/FFMpeg/Unit/Format/Video/VideoTestCase.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use Tests\FFMpeg\Unit\Format\Audio\AudioTestCase;
|
||||
|
||||
abstract class VideoTestCase extends AudioTestCase
|
||||
{
|
||||
public function testGetVideoCodec()
|
||||
{
|
||||
$this->assertScalar($this->getFormat()->getVideoCodec());
|
||||
$this->assertContains($this->getFormat()->getVideoCodec(), $this->getFormat()->getAvailableVideoCodecs());
|
||||
}
|
||||
|
||||
public function testSupportBFrames()
|
||||
{
|
||||
$this->assertIsBool($this->getFormat()->supportBFrames());
|
||||
}
|
||||
|
||||
public function testSetVideoCodec()
|
||||
{
|
||||
$format = $this->getFormat();
|
||||
|
||||
foreach ($format->getAvailableVideoCodecs() as $codec) {
|
||||
$format->setVideoCodec($codec);
|
||||
$this->assertEquals($codec, $format->getVideoCodec());
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetKiloBitrate()
|
||||
{
|
||||
$this->assertIsInt($this->getFormat()->getKiloBitrate());
|
||||
}
|
||||
|
||||
public function testSetKiloBitrate()
|
||||
{
|
||||
$format = $this->getFormat();
|
||||
$format->setKiloBitrate(2560);
|
||||
$this->assertEquals(2560, $format->getKiloBitrate());
|
||||
}
|
||||
|
||||
public function testSetKiloBitrateBelowZero()
|
||||
{
|
||||
$this->expectException('FFMpeg\Exception\InvalidArgumentException');
|
||||
$format = $this->getFormat();
|
||||
$format->setKiloBitrate(-1);
|
||||
}
|
||||
|
||||
public function testSetInvalidVideoCodec()
|
||||
{
|
||||
$this->expectException('FFMpeg\Exception\InvalidArgumentException');
|
||||
$this->getFormat()->setVideoCodec('invalid-random-video-codec');
|
||||
}
|
||||
|
||||
public function testGetAvailableVideoCodecs()
|
||||
{
|
||||
$this->assertGreaterThan(0, count($this->getFormat()->getAvailableVideoCodecs()));
|
||||
}
|
||||
|
||||
public function testCreateProgressListener()
|
||||
{
|
||||
$media = $this->getMockBuilder('FFMpeg\Media\MediaTypeInterface')->getMock();
|
||||
$media->expects($this->any())
|
||||
->method('getPathfile')
|
||||
->will($this->returnValue(__FILE__));
|
||||
$format = $this->getFormat();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
foreach ($format->createProgressListener($media, $ffprobe, 1, 3) as $listener) {
|
||||
$this->assertInstanceOf('FFMpeg\Format\ProgressListener\VideoProgressListener', $listener);
|
||||
$this->assertSame($ffprobe, $listener->getFFProbe());
|
||||
$this->assertSame(__FILE__, $listener->getPathfile());
|
||||
$this->assertSame(1, $listener->getCurrentPass());
|
||||
$this->assertSame(3, $listener->getTotalPass());
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetPasses()
|
||||
{
|
||||
$this->assertIsInt($this->getFormat()->getPasses());
|
||||
$this->assertGreaterThan(0, $this->getFormat()->getPasses());
|
||||
}
|
||||
|
||||
public function testGetModulus()
|
||||
{
|
||||
$this->assertIsInt($this->getFormat()->getModulus());
|
||||
$this->assertGreaterThan(0, $this->getFormat()->getModulus());
|
||||
$this->assertEquals(0, $this->getFormat()->getModulus() % 2);
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Video/WMV3Test.php
Normal file
13
tests/FFMpeg/Unit/Format/Video/WMV3Test.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use FFMpeg\Format\Video\WMV3;
|
||||
|
||||
class WMV3Test extends VideoTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new WMV3();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Video/WMVTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Video/WMVTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use FFMpeg\Format\Video\WMV;
|
||||
|
||||
class WMVTest extends VideoTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new WMV();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Video/WebMTest.php
Normal file
13
tests/FFMpeg/Unit/Format/Video/WebMTest.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use FFMpeg\Format\Video\WebM;
|
||||
|
||||
class WebMTest extends VideoTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new WebM();
|
||||
}
|
||||
}
|
||||
13
tests/FFMpeg/Unit/Format/Video/X264Test.php
Normal file
13
tests/FFMpeg/Unit/Format/Video/X264Test.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Format\Video;
|
||||
|
||||
use FFMpeg\Format\Video\X264;
|
||||
|
||||
class X264Test extends VideoTestCase
|
||||
{
|
||||
public function getFormat()
|
||||
{
|
||||
return new X264();
|
||||
}
|
||||
}
|
||||
9
tests/FFMpeg/Unit/Media/AbstractMediaTestCase.php
Normal file
9
tests/FFMpeg/Unit/Media/AbstractMediaTestCase.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use Tests\FFMpeg\Unit\TestCase;
|
||||
|
||||
abstract class AbstractMediaTestCase extends TestCase
|
||||
{
|
||||
}
|
||||
38
tests/FFMpeg/Unit/Media/AbstractStreamableTestCase.php
Normal file
38
tests/FFMpeg/Unit/Media/AbstractStreamableTestCase.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
abstract class AbstractStreamableTestCase extends AbstractMediaTestCase
|
||||
{
|
||||
public function testGetStreams()
|
||||
{
|
||||
$classname = $this->getClassName();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$format = $this->getFormatMock();
|
||||
|
||||
$ffprobe->expects($this->once())
|
||||
->method('format')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue($format));
|
||||
|
||||
$media = new $classname(__FILE__, $this->getFFMpegDriverMock(), $ffprobe);
|
||||
$this->assertSame($format, $media->getFormat());
|
||||
}
|
||||
|
||||
public function testGetFormat()
|
||||
{
|
||||
$classname = $this->getClassName();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$streams = $this->getStreamCollectionMock();
|
||||
|
||||
$ffprobe->expects($this->once())
|
||||
->method('streams')
|
||||
->with(__FILE__)
|
||||
->will($this->returnValue($streams));
|
||||
|
||||
$media = new $classname(__FILE__, $this->getFFMpegDriverMock(), $ffprobe);
|
||||
$this->assertSame($streams, $media->getStreams());
|
||||
}
|
||||
|
||||
abstract protected function getClassName();
|
||||
}
|
||||
35
tests/FFMpeg/Unit/Media/AdvancedMediaTest.php
Normal file
35
tests/FFMpeg/Unit/Media/AdvancedMediaTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Media\AdvancedMedia;
|
||||
|
||||
class AdvancedMediaTest extends AbstractMediaTestCase
|
||||
{
|
||||
public function testGetInputs()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$advancedMedia = new AdvancedMedia([__FILE__, __FILE__], $driver, $ffprobe);
|
||||
$this->assertSame([__FILE__, __FILE__], $advancedMedia->getInputs());
|
||||
}
|
||||
|
||||
public function testGetInputsCount()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$advancedMedia = new AdvancedMedia([__FILE__, __FILE__], $driver, $ffprobe);
|
||||
$this->assertEquals(2, $advancedMedia->getInputsCount());
|
||||
}
|
||||
|
||||
public function testFiltersReturnFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$advancedMedia = new AdvancedMedia([__FILE__, __FILE__], $driver, $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\AdvancedMedia\ComplexFilters', $advancedMedia->filters());
|
||||
}
|
||||
}
|
||||
10
tests/FFMpeg/Unit/Media/AudioProg.php
Normal file
10
tests/FFMpeg/Unit/Media/AudioProg.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Format\AudioInterface;
|
||||
use FFMpeg\Format\ProgressableInterface;
|
||||
|
||||
abstract class AudioProg implements ProgressableInterface, AudioInterface
|
||||
{
|
||||
}
|
||||
341
tests/FFMpeg/Unit/Media/AudioTest.php
Normal file
341
tests/FFMpeg/Unit/Media/AudioTest.php
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Exception\RuntimeException;
|
||||
use FFMpeg\Media\Audio;
|
||||
|
||||
class AudioTest extends AbstractStreamableTestCase
|
||||
{
|
||||
public function testFiltersReturnsAudioFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\Audio\AudioFilters', $audio->filters());
|
||||
}
|
||||
|
||||
public function testAddFiltersAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
$audio->setFiltersCollection($filters);
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Audio\AudioFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$audio->addFilter($filter);
|
||||
}
|
||||
|
||||
public function testAddAVideoFilterThrowsException()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
$audio->setFiltersCollection($filters);
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Video\VideoFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->never())
|
||||
->method('add');
|
||||
|
||||
$this->expectException('\FFMpeg\Exception\InvalidArgumentException');
|
||||
$audio->addFilter($filter);
|
||||
}
|
||||
|
||||
public function testSaveWithFailure()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$failure = new RuntimeException('failed to encode');
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->will($this->throwException($failure));
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
$this->expectException('\FFMpeg\Exception\RuntimeException');
|
||||
$audio->save($format, $outputPathfile);
|
||||
}
|
||||
|
||||
public function testSaveAppliesFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$outputPathfile = '/target/file';
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Audio\AudioFilterInterface')->getMock();
|
||||
$filter->expects($this->once())
|
||||
->method('apply')
|
||||
->with($audio, $format)
|
||||
->will($this->returnValue(['extra-filter-command']));
|
||||
|
||||
$capturedCommands = [];
|
||||
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use (&$capturedCommands) {
|
||||
$capturedCommands[] = $commands;
|
||||
}));
|
||||
|
||||
$audio->addFilter($filter);
|
||||
$audio->save($format, $outputPathfile);
|
||||
|
||||
foreach ($capturedCommands as $commands) {
|
||||
$this->assertEquals('-y', $commands[0]);
|
||||
$this->assertEquals('-i', $commands[1]);
|
||||
$this->assertEquals(__FILE__, $commands[2]);
|
||||
$this->assertEquals('extra-filter-command', $commands[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveData
|
||||
*/
|
||||
public function testSaveShouldSave($threads, $expectedCommands, $expectedListeners, $format)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$configuration->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue($threads));
|
||||
|
||||
if ($threads) {
|
||||
$configuration->expects($this->once())
|
||||
->method('get')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue(24));
|
||||
} else {
|
||||
$configuration->expects($this->never())
|
||||
->method('get');
|
||||
}
|
||||
|
||||
$capturedCommand = $capturedListeners = null;
|
||||
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use (&$capturedCommand, &$capturedListeners) {
|
||||
$capturedCommand = $commands;
|
||||
$capturedListeners = $listeners;
|
||||
}));
|
||||
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
$audio->save($format, $outputPathfile);
|
||||
|
||||
$this->assertEquals($expectedCommands, $capturedCommand);
|
||||
$this->assertEquals($expectedListeners, $capturedListeners);
|
||||
}
|
||||
|
||||
public function provideSaveData()
|
||||
{
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$format->expects($this->any())
|
||||
->method('getAudioKiloBitrate')
|
||||
->will($this->returnValue(663));
|
||||
$format->expects($this->any())
|
||||
->method('getAudioChannels')
|
||||
->will($this->returnValue(5));
|
||||
|
||||
$audioFormat = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$audioFormat->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$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'));
|
||||
|
||||
$formatExtra = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$formatExtra->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue(['extra', 'param']));
|
||||
$formatExtra->expects($this->any())
|
||||
->method('getAudioKiloBitrate')
|
||||
->will($this->returnValue(665));
|
||||
$formatExtra->expects($this->any())
|
||||
->method('getAudioChannels')
|
||||
->will($this->returnValue(5));
|
||||
|
||||
$listeners = [$this->getMockBuilder('Alchemy\BinaryDriver\Listeners\ListenerInterface')->getMock()];
|
||||
|
||||
$progressableFormat = $this->getMockBuilder('Tests\FFMpeg\Unit\Media\AudioProg')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('createProgressListener')
|
||||
->will($this->returnValue($listeners));
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('getAudioKiloBitrate')
|
||||
->will($this->returnValue(666));
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('getAudioChannels')
|
||||
->will($this->returnValue(5));
|
||||
|
||||
return [
|
||||
[false, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-b:a', '663k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], null, $format],
|
||||
[false, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-acodec', 'patati-patata-audio',
|
||||
'-b:a', '664k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], null, $audioFormat],
|
||||
[false, [
|
||||
'-y', '-i', __FILE__,
|
||||
'extra', 'param',
|
||||
'-b:a', '665k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], null, $formatExtra],
|
||||
[true, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-threads', 24,
|
||||
'-b:a', '663k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], null, $format],
|
||||
[true, [
|
||||
'-y', '-i', __FILE__,
|
||||
'extra', 'param',
|
||||
'-threads', 24,
|
||||
'-b:a', '665k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], null, $formatExtra],
|
||||
[false, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-b:a', '666k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], $listeners, $progressableFormat],
|
||||
[true, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-threads', 24,
|
||||
'-b:a', '666k',
|
||||
'-ac', '5',
|
||||
'/target/file',
|
||||
], $listeners, $progressableFormat],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSaveShouldNotStoreCodecFiltersInTheMedia()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$configuration->expects($this->any())
|
||||
->method('has')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$configuration->expects($this->any())
|
||||
->method('get')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue(24));
|
||||
|
||||
$capturedCommands = [];
|
||||
|
||||
$driver->expects($this->exactly(2))
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use (&$capturedCommands, &$capturedListeners) {
|
||||
$capturedCommands[] = $commands;
|
||||
}));
|
||||
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue(['param']));
|
||||
|
||||
$audio = new Audio(__FILE__, $driver, $ffprobe);
|
||||
$audio->save($format, $outputPathfile);
|
||||
$audio->save($format, $outputPathfile);
|
||||
|
||||
$expected = [
|
||||
'-y', '-i', __FILE__, 'param', '-threads', 24, '/target/file',
|
||||
];
|
||||
|
||||
foreach ($capturedCommands as $capturedCommand) {
|
||||
$this->assertEquals($expected, $capturedCommand);
|
||||
}
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return 'FFMpeg\Media\Audio';
|
||||
}
|
||||
}
|
||||
67
tests/FFMpeg/Unit/Media/ClipTest.php
Normal file
67
tests/FFMpeg/Unit/Media/ClipTest.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Media\Clip;
|
||||
|
||||
class ClipTest extends AbstractMediaTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideBuildOptions
|
||||
*/
|
||||
public function testBuildCommand($startValue, $durationValue, $commands)
|
||||
{
|
||||
$configuration = $this->getConfigurationMock();
|
||||
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$start = $this->getTimeCodeMock();
|
||||
$start->expects($this->once())
|
||||
->method('__toString')
|
||||
->will($this->returnValue($startValue));
|
||||
|
||||
$duration = null;
|
||||
if (null !== $durationValue) {
|
||||
$duration = $this->getTimeCodeMock();
|
||||
$duration->expects($this->once())
|
||||
->method('__toString')
|
||||
->will($this->returnValue($durationValue));
|
||||
}
|
||||
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getPasses')
|
||||
->will($this->returnValue(1));
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$clip = new Clip($this->getVideoMock(__FILE__), $driver, $ffprobe, $start, $duration);
|
||||
$fc = $clip->getFinalCommand($format, $outputPathfile);
|
||||
|
||||
$this->assertCount(1, $fc);
|
||||
$this->assertStringStartsWith(implode(' ', $commands), $fc[0]);
|
||||
}
|
||||
|
||||
public function provideBuildOptions()
|
||||
{
|
||||
return [
|
||||
['SS01', null, [
|
||||
'-y', '-ss', 'SS01',
|
||||
'-i', __FILE__, ],
|
||||
],
|
||||
['SS02', 'D02', [
|
||||
'-y', '-ss', 'SS02',
|
||||
'-i', __FILE__,
|
||||
'-t', 'D02', ],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
149
tests/FFMpeg/Unit/Media/ConcatTest.php
Normal file
149
tests/FFMpeg/Unit/Media/ConcatTest.php
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Media\Concat;
|
||||
use Spatie\TemporaryDirectory\TemporaryDirectory;
|
||||
|
||||
class ConcatTest extends AbstractMediaTestCase
|
||||
{
|
||||
public function testGetSources()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$concat = new Concat([__FILE__, __FILE__], $driver, $ffprobe);
|
||||
$this->assertSame([__FILE__, __FILE__], $concat->getSources());
|
||||
}
|
||||
|
||||
public function testFiltersReturnFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$concat = new Concat([__FILE__, __FILE__], $driver, $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\Concat\ConcatFilters', $concat->filters());
|
||||
}
|
||||
|
||||
public function testAddFiltersAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Concat\ConcatFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$concat = new Concat([__FILE__, __FILE__], $driver, $ffprobe);
|
||||
$concat->setFiltersCollection($filters);
|
||||
$concat->addFilter($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveFromSameCodecsOptions
|
||||
*/
|
||||
public function testSaveFromSameCodecs($streamCopy, $commands)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$pathfile = '/target/destination';
|
||||
|
||||
array_push($commands, $pathfile);
|
||||
|
||||
$driver->expects($this->exactly(1))
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) {
|
||||
}));
|
||||
|
||||
$concat = new Concat([__FILE__, 'concat-2.mp4'], $driver, $ffprobe);
|
||||
$concat->saveFromSameCodecs($pathfile, $streamCopy);
|
||||
|
||||
$this->assertEquals('-f', $commands[0]);
|
||||
$this->assertEquals('concat', $commands[1]);
|
||||
$this->assertEquals('-safe', $commands[2]);
|
||||
$this->assertEquals('0', $commands[3]);
|
||||
$this->assertEquals('-i', $commands[4]);
|
||||
if (isset($commands[6]) && (0 == strcmp($commands[6], '-c'))) {
|
||||
$this->assertEquals('-c', $commands[6]);
|
||||
$this->assertEquals('copy', $commands[7]);
|
||||
}
|
||||
}
|
||||
|
||||
public function provideSaveFromSameCodecsOptions()
|
||||
{
|
||||
$fs = (new TemporaryDirectory())->create();
|
||||
$tmpFile = $fs->path('ffmpeg-concat');
|
||||
touch($tmpFile);
|
||||
|
||||
return [
|
||||
[
|
||||
true,
|
||||
[
|
||||
'-f', 'concat',
|
||||
'-safe', '0',
|
||||
'-i', $tmpFile,
|
||||
'-c', 'copy',
|
||||
],
|
||||
],
|
||||
[
|
||||
false,
|
||||
[
|
||||
'-f', 'concat',
|
||||
'-safe', '0',
|
||||
'-i', $tmpFile,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveFromDifferentCodecsOptions
|
||||
*/
|
||||
public function testSaveFromDifferentCodecs($commands)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$format = $this->getFormatInterfaceMock();
|
||||
|
||||
$pathfile = '/target/destination';
|
||||
|
||||
array_push($commands, $pathfile);
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($commands);
|
||||
|
||||
$concat = new Concat([__FILE__, 'concat-2.mp4'], $driver, $ffprobe);
|
||||
$this->assertSame($concat, $concat->saveFromDifferentCodecs($format, $pathfile));
|
||||
}
|
||||
|
||||
public function provideSaveFromDifferentCodecsOptions()
|
||||
{
|
||||
return [
|
||||
[
|
||||
[
|
||||
'-i', __FILE__,
|
||||
'-i', 'concat-2.mp4',
|
||||
'-filter_complex',
|
||||
'[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]',
|
||||
'-map', '[v]',
|
||||
'-map', '[a]',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
108
tests/FFMpeg/Unit/Media/FrameTest.php
Normal file
108
tests/FFMpeg/Unit/Media/FrameTest.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Media\Frame;
|
||||
|
||||
class FrameTest extends AbstractMediaTestCase
|
||||
{
|
||||
public function testGetTimeCode()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
|
||||
$frame = new Frame($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode);
|
||||
$this->assertSame($timecode, $frame->getTimeCode());
|
||||
}
|
||||
|
||||
public function testFiltersReturnFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
|
||||
$frame = new Frame($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\Frame\FrameFilters', $frame->filters());
|
||||
}
|
||||
|
||||
public function testAddFiltersAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Frame\FrameFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$frame = new Frame($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode);
|
||||
$frame->setFiltersCollection($filters);
|
||||
$frame->addFilter($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveOptions
|
||||
*/
|
||||
public function testSave($accurate, $base64, $commands)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
$timecode->expects($this->once())
|
||||
->method('__toString')
|
||||
->will($this->returnValue('timecode'));
|
||||
|
||||
$pathfile = '/target/destination';
|
||||
|
||||
if (!$base64) {
|
||||
array_push($commands, $pathfile);
|
||||
}
|
||||
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($commands);
|
||||
|
||||
if (!$base64) {
|
||||
$frame = new Frame($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode);
|
||||
$this->assertSame($frame, $frame->save($pathfile, $accurate, $base64));
|
||||
} else {
|
||||
$frame = new Frame($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode);
|
||||
$frame->save($pathfile, $accurate, $base64);
|
||||
}
|
||||
}
|
||||
|
||||
public function provideSaveOptions()
|
||||
{
|
||||
return [
|
||||
[false, false, [
|
||||
'-y', '-ss', 'timecode',
|
||||
'-i', __FILE__,
|
||||
'-vframes', '1',
|
||||
'-f', 'image2', ],
|
||||
],
|
||||
[true, false, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-vframes', '1', '-ss', 'timecode',
|
||||
'-f', 'image2', ],
|
||||
],
|
||||
[false, true, [
|
||||
'-y', '-ss', 'timecode',
|
||||
'-i', __FILE__,
|
||||
'-vframes', '1',
|
||||
'-f', 'image2pipe', '-', ],
|
||||
],
|
||||
[true, true, [
|
||||
'-y', '-i', __FILE__,
|
||||
'-vframes', '1', '-ss', 'timecode',
|
||||
'-f', 'image2pipe', '-', ],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
116
tests/FFMpeg/Unit/Media/GifTest.php
Normal file
116
tests/FFMpeg/Unit/Media/GifTest.php
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\Media\Gif;
|
||||
|
||||
class GifTest extends AbstractMediaTestCase
|
||||
{
|
||||
public function testGetTimeCode()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
$dimension = $this->getDimensionMock();
|
||||
|
||||
$gif = new Gif($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode, $dimension);
|
||||
$this->assertSame($timecode, $gif->getTimeCode());
|
||||
}
|
||||
|
||||
public function testGetDimension()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
$dimension = $this->getDimensionMock();
|
||||
|
||||
$gif = new Gif($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode, $dimension);
|
||||
$this->assertSame($dimension, $gif->getDimension());
|
||||
}
|
||||
|
||||
public function testFiltersReturnFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
$dimension = $this->getDimensionMock();
|
||||
|
||||
$gif = new Gif($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode, $dimension);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\Gif\GifFilters', $gif->filters());
|
||||
}
|
||||
|
||||
public function testAddFiltersAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
$dimension = $this->getDimensionMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Gif\GifFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$gif = new Gif($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode, $dimension);
|
||||
$gif->setFiltersCollection($filters);
|
||||
$gif->addFilter($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveOptions
|
||||
*/
|
||||
public function testSave($dimension, $duration, $commands)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$timecode = $this->getTimeCodeMock();
|
||||
|
||||
$timecode->expects($this->once())
|
||||
->method('__toString')
|
||||
->will($this->returnValue('timecode'));
|
||||
|
||||
$pathfile = '/target/destination';
|
||||
|
||||
array_push($commands, $pathfile);
|
||||
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($commands);
|
||||
|
||||
$gif = new Gif($this->getVideoMock(__FILE__), $driver, $ffprobe, $timecode, $dimension, $duration);
|
||||
$this->assertSame($gif, $gif->save($pathfile));
|
||||
}
|
||||
|
||||
public function provideSaveOptions()
|
||||
{
|
||||
return [
|
||||
[
|
||||
new Dimension(320, 240), 3,
|
||||
[
|
||||
'-ss', 'timecode',
|
||||
'-t', '3',
|
||||
'-i', __FILE__,
|
||||
'-vf',
|
||||
'scale=320:-1', '-gifflags',
|
||||
'+transdiff', '-y',
|
||||
],
|
||||
],
|
||||
[
|
||||
new Dimension(320, 240), null,
|
||||
[
|
||||
'-ss', 'timecode',
|
||||
'-i', __FILE__,
|
||||
'-vf',
|
||||
'scale=320:-1', '-gifflags',
|
||||
'+transdiff', '-y',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
10
tests/FFMpeg/Unit/Media/Prog.php
Normal file
10
tests/FFMpeg/Unit/Media/Prog.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Format\ProgressableInterface;
|
||||
use FFMpeg\Format\VideoInterface;
|
||||
|
||||
abstract class Prog implements ProgressableInterface, VideoInterface
|
||||
{
|
||||
}
|
||||
713
tests/FFMpeg/Unit/Media/VideoTest.php
Normal file
713
tests/FFMpeg/Unit/Media/VideoTest.php
Normal file
|
|
@ -0,0 +1,713 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Exception\RuntimeException;
|
||||
use FFMpeg\Format\Video\X264;
|
||||
use FFMpeg\Media\Video;
|
||||
|
||||
class VideoTest extends AbstractStreamableTestCase
|
||||
{
|
||||
public function testFiltersReturnsVideoFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\Video\VideoFilters', $video->filters());
|
||||
}
|
||||
|
||||
public function testAddFiltersAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$video->setFiltersCollection($filters);
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Video\VideoFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$video->addFilter($filter);
|
||||
}
|
||||
|
||||
public function testAddAudioFilterAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$video->setFiltersCollection($filters);
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Audio\AudioFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$video->addFilter($filter);
|
||||
}
|
||||
|
||||
public function testFrameShouldReturnAFrame()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$at = $this->getTimeCodeMock();
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$frame = $video->frame($at);
|
||||
|
||||
$this->assertInstanceOf('FFMpeg\Media\Frame', $frame);
|
||||
$this->assertSame($at, $frame->getTimeCode());
|
||||
$this->assertSame(__FILE__, $frame->getPathfile());
|
||||
}
|
||||
|
||||
public function testSaveWithFailure()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$outputPathfile = '/target/file';
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getPasses')
|
||||
->will($this->returnValue(1));
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$failure = new RuntimeException('failed to encode');
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->will($this->throwException($failure));
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$this->expectException('\FFMpeg\Exception\RuntimeException');
|
||||
$video->save($format, $outputPathfile);
|
||||
}
|
||||
|
||||
public function testSaveAppliesFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
$outputPathfile = '/target/file';
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$format->expects($this->any())
|
||||
->method('getPasses')
|
||||
->will($this->returnValue(2));
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Video\VideoFilterInterface')->getMock();
|
||||
$filter->expects($this->once())
|
||||
->method('apply')
|
||||
->with($video, $format)
|
||||
->will($this->returnValue(['extra-filter-command']));
|
||||
|
||||
$capturedCommands = [];
|
||||
|
||||
$driver->expects($this->exactly(2))
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use (&$capturedCommands) {
|
||||
$capturedCommands[] = $commands;
|
||||
}));
|
||||
|
||||
$video->addFilter($filter);
|
||||
$video->save($format, $outputPathfile);
|
||||
|
||||
foreach ($capturedCommands as $commands) {
|
||||
$this->assertEquals('-y', $commands[0]);
|
||||
$this->assertEquals('-i', $commands[1]);
|
||||
$this->assertEquals(__FILE__, $commands[2]);
|
||||
$this->assertEquals('extra-filter-command', $commands[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveData
|
||||
*/
|
||||
public function testSaveShouldSave($threads, $expectedCommands, $expectedListeners, $format)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$configuration->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue($threads));
|
||||
|
||||
if ($threads) {
|
||||
$configuration->expects($this->once())
|
||||
->method('get')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue(24));
|
||||
} else {
|
||||
$configuration->expects($this->never())
|
||||
->method('get');
|
||||
}
|
||||
|
||||
$capturedCommands = [];
|
||||
$capturedListeners = null;
|
||||
|
||||
$driver->expects($this->exactly(count($expectedCommands)))
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use (&$capturedCommands, &$capturedListeners) {
|
||||
$capturedCommands[] = $commands;
|
||||
$capturedListeners = $listeners;
|
||||
}));
|
||||
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$video->save($format, $outputPathfile);
|
||||
|
||||
foreach ($capturedCommands as $passKey => $pass) {
|
||||
$prefix = null;
|
||||
if (count($expectedCommands) > 1) {
|
||||
// look for pass commands only in multipass cases
|
||||
foreach ($pass as $command) {
|
||||
$prefix = null;
|
||||
if (false !== strpos($command, '/pass-')) {
|
||||
$prefix = $command;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $prefix) {
|
||||
$this->fail('Unable to find pass prefix command.');
|
||||
}
|
||||
}
|
||||
|
||||
$found = false || (null === $prefix);
|
||||
foreach ($pass as $key => $command) {
|
||||
if ($command === $prefix) {
|
||||
$found = true;
|
||||
unset($capturedCommands[$passKey][$key]);
|
||||
$capturedCommands[$passKey] = array_values($capturedCommands[$passKey]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->fail('Unable to find pass prefix command back.');
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertEquals($expectedCommands, $capturedCommands);
|
||||
$this->assertEquals($expectedListeners, $capturedListeners);
|
||||
}
|
||||
|
||||
public function provideSaveData()
|
||||
{
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$format->expects($this->any())
|
||||
->method('getKiloBitrate')
|
||||
->will($this->returnValue(663));
|
||||
$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));
|
||||
$format->expects($this->any())
|
||||
->method('getAdditionalParameters')
|
||||
->will($this->returnValue(['foo', 'bar']));
|
||||
|
||||
$format2 = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format2->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$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(['foo', 'bar']));
|
||||
|
||||
$audioFormat = $this->getMockBuilder('FFMpeg\Format\AudioInterface')->getMock();
|
||||
$audioFormat->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$audioFormat->expects($this->any())
|
||||
->method('getAudioCodec')
|
||||
->will($this->returnValue('patati-patata-audio'));
|
||||
$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));
|
||||
|
||||
$audioVideoFormat = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$audioVideoFormat->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$audioVideoFormat->expects($this->any())
|
||||
->method('getVideoCodec')
|
||||
->will($this->returnValue('gloubi-boulga-video'));
|
||||
$audioVideoFormat->expects($this->any())
|
||||
->method('getAudioCodec')
|
||||
->will($this->returnValue('patati-patata-audio'));
|
||||
$audioVideoFormat->expects($this->any())
|
||||
->method('getKiloBitrate')
|
||||
->will($this->returnValue(664));
|
||||
$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));
|
||||
$audioVideoFormat->expects($this->any())
|
||||
->method('getAdditionalParameters')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$audioVideoFormatSinglePass = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$audioVideoFormatSinglePass->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$audioVideoFormatSinglePass->expects($this->any())
|
||||
->method('getVideoCodec')
|
||||
->will($this->returnValue('gloubi-boulga-video'));
|
||||
$audioVideoFormatSinglePass->expects($this->any())
|
||||
->method('getAudioCodec')
|
||||
->will($this->returnValue('patati-patata-audio'));
|
||||
$audioVideoFormatSinglePass->expects($this->any())
|
||||
->method('getKiloBitrate')
|
||||
->will($this->returnValue(664));
|
||||
$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));
|
||||
$audioVideoFormatSinglePass->expects($this->any())
|
||||
->method('getAdditionalParameters')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$formatExtra = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$formatExtra->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue(['extra', 'param']));
|
||||
$formatExtra->expects($this->any())
|
||||
->method('getKiloBitrate')
|
||||
->will($this->returnValue(665));
|
||||
$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));
|
||||
$formatExtra->expects($this->any())
|
||||
->method('getAdditionalParameters')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$formatExtra2 = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$formatExtra2->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue(['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([]));
|
||||
|
||||
$listeners = [$this->getMockBuilder('Alchemy\BinaryDriver\Listeners\ListenerInterface')->getMock()];
|
||||
|
||||
$progressableFormat = $this->getMockBuilder('Tests\FFMpeg\Unit\Media\Prog')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('createProgressListener')
|
||||
->will($this->returnValue($listeners));
|
||||
$progressableFormat->expects($this->any())
|
||||
->method('getKiloBitrate')
|
||||
->will($this->returnValue(666));
|
||||
$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));
|
||||
|
||||
$progressableFormat2 = $this->getMockBuilder('Tests\FFMpeg\Unit\Media\Prog')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$progressableFormat2->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$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())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
$progressableAudioFormat->expects($this->any())
|
||||
->method('getAudioCodec')
|
||||
->will($this->returnValue('patati-patata-audio'));
|
||||
$progressableAudioFormat->expects($this->any())
|
||||
->method('createProgressListener')
|
||||
->will($this->returnValue($listeners));
|
||||
$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));
|
||||
|
||||
return [
|
||||
[false, [[
|
||||
'-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, 'foo', 'bar', '-pass', 1, '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-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, 'foo', 'bar', '-pass', 2, '-passlogfile',
|
||||
'/target/file',
|
||||
]], null, $format],
|
||||
[false, [[
|
||||
'-y', '-i', __FILE__,
|
||||
'-vcodec', 'gloubi-boulga-video',
|
||||
'-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', '-ac', '2', '-pass', '1', '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-y', '-i', __FILE__,
|
||||
'-vcodec', 'gloubi-boulga-video',
|
||||
'-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', '-ac', '2', '-pass', '2', '-passlogfile',
|
||||
'/target/file',
|
||||
]], null, $audioVideoFormat],
|
||||
[false, [[
|
||||
'-y', '-i', __FILE__,
|
||||
'-vcodec', 'gloubi-boulga-video',
|
||||
'-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', '-ac', '2',
|
||||
'/target/file',
|
||||
]], null, $audioVideoFormatSinglePass],
|
||||
[false, [[
|
||||
'-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', '-ac', '2', '-pass', '1', '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-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', '-ac', '2', '-pass', '2', '-passlogfile',
|
||||
'/target/file',
|
||||
]], null, $formatExtra],
|
||||
[true, [[
|
||||
'-y', '-i', __FILE__,
|
||||
'-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, 'foo', 'bar', '-pass', 1, '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-y', '-i', __FILE__,
|
||||
'-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, 'foo', 'bar', '-pass', 2, '-passlogfile',
|
||||
'/target/file',
|
||||
]], null, $format2],
|
||||
[true, [[
|
||||
'-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', '-ac', '2', '-pass', '1', '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-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', '-ac', '2', '-pass', '2', '-passlogfile',
|
||||
'/target/file',
|
||||
]], null, $formatExtra2],
|
||||
[false, [[
|
||||
'-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', '-ac', '2', '-pass', '1', '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-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', '-ac', '2', '-pass', '2', '-passlogfile',
|
||||
'/target/file',
|
||||
]], $listeners, $progressableFormat2],
|
||||
[true, [[
|
||||
'-y', '-i', __FILE__,
|
||||
'-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', '-ac', '2', '-pass', '1', '-passlogfile',
|
||||
'/target/file',
|
||||
], [
|
||||
'-y', '-i', __FILE__,
|
||||
'-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', '-ac', '2', '-pass', '2', '-passlogfile',
|
||||
'/target/file',
|
||||
]], $listeners, $progressableFormat],
|
||||
[true, [[
|
||||
'-y', '-i', __FILE__,
|
||||
'-threads', 24, '-acodec', 'patati-patata-audio',
|
||||
'-b:a', '92k', '-ac', '2',
|
||||
'/target/file',
|
||||
]], null, $audioFormat],
|
||||
[true, [[
|
||||
'-y', '-i', __FILE__,
|
||||
'-threads', 24, '-acodec', 'patati-patata-audio',
|
||||
'-b:a', '92k', '-ac', '2',
|
||||
'/target/file',
|
||||
]], $listeners, $progressableAudioFormat],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSaveShouldNotStoreCodecFiltersInTheMedia()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$configuration->expects($this->any())
|
||||
->method('has')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$configuration->expects($this->any())
|
||||
->method('get')
|
||||
->with($this->equalTo('ffmpeg.threads'))
|
||||
->will($this->returnValue(24));
|
||||
|
||||
$capturedCommands = [];
|
||||
|
||||
$driver->expects($this->exactly(4))
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use (&$capturedCommands, &$capturedListeners) {
|
||||
$capturedCommands[] = $commands;
|
||||
}));
|
||||
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$format = $this->getMockBuilder('FFMpeg\Format\VideoInterface')->getMock();
|
||||
$format->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue(['param']));
|
||||
$format->expects($this->any())
|
||||
->method('getPasses')
|
||||
->will($this->returnValue(2));
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$video->save($format, $outputPathfile);
|
||||
$video->save($format, $outputPathfile);
|
||||
|
||||
$expectedPass1 = [
|
||||
'-y', '-i', __FILE__, 'param', '-threads', 24, '-b:v', 'k', '-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',
|
||||
'-pass', '1', '-passlogfile', '/target/file',
|
||||
];
|
||||
$expectedPass2 = [
|
||||
'-y', '-i', __FILE__, 'param', '-threads', 24, '-b:v', 'k', '-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',
|
||||
'-pass', '2', '-passlogfile', '/target/file',
|
||||
];
|
||||
|
||||
$n = 1;
|
||||
foreach ($capturedCommands as $capturedCommand) {
|
||||
$prefix = null;
|
||||
foreach ($capturedCommand as $command) {
|
||||
if (false !== strpos($command, '/pass-')) {
|
||||
$prefix = $command;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $prefix) {
|
||||
$this->fail('Unable to find pass prefix command.');
|
||||
}
|
||||
|
||||
$found = false;
|
||||
foreach ($capturedCommand as $key => $command) {
|
||||
if ($command === $prefix) {
|
||||
$found = true;
|
||||
unset($capturedCommand[$key]);
|
||||
$capturedCommand = array_values($capturedCommand);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->fail('Unable to find pass prefix command back.');
|
||||
}
|
||||
|
||||
if (0 === $n % 2) {
|
||||
$this->assertEquals($expectedPass2, $capturedCommand);
|
||||
} else {
|
||||
$this->assertEquals($expectedPass1, $capturedCommand);
|
||||
}
|
||||
++$n;
|
||||
}
|
||||
}
|
||||
|
||||
public function testCaseWhereKiloBitRateIsEqualToZero()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$pathfile = '/target/destination';
|
||||
$outputPathfile = '/target/file';
|
||||
|
||||
$format = new X264();
|
||||
$format->setKiloBitrate(0);
|
||||
|
||||
$configuration = $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
|
||||
$driver->expects($this->any())
|
||||
->method('getConfiguration')
|
||||
->will($this->returnValue($configuration));
|
||||
|
||||
$self = $this;
|
||||
|
||||
$driver->expects($this->exactly(1))
|
||||
->method('command')
|
||||
->with($this->isType('array'), false, $this->anything())
|
||||
->will($this->returnCallback(function ($commands, $errors, $listeners) use ($self) {
|
||||
$self->assertTrue(!in_array('-b:v', $commands));
|
||||
}));
|
||||
|
||||
$video = new Video(__FILE__, $driver, $ffprobe);
|
||||
$video->save($format, $outputPathfile);
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return 'FFMpeg\Media\Video';
|
||||
}
|
||||
}
|
||||
70
tests/FFMpeg/Unit/Media/WaveformTest.php
Normal file
70
tests/FFMpeg/Unit/Media/WaveformTest.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit\Media;
|
||||
|
||||
use FFMpeg\Media\Waveform;
|
||||
|
||||
class WaveformTest extends AbstractMediaTestCase
|
||||
{
|
||||
public function testFiltersReturnFilters()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$waveform = new Waveform($this->getAudioMock(__FILE__), $driver, $ffprobe, 640, 120);
|
||||
$this->assertInstanceOf('FFMpeg\Filters\Waveform\WaveformFilters', $waveform->filters());
|
||||
}
|
||||
|
||||
public function testAddFiltersAddsAFilter()
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$filters = $this->getMockBuilder('FFMpeg\Filters\FiltersCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$filter = $this->getMockBuilder('FFMpeg\Filters\Waveform\WaveformFilterInterface')->getMock();
|
||||
|
||||
$filters->expects($this->once())
|
||||
->method('add')
|
||||
->with($filter);
|
||||
|
||||
$waveform = new Waveform($this->getAudioMock(__FILE__), $driver, $ffprobe, 640, 120);
|
||||
$waveform->setFiltersCollection($filters);
|
||||
$waveform->addFilter($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSaveOptions
|
||||
*/
|
||||
public function testSave($commands)
|
||||
{
|
||||
$driver = $this->getFFMpegDriverMock();
|
||||
$ffprobe = $this->getFFProbeMock();
|
||||
|
||||
$pathfile = '/tests/files/Audio.mp3';
|
||||
|
||||
array_push($commands, $pathfile);
|
||||
|
||||
$driver->expects($this->once())
|
||||
->method('command')
|
||||
->with($commands);
|
||||
|
||||
$waveform = new Waveform($this->getAudioMock(__FILE__), $driver, $ffprobe, 640, 120, array('#FFFFFF'));
|
||||
$this->assertSame($waveform, $waveform->save($pathfile));
|
||||
}
|
||||
|
||||
public function provideSaveOptions()
|
||||
{
|
||||
return [
|
||||
[
|
||||
[
|
||||
'-y', '-i', null, '-filter_complex',
|
||||
'showwavespic=colors=#FFFFFF:s=640x120',
|
||||
'-frames:v', '1',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
168
tests/FFMpeg/Unit/TestCase.php
Normal file
168
tests/FFMpeg/Unit/TestCase.php
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\FFMpeg\Unit;
|
||||
|
||||
use Tests\FFMpeg\BaseTestCase;
|
||||
|
||||
class TestCase extends BaseTestCase
|
||||
{
|
||||
public function getLoggerMock()
|
||||
{
|
||||
return $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
||||
}
|
||||
|
||||
public function getCacheMock()
|
||||
{
|
||||
return $this->getMockBuilder('Psr\Cache\CacheItemPoolInterface')->getMock();
|
||||
}
|
||||
|
||||
public function getTimeCodeMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Coordinate\TimeCode')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getDimensionMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Coordinate\Dimension')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFramerateMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Coordinate\Framerate')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFrameMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Media\Frame')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getWaveformMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Media\Waveform')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFFMpegDriverMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Driver\FFMpegDriver')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFFProbeDriverMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Driver\FFProbeDriver')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFFProbeMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getStreamMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe\DataMapping\Stream')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFFProbeParserMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe\OutputParserInterface')->getMock();
|
||||
}
|
||||
|
||||
public function getFFProbeOptionsTesterMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe\OptionsTesterInterface')->getMock();
|
||||
}
|
||||
|
||||
public function getFFProbeMapperMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe\MapperInterface')->getMock();
|
||||
}
|
||||
|
||||
public function getFFProbeOptionsTesterMockWithOptions(array $options)
|
||||
{
|
||||
$tester = $this->getFFProbeOptionsTesterMock();
|
||||
|
||||
$tester->expects($this->any())
|
||||
->method('has')
|
||||
->will($this->returnCallback(function ($option) use ($options) {
|
||||
return in_array($option, $options);
|
||||
}));
|
||||
|
||||
return $tester;
|
||||
}
|
||||
|
||||
public function getConfigurationMock()
|
||||
{
|
||||
return $this->getMockBuilder('Alchemy\BinaryDriver\ConfigurationInterface')->getMock();
|
||||
}
|
||||
|
||||
public function getFormatMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe\DataMapping\Format')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getStreamCollectionMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\FFProbe\DataMapping\StreamCollection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
protected function getAudioMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Media\Audio')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
protected function getVideoMock($filename = null)
|
||||
{
|
||||
$video = $this->getMockBuilder('FFMpeg\Media\Video')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$video->expects($this->any())
|
||||
->method('getPathfile')
|
||||
->will($this->returnValue($filename));
|
||||
|
||||
return $video;
|
||||
}
|
||||
|
||||
public function getConcatMock()
|
||||
{
|
||||
return $this->getMockBuilder('FFMpeg\Media\Concat')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function getFormatInterfaceMock()
|
||||
{
|
||||
$FormatInterface = $this->getMockBuilder('FFMpeg\Format\FormatInterface')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$FormatInterface->expects($this->any())
|
||||
->method('getExtraParams')
|
||||
->will($this->returnValue([]));
|
||||
|
||||
return $FormatInterface;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue