Merge pull request #16 from pulse00/pipe-patch-helpers
added support for retrieving progress information via helpers
This commit is contained in:
commit
aec70d9a76
10 changed files with 463 additions and 7 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,4 +2,5 @@
|
||||||
/vendor/
|
/vendor/
|
||||||
/docs/build
|
/docs/build
|
||||||
composer.phar
|
composer.phar
|
||||||
|
phpunit.xml
|
||||||
|
|
||||||
|
|
|
||||||
15
README.md
15
README.md
|
|
@ -27,6 +27,21 @@ $ffmpeg->open('Video.mpeg')
|
||||||
->close();
|
->close();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##Getting progress information
|
||||||
|
|
||||||
|
|
||||||
|
```php
|
||||||
|
$progressHelper = new FFMpeg\Helper\AudioProgressHelper(function($percent, $remaining, $rate) {
|
||||||
|
echo "Current progress: " . $percent "%\n";
|
||||||
|
echo "Remaining time: " . $remaining " seconds\n";
|
||||||
|
});
|
||||||
|
|
||||||
|
$ffmpeg->open('Audio.wav')
|
||||||
|
->attachHelper($progressHelper)
|
||||||
|
->encode(new Mp3(), 'file.mp3')
|
||||||
|
->close();
|
||||||
|
```
|
||||||
|
|
||||||
##Using with Silex Microframework
|
##Using with Silex Microframework
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,9 @@
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fabpot/php-cs-fixer": "master",
|
"fabpot/php-cs-fixer": "master",
|
||||||
"sami/sami": "dev-master",
|
"sami/sami": "dev-master",
|
||||||
"silex/silex": "dev-master"
|
"silex/silex": "dev-master",
|
||||||
|
"phpunit/phpunit": "3.7.*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-0": {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ use FFMpeg\Exception\LogicException;
|
||||||
use FFMpeg\Exception\RuntimeException;
|
use FFMpeg\Exception\RuntimeException;
|
||||||
use FFMpeg\Format\Audio;
|
use FFMpeg\Format\Audio;
|
||||||
use FFMpeg\Format\Video;
|
use FFMpeg\Format\Video;
|
||||||
|
use FFMpeg\Helper\HelperInterface;
|
||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
use Symfony\Component\Process\ProcessBuilder;
|
use Symfony\Component\Process\ProcessBuilder;
|
||||||
|
|
||||||
|
|
@ -35,6 +36,11 @@ class FFMpeg extends Binary
|
||||||
protected $prober;
|
protected $prober;
|
||||||
protected $threads = 1;
|
protected $threads = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var HelperInterface[]
|
||||||
|
*/
|
||||||
|
protected $helpers = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
|
@ -44,6 +50,24 @@ class FFMpeg extends Binary
|
||||||
parent::__destruct();
|
parent::__destruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param HelperInterface $helper
|
||||||
|
* @return \FFMpeg\FFMpeg
|
||||||
|
*/
|
||||||
|
public function attachHelper(HelperInterface $helper)
|
||||||
|
{
|
||||||
|
$this->helpers[] = $helper;
|
||||||
|
$helper->setProber($this->prober);
|
||||||
|
|
||||||
|
// ensure the helpers have the path to the file in case
|
||||||
|
// they need to probe for format information
|
||||||
|
if ($this->pathfile !== null) {
|
||||||
|
$helper->open($this->pathfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setThreads($threads)
|
public function setThreads($threads)
|
||||||
{
|
{
|
||||||
if ($threads > 64 || $threads < 1) {
|
if ($threads > 64 || $threads < 1) {
|
||||||
|
|
@ -76,9 +100,12 @@ class FFMpeg extends Binary
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->addInfo(sprintf('FFmpeg opens %s', $pathfile));
|
$this->logger->addInfo(sprintf('FFmpeg opens %s', $pathfile));
|
||||||
|
|
||||||
$this->pathfile = $pathfile;
|
$this->pathfile = $pathfile;
|
||||||
|
|
||||||
|
foreach ($this->helpers as $helper) {
|
||||||
|
$helper->open($pathfile);
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +162,7 @@ class FFMpeg extends Binary
|
||||||
$this->logger->addInfo(sprintf('FFmpeg executes command %s', $process->getCommandline()));
|
$this->logger->addInfo(sprintf('FFmpeg executes command %s', $process->getCommandline()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$process->run();
|
$process->run(array($this, 'transcodeCallback'));
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +245,7 @@ class FFMpeg extends Binary
|
||||||
$this->logger->addInfo(sprintf('FFmpeg executes command %s', $process->getCommandLine()));
|
$this->logger->addInfo(sprintf('FFmpeg executes command %s', $process->getCommandLine()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$process->run();
|
$process->run(array($this, 'transcodeCallback'));
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +371,7 @@ class FFMpeg extends Binary
|
||||||
$this->logger->addInfo(sprintf('FFmpeg executes command %s', $process->getCommandline()));
|
$this->logger->addInfo(sprintf('FFmpeg executes command %s', $process->getCommandline()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$process->run();
|
$process->run(array($this, 'transcodeCallback'));
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -365,6 +392,19 @@ class FFMpeg extends Binary
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main transcoding callback, delegates the content to the helpers.
|
||||||
|
*
|
||||||
|
* @param string $channel (stdio|stderr)
|
||||||
|
* @param string $content the current line of the ffmpeg output
|
||||||
|
*/
|
||||||
|
public function transcodeCallback($channel, $content)
|
||||||
|
{
|
||||||
|
foreach ($this->helpers as $helper) {
|
||||||
|
$helper->transcodeCallback($channel, $content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes unnecessary file
|
* Removes unnecessary file
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ use Symfony\Component\Process\ProcessBuilder;
|
||||||
class FFProbe extends Binary
|
class FFProbe extends Binary
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected $cachedFormats = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Probe the format of a given file
|
* Probe the format of a given file
|
||||||
*
|
*
|
||||||
|
|
@ -39,6 +41,10 @@ class FFProbe extends Binary
|
||||||
throw new InvalidArgumentException($pathfile);
|
throw new InvalidArgumentException($pathfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($this->cachedFormats[$pathfile])) {
|
||||||
|
return $this->cachedFormats[$pathfile];
|
||||||
|
}
|
||||||
|
|
||||||
$builder = ProcessBuilder::create(array(
|
$builder = ProcessBuilder::create(array(
|
||||||
$this->binary, $pathfile, '-show_format'
|
$this->binary, $pathfile, '-show_format'
|
||||||
));
|
));
|
||||||
|
|
@ -69,7 +75,7 @@ class FFProbe extends Binary
|
||||||
$ret[$key] = $value;
|
$ret[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return json_encode($ret);
|
return $this->cachedFormats[$pathfile] = json_encode($ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
29
src/FFMpeg/Helper/AudioProgressHelper.php
Normal file
29
src/FFMpeg/Helper/AudioProgressHelper.php
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of PHP-FFmpeg.
|
||||||
|
*
|
||||||
|
* (c) Alchemy <info@alchemy.fr>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FFMpeg\Helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses ffmpeg stderr progress information. An example:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* size= 3552kB time=00:03:47.29 bitrate= 128.0kbits/s
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Robert Gruendler <r.gruendler@gmail.com>
|
||||||
|
*/
|
||||||
|
class AudioProgressHelper extends ProgressHelper
|
||||||
|
{
|
||||||
|
public function getPattern()
|
||||||
|
{
|
||||||
|
return '/size=(.*?) time=(.*?) /';
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/FFMpeg/Helper/HelperInterface.php
Normal file
42
src/FFMpeg/Helper/HelperInterface.php
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of PHP-FFmpeg.
|
||||||
|
*
|
||||||
|
* (c) Alchemy <info@alchemy.fr>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FFMpeg\Helper;
|
||||||
|
|
||||||
|
use FFMpeg\FFProbe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert Gruendler <r.gruendler@gmail.com>
|
||||||
|
*/
|
||||||
|
interface HelperInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The callback from the ffmpeg process.
|
||||||
|
*
|
||||||
|
* @param string $channel (stdio|stderr)
|
||||||
|
* @param string $content the current line of the ffmpeg output
|
||||||
|
*/
|
||||||
|
function transcodeCallback($channel, $content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The helper has access to a prober instance if available.
|
||||||
|
*
|
||||||
|
* @param FFProbe $prober
|
||||||
|
*/
|
||||||
|
function setProber(FFProbe $prober);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the input file is opened.
|
||||||
|
*
|
||||||
|
* @param string $pathfile
|
||||||
|
*/
|
||||||
|
function open($pathfile);
|
||||||
|
}
|
||||||
223
src/FFMpeg/Helper/ProgressHelper.php
Normal file
223
src/FFMpeg/Helper/ProgressHelper.php
Normal file
|
|
@ -0,0 +1,223 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of PHP-FFmpeg.
|
||||||
|
*
|
||||||
|
* (c) Alchemy <info@alchemy.fr>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FFMpeg\Helper;
|
||||||
|
|
||||||
|
use FFMpeg\FFProbe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert Gruendler <r.gruendler@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class ProgressHelper implements HelperInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $duration = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transcoding rate in kb/s
|
||||||
|
*
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $rate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $totalSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $currentSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $currentTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var double
|
||||||
|
*/
|
||||||
|
protected $lastOutput = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Percentage of transcoding progress (0 - 100)
|
||||||
|
*
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $percent = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time remaining (seconds)
|
||||||
|
*
|
||||||
|
* @var number
|
||||||
|
*/
|
||||||
|
protected $remaining = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FFProbe
|
||||||
|
*/
|
||||||
|
protected $prober;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Closure|string|array
|
||||||
|
*/
|
||||||
|
protected $callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $callback
|
||||||
|
*/
|
||||||
|
public function __construct($callback)
|
||||||
|
{
|
||||||
|
$this->callback = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to ease testing.
|
||||||
|
*
|
||||||
|
* @param number $duration
|
||||||
|
*/
|
||||||
|
public function setDuration($duration)
|
||||||
|
{
|
||||||
|
$this->duration = $duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function transcodeCallback($channel, $content)
|
||||||
|
{
|
||||||
|
$progress = $this->parseProgress($content);
|
||||||
|
|
||||||
|
if (is_array($progress)) {
|
||||||
|
call_user_func_array($this->callback, $progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setProber(FFProbe $prober)
|
||||||
|
{
|
||||||
|
$this->prober = $prober;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function open($pathfile)
|
||||||
|
{
|
||||||
|
if ($this->prober === null) {
|
||||||
|
throw new \RuntimeException('Unable to report audio progress without a prober');
|
||||||
|
}
|
||||||
|
|
||||||
|
$format = json_decode($this->prober->probeFormat($pathfile), true);
|
||||||
|
|
||||||
|
if ($format === null || count($format) === 0 || isset($format['size']) === false) {
|
||||||
|
throw new \RuntimeException('Unable to probe format for ' . $pathfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->format = $format;
|
||||||
|
$this->totalSize = $format['size'] / 1024;
|
||||||
|
$this->duration = $format['duration'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $progress A ffmpeg stderr progress output
|
||||||
|
* @return array the progressinfo array or null if there's no progress available yet.
|
||||||
|
*/
|
||||||
|
public function parseProgress($progress)
|
||||||
|
{
|
||||||
|
$matches = array();
|
||||||
|
|
||||||
|
if (preg_match($this->getPattern(), $progress, $matches) !== 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentDuration = $this->convertDuration($matches[2]);
|
||||||
|
$currentTime = $this->microtimeFloat();
|
||||||
|
$currentSize = trim(str_replace('kb', '', strtolower(($matches[1]))));
|
||||||
|
$percent = $currentDuration/ $this->duration;
|
||||||
|
|
||||||
|
if ($this->lastOutput !== null) {
|
||||||
|
$delta = $currentTime - $this->lastOutput;
|
||||||
|
$deltaSize = $currentSize - $this->currentSize;
|
||||||
|
$rate = $deltaSize * $delta;
|
||||||
|
$totalDuration = $this->totalSize / $rate;
|
||||||
|
$this->remaining = floor($totalDuration - ($totalDuration * $percent));
|
||||||
|
$this->rate = floor($rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->percent = floor($percent * 100);
|
||||||
|
$this->lastOutput = $currentTime;
|
||||||
|
$this->currentSize = (int) $currentSize;
|
||||||
|
$this->currentTime = $currentDuration;
|
||||||
|
|
||||||
|
return $this->getProgressInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param string $rawDuration in the format 00:00:00.00
|
||||||
|
* @return number
|
||||||
|
*/
|
||||||
|
protected function convertDuration($rawDuration)
|
||||||
|
{
|
||||||
|
$ar = array_reverse(explode(":", $rawDuration));
|
||||||
|
$duration = floatval($ar[0]);
|
||||||
|
if (!empty($ar[1])) {
|
||||||
|
$duration += intval($ar[1]) * 60;
|
||||||
|
}
|
||||||
|
if (!empty($ar[2])) {
|
||||||
|
$duration += intval($ar[2]) * 60 * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getProgressInfo()
|
||||||
|
{
|
||||||
|
if ($this->remaining === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'percent' => $this->percent,
|
||||||
|
'remaining' => $this->remaining,
|
||||||
|
'rate' => $this->rate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return number
|
||||||
|
*/
|
||||||
|
protected function microtimeFloat()
|
||||||
|
{
|
||||||
|
list($usec, $sec) = explode(" ", microtime());
|
||||||
|
return ((float)$usec + (float)$sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the regex pattern to match a ffmpeg stderr status line
|
||||||
|
*/
|
||||||
|
abstract function getPattern();
|
||||||
|
|
||||||
|
}
|
||||||
29
src/FFMpeg/Helper/VideoProgressHelper.php
Normal file
29
src/FFMpeg/Helper/VideoProgressHelper.php
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of PHP-FFmpeg.
|
||||||
|
*
|
||||||
|
* (c) Alchemy <info@alchemy.fr>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FFMpeg\Helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses ffmpeg stderr progress information for video files. An example:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* frame= 171 fps=0.0 q=10.0 size= 18kB time=00:00:05.72 bitrate= 26.4kbits/s dup=8 drop=0
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Robert Gruendler <r.gruendler@gmail.com>
|
||||||
|
*/
|
||||||
|
class VideoProgressHelper extends ProgressHelper
|
||||||
|
{
|
||||||
|
public function getPattern()
|
||||||
|
{
|
||||||
|
return '/size=(.*?) time=(.*?) /';
|
||||||
|
}
|
||||||
|
}
|
||||||
70
tests/src/FFMpeg/Progress/ProgressTest.php
Normal file
70
tests/src/FFMpeg/Progress/ProgressTest.php
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
use FFMpeg\Helper\AudioProgressHelper;
|
||||||
|
use FFMpeg\FFMpegTest;
|
||||||
|
use FFMpeg\Format\Audio\Mp3;
|
||||||
|
use FFMpeg\Helper\VideoProgressHelper;
|
||||||
|
|
||||||
|
class ProgressTest extends FFMpegTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers FFMpeg\Helper\ProgressHelper::parseProgress
|
||||||
|
* @covers FFMpeg\Helper\ProgressHelper::convertDuration
|
||||||
|
* @covers FFMpeg\Helper\ProgressHelper::getProgressInfo
|
||||||
|
* @covers FFMpeg\Helper\ProgressHelper::microtimeFloat
|
||||||
|
* @covers FFMpeg\Helper\AudioProgressHelper::getPattern
|
||||||
|
*/
|
||||||
|
public function testProgressHelper()
|
||||||
|
{
|
||||||
|
$progressInfo = array();
|
||||||
|
|
||||||
|
$audioProgress = new AudioProgressHelper(function($percent, $remaining, $rate) use ($progressInfo ) {
|
||||||
|
$progressInfo[] = $percent;
|
||||||
|
});
|
||||||
|
|
||||||
|
$dest = __DIR__ . '/../../../files/encode_test.mp3';
|
||||||
|
|
||||||
|
$this->object->open(__DIR__ . '/../../../files/Audio.mp3');
|
||||||
|
$this->object->attachHelper($audioProgress);
|
||||||
|
$this->object->encode(new Mp3(), $dest);
|
||||||
|
|
||||||
|
$this->assertGreaterThanOrEqual(3, $progressInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers FFMpeg\Helper\AudioProgressHelper::getPattern
|
||||||
|
*/
|
||||||
|
public function testAudioProgressHelper()
|
||||||
|
{
|
||||||
|
$audioProgress = new AudioProgressHelper(function($percent, $remaining, $rate) { });
|
||||||
|
$audioProgress->setDuration(500);
|
||||||
|
|
||||||
|
$line = "size= 712kB time=00:00:45.50 bitrate= 128.1kbits/s";
|
||||||
|
$audioProgress->parseProgress($line);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
$line = "size= 4712kB time=00:01:45.50 bitrate= 128.1kbits/s";
|
||||||
|
$progress = $audioProgress->parseProgress($line);
|
||||||
|
|
||||||
|
$this->assertEquals('21.0', $progress['percent']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers FFMpeg\Helper\VideoProgressHelper::getPattern
|
||||||
|
*/
|
||||||
|
public function testVideoProgress()
|
||||||
|
{
|
||||||
|
$videoProgress = new VideoProgressHelper(function($percent, $remaining, $rate) {});
|
||||||
|
$videoProgress->setDuration(500);
|
||||||
|
|
||||||
|
$line = "frame= 206 fps=202 q=10.0 size= 571kB time=00:00:07.12 bitrate= 656.8kbits/s dup=9 drop=0";
|
||||||
|
$videoProgress->parseProgress($line);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
$line = "frame= 854 fps=113 q=20.0 size= 4430kB time=00:00:33.04 bitrate=1098.5kbits/s dup=36 drop=0";
|
||||||
|
$progress = $videoProgress->parseProgress($line);
|
||||||
|
|
||||||
|
$this->assertEquals('6.0', $progress['percent']);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue