Merge branch 'master' into spectrumpic

This commit is contained in:
Marcus Bointon 2021-06-18 19:09:36 +02:00 committed by GitHub
commit 839207457f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 17 deletions

3
.gitattributes vendored
View file

@ -2,3 +2,6 @@
.gitignore export-ignore .gitignore export-ignore
.github export-ignore .github export-ignore
docs export-ignore docs export-ignore
tests export-ignore
phpunit.xml.dist export-ignore
.travis.yml export-ignore

View file

@ -12,12 +12,10 @@ Check another amazing repo: [PHP FFMpeg extras](https://github.com/alchemy-fr/PH
### How this library works: ### How this library works:
This library requires a working FFMpeg install. You will need both FFMpeg and FFProbe binaries to use it. This library requires a working [FFMpeg install](https://ffmpeg.org/download.html). You will need both FFMpeg and FFProbe binaries to use it.
Be sure that these binaries can be located with system PATH to get the benefit of the binary detection, Be sure that these binaries can be located with system PATH to get the benefit of the binary detection,
otherwise you should have to explicitly give the binaries path on load. otherwise you should have to explicitly give the binaries path on load.
For Windows users: Please find the binaries at http://ffmpeg.zeranoe.com/builds/.
### Known issues: ### Known issues:
- Using rotate and resize will produce a corrupted output when using - Using rotate and resize will produce a corrupted output when using
@ -111,7 +109,7 @@ video. Frames can be extracted.
You can transcode videos using the `FFMpeg\Media\Video:save` method. You will You can transcode videos using the `FFMpeg\Media\Video:save` method. You will
pass a `FFMpeg\Format\FormatInterface` for that. pass a `FFMpeg\Format\FormatInterface` for that.
Please note that audio and video bitrate are set on the format. Please note that audio and video bitrate are set on the format. You can disable the `-b:v` option by setting the kilo bitrate to 0.
```php ```php
$format = new FFMpeg\Format\Video\X264(); $format = new FFMpeg\Format\Video\X264();
@ -503,7 +501,7 @@ $video
The boolean parameter of the save function allows you to use the copy parameter which accelerates drastically the generation of the encoded file. The boolean parameter of the save function allows you to use the copy parameter which accelerates drastically the generation of the encoded file.
To concatenate videos encoded with the same codec, do as follow: To concatenate videos encoded with the different codec, do as follow:
```php ```php
// In order to instantiate the video object, you HAVE TO pass a path to a valid video file. // In order to instantiate the video object, you HAVE TO pass a path to a valid video file.

View file

@ -54,7 +54,7 @@ abstract class DefaultVideo extends DefaultAudio implements VideoInterface
*/ */
public function setKiloBitrate($kiloBitrate) public function setKiloBitrate($kiloBitrate)
{ {
if ($kiloBitrate < 1) { if ($kiloBitrate < 0) {
throw new InvalidArgumentException('Wrong kiloBitrate value'); throw new InvalidArgumentException('Wrong kiloBitrate value');
} }

View file

@ -22,7 +22,7 @@ class X264 extends DefaultVideo
/** @var int */ /** @var int */
private $passes = 2; private $passes = 2;
public function __construct($audioCodec = 'libfaac', $videoCodec = 'libx264') public function __construct($audioCodec = 'aac', $videoCodec = 'libx264')
{ {
$this $this
->setAudioCodec($audioCodec) ->setAudioCodec($audioCodec)
@ -81,7 +81,7 @@ class X264 extends DefaultVideo
*/ */
public function getPasses() public function getPasses()
{ {
return $this->passes; return $this->getKiloBitrate() === 0 ? 1 : $this->passes;
} }
/** /**

View file

@ -86,6 +86,10 @@ abstract class AbstractVideo extends Audio
// FFMpeg\Format\ProgressListener\AbstractProgressListener class // FFMpeg\Format\ProgressListener\AbstractProgressListener class
foreach ($filters as $filter) { foreach ($filters as $filter) {
if ($filter instanceof ClipFilter) { if ($filter instanceof ClipFilter) {
if ($filter->getDuration() === NULL) {
continue;
}
$duration = $filter->getDuration()->toSeconds(); $duration = $filter->getDuration()->toSeconds();
break; break;
} }
@ -158,8 +162,11 @@ abstract class AbstractVideo extends Audio
} }
if ($format instanceof VideoInterface) { if ($format instanceof VideoInterface) {
$commands[] = '-b:v'; if ($format->getKiloBitrate() !== 0) {
$commands[] = $format->getKiloBitrate() . 'k'; $commands[] = '-b:v';
$commands[] = $format->getKiloBitrate() . 'k';
}
$commands[] = '-refs'; $commands[] = '-refs';
$commands[] = '6'; $commands[] = '6';
$commands[] = '-coder'; $commands[] = '-coder';

View file

@ -10,22 +10,22 @@ class AudioConcatenationTest extends FunctionalTestCase
public function testSimpleAudioFileConcatTest() public function testSimpleAudioFileConcatTest()
{ {
$ffmpeg = $this->getFFMpeg(); $ffmpeg = $this->getFFMpeg();
$files = [ $files = [
__DIR__ . '/../files/Jahzzar_-_05_-_Siesta.mp3', realpath(__DIR__ . '/../files/Jahzzar_-_05_-_Siesta.mp3'),
__DIR__ . '/../files/02_-_Favorite_Secrets.mp3', realpath(__DIR__ . '/../files/02_-_Favorite_Secrets.mp3'),
]; ];
$audio = $ffmpeg->open(reset($files)); $audio = $ffmpeg->open(reset($files));
$this->assertInstanceOf('FFMpeg\Media\Audio', $audio); $this->assertInstanceOf('FFMpeg\Media\Audio', $audio);
clearstatcache(); clearstatcache();
$filename = __DIR__ . '/output/concat-output.mp3'; $filename = __DIR__ . '/output/concat-output.mp3';
$audio->concat($files)->saveFromSameCodecs($filename, TRUE); $audio->concat($files)->saveFromSameCodecs($filename, TRUE);
$this->assertFileExists($filename); $this->assertFileExists($filename);
unlink($filename); unlink($filename);
} }
} }

View file

@ -39,9 +39,16 @@ abstract class VideoTestCase extends AudioTestCase
$this->assertEquals(2560, $format->getKiloBitrate()); $this->assertEquals(2560, $format->getKiloBitrate());
} }
public function testSetKiloBitrateBelowZero()
{
$this->expectException('FFMpeg\Exception\InvalidArgumentException');
$format = $this->getFormat();
$format->setKiloBitrate(-1);
}
public function testSetInvalidVideoCodec() public function testSetInvalidVideoCodec()
{ {
$this->expectException('\FFMpeg\Exception\InvalidArgumentException'); $this->expectException('FFMpeg\Exception\InvalidArgumentException');
$this->getFormat()->setVideoCodec('invalid-random-video-codec'); $this->getFormat()->setVideoCodec('invalid-random-video-codec');
} }

View file

@ -4,6 +4,7 @@ namespace Tests\FFMpeg\Unit\Media;
use FFMpeg\Exception\RuntimeException; use FFMpeg\Exception\RuntimeException;
use FFMpeg\Media\Video; use FFMpeg\Media\Video;
use FFMpeg\Format\Video\X264;
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
use FFMpeg\Format\VideoInterface; use FFMpeg\Format\VideoInterface;
@ -677,6 +678,35 @@ class VideoTest extends AbstractStreamableTestCase
} }
} }
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));
$driver->expects($this->exactly(1))
->method('command')
->with($this->isType('array'), false, $this->anything())
->will($this->returnCallback(function ($commands, $errors, $listeners) {
var_dump($commands);
$this->assertTrue(!in_array('-b:v', $commands));
}));
$video = new Video(__FILE__, $driver, $ffprobe);
$video->save($format, $outputPathfile);
}
public function getClassName() public function getClassName()
{ {
return 'FFMpeg\Media\Video'; return 'FFMpeg\Media\Video';