From 5a889aa5f25892db4f44f900bfda596509317250 Mon Sep 17 00:00:00 2001 From: jens1o Date: Sun, 5 Nov 2017 17:35:41 +0100 Subject: [PATCH 1/3] Added `buildCommand` and `getFinalCommand` to Audio class #403 --- src/FFMpeg/Media/Audio.php | 50 ++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/FFMpeg/Media/Audio.php b/src/FFMpeg/Media/Audio.php index 19f3478..11818d3 100644 --- a/src/FFMpeg/Media/Audio.php +++ b/src/FFMpeg/Media/Audio.php @@ -52,14 +52,12 @@ class Audio extends AbstractStreamableMedia /** * Exports the audio in the desired format, applies registered filters. * - * @param FormatInterface $format - * @param string $outputPathfile - * + * @param FormatInterface $format + * @param string $outputPathfile * @return Audio - * * @throws RuntimeException */ - public function save(FormatInterface $format, $outputPathfile) + public function save(FormatInterface $format, string $outputPathfile) { $listeners = null; @@ -67,6 +65,39 @@ class Audio extends AbstractStreamableMedia $listeners = $format->createProgressListener($this, $this->ffprobe, 1, 1); } + $commands = $this->buildCommand($format, $outputPathfile); + + try { + $this->driver->command($commands, false, $listeners); + } catch (ExecutionFailureException $e) { + $this->cleanupTemporaryFile($outputPathfile); + throw new RuntimeException('Encoding failed', $e->getCode(), $e); + } + + return $this; + } + + /** + * Returns the final command as a string, useful for debugging purposes. + * + * @param FormatInterface $format + * @param string $outputPathfile + * @return string + * @since 0.11.0 + */ + public function getFinalCommand(FormatInterface $format, string $outputPathfile) { + return implode(' ', $this->buildCommand($format, $outputPathfile)); + } + + /** + * Builds the command which will be executed with the provided format + * + * @param FormatInterface $format + * @param string $outputPathfile + * @return string[] An array which are the components of the command + * @since 0.11.0 + */ + protected function buildCommand(FormatInterface $format, string $outputPathfile) { $commands = array('-y', '-i', $this->pathfile); $filters = clone $this->filters; @@ -93,14 +124,7 @@ class Audio extends AbstractStreamableMedia } $commands[] = $outputPathfile; - try { - $this->driver->command($commands, false, $listeners); - } catch (ExecutionFailureException $e) { - $this->cleanupTemporaryFile($outputPathfile); - throw new RuntimeException('Encoding failed', $e->getCode(), $e); - } - - return $this; + return $commands; } /** From c43632faa8f48884fbc4864971454e279e6e39c5 Mon Sep 17 00:00:00 2001 From: jens1o Date: Sun, 5 Nov 2017 18:26:04 +0100 Subject: [PATCH 2/3] Add `Video#getFinalCommand` and some refactor --- src/FFMpeg/Media/Video.php | 131 ++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 47 deletions(-) diff --git a/src/FFMpeg/Media/Video.php b/src/FFMpeg/Media/Video.php index 264126a..d000d2c 100644 --- a/src/FFMpeg/Media/Video.php +++ b/src/FFMpeg/Media/Video.php @@ -28,8 +28,19 @@ use Neutron\TemporaryFilesystem\Manager as FsManager; class Video extends Audio { /** - * {@inheritdoc} - * + * FileSystem Manager instance + * @var Manager + */ + protected $fs; + + /** + * FileSystem Manager ID + * @var int + */ + protected $fsId; + + /** + * @inheritDoc * @return VideoFilters */ public function filters() @@ -38,8 +49,7 @@ class Video extends Audio } /** - * {@inheritdoc} - * + * @inheritDoc * @return Video */ public function addFilter(FilterInterface $filter) @@ -52,15 +62,66 @@ class Video extends Audio /** * Exports the video in the desired format, applies registered filters. * - * @param FormatInterface $format - * @param string $outputPathfile - * + * @param FormatInterface $format + * @param string $outputPathfile * @return Video - * * @throws RuntimeException */ - public function save(FormatInterface $format, $outputPathfile) + public function save(FormatInterface $format, string $outputPathfile) { + $passes = $this->buildCommand($format, $outputPathfile); + + $failure = null; + $totalPasses = $format->getPasses(); + + foreach ($passes as $pass => $passCommands) { + try { + /** add listeners here */ + $listeners = null; + + if ($format instanceof ProgressableInterface) { + $listeners = $format->createProgressListener($this, $this->ffprobe, $pass + 1, $totalPasses); + } + + $this->driver->command($passCommands, false, $listeners); + } catch (ExecutionFailureException $e) { + $failure = $e; + break; + } + } + + $this->fs->clean($this->fsId); + + if (null !== $failure) { + throw new RuntimeException('Encoding failed', $failure->getCode(), $failure); + } + + return $this; + } + + /** + * NOTE: This method is different to the Audio's one, because Video is using passes. + * @inheritDoc + */ + public function getFinalCommand(FormatInterface $format, string $outputPathfile) { + $finalCommands = array(); + + foreach($this->buildCommand($format, $outputPathfile) as $pass => $passCommands) { + $finalCommands[] = implode(' ', $passCommands); + } + + $this->fs->clean($this->fsId); + + return $finalCommands; + } + + /** + * **NOTE:** This creates passes instead of a single command! + * + * @inheritDoc + * @return string[][] + */ + protected function buildCommand(FormatInterface $format, string $outputPathfile) { $commands = array('-y', '-i', $this->pathfile); $filters = clone $this->filters; @@ -141,7 +202,7 @@ class Video extends Audio if ( preg_match("/^\[in\](.*?)\[out\]$/is", $command, $match) ) { $videoFilterProcesses[] = $match[1]; } else { - $videoFilterProcesses[] = $command; + $videoFilterProcesses[] = $command; } } else { foreach($commandSplits as $commandSplit) { @@ -150,7 +211,7 @@ class Video extends Audio $videoFilterProcesses[] = $match[1]; } else { $videoFilterVars[] = $command; - } + } } } unset($commands[$i]); @@ -164,32 +225,32 @@ class Video extends Audio $command = '[' . $lastInput .']'; $command .= $process; $lastInput = 'p' . $i; - if ( $i == count($videoFilterProcesses) - 1 ) { + if($i === (count($videoFilterProcesses) - 1)) { $command .= '[out]'; } else { $command .= '[' . $lastInput . ']'; } - + $videoFilterCommands[] = $command; } - $videoFilterCommand = implode(";", $videoFilterCommands); - - if ( $videoFilterCommand ) { + $videoFilterCommand = implode(';', $videoFilterCommands); + + if($videoFilterCommand) { $commands[] = '-vf'; $commands[] = $videoFilterCommand; } - - $fs = FsManager::create(); - $fsId = uniqid('ffmpeg-passes'); - $passPrefix = $fs->createTemporaryDirectory(0777, 50, $fsId) . '/' . uniqid('pass-'); + + $this->fs = FsManager::create(); + $this->fsId = uniqid('ffmpeg-passes'); + $passPrefix = $this->fs->createTemporaryDirectory(0777, 50, $this->fsId) . '/' . uniqid('pass-'); $passes = array(); $totalPasses = $format->getPasses(); - if (1 > $totalPasses) { + if(!$totalPasses) { throw new InvalidArgumentException('Pass number should be a positive value.'); } - for ($i = 1; $i <= $totalPasses; $i++) { + for($i = 1; $i <= $totalPasses; $i++) { $pass = $commands; if ($totalPasses > 1) { @@ -204,31 +265,7 @@ class Video extends Audio $passes[] = $pass; } - $failure = null; - - foreach ($passes as $pass => $passCommands) { - try { - /** add listeners here */ - $listeners = null; - - if ($format instanceof ProgressableInterface) { - $listeners = $format->createProgressListener($this, $this->ffprobe, $pass + 1, $totalPasses); - } - - $this->driver->command($passCommands, false, $listeners); - } catch (ExecutionFailureException $e) { - $failure = $e; - break; - } - } - - $fs->clean($fsId); - - if (null !== $failure) { - throw new RuntimeException('Encoding failed', $failure->getCode(), $failure); - } - - return $this; + return $passes; } /** From c393e31803a314f7e12153ed3d49a86eb9f07a10 Mon Sep 17 00:00:00 2001 From: jens1o Date: Sun, 5 Nov 2017 18:45:35 +0100 Subject: [PATCH 3/3] old php versions <.< --- src/FFMpeg/Media/Audio.php | 6 +++--- src/FFMpeg/Media/Video.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/FFMpeg/Media/Audio.php b/src/FFMpeg/Media/Audio.php index 11818d3..29d2c89 100644 --- a/src/FFMpeg/Media/Audio.php +++ b/src/FFMpeg/Media/Audio.php @@ -57,7 +57,7 @@ class Audio extends AbstractStreamableMedia * @return Audio * @throws RuntimeException */ - public function save(FormatInterface $format, string $outputPathfile) + public function save(FormatInterface $format, $outputPathfile) { $listeners = null; @@ -85,7 +85,7 @@ class Audio extends AbstractStreamableMedia * @return string * @since 0.11.0 */ - public function getFinalCommand(FormatInterface $format, string $outputPathfile) { + public function getFinalCommand(FormatInterface $format, $outputPathfile) { return implode(' ', $this->buildCommand($format, $outputPathfile)); } @@ -97,7 +97,7 @@ class Audio extends AbstractStreamableMedia * @return string[] An array which are the components of the command * @since 0.11.0 */ - protected function buildCommand(FormatInterface $format, string $outputPathfile) { + protected function buildCommand(FormatInterface $format, $outputPathfile) { $commands = array('-y', '-i', $this->pathfile); $filters = clone $this->filters; diff --git a/src/FFMpeg/Media/Video.php b/src/FFMpeg/Media/Video.php index d000d2c..3d469ec 100644 --- a/src/FFMpeg/Media/Video.php +++ b/src/FFMpeg/Media/Video.php @@ -67,7 +67,7 @@ class Video extends Audio * @return Video * @throws RuntimeException */ - public function save(FormatInterface $format, string $outputPathfile) + public function save(FormatInterface $format, $outputPathfile) { $passes = $this->buildCommand($format, $outputPathfile); @@ -103,7 +103,7 @@ class Video extends Audio * NOTE: This method is different to the Audio's one, because Video is using passes. * @inheritDoc */ - public function getFinalCommand(FormatInterface $format, string $outputPathfile) { + public function getFinalCommand(FormatInterface $format, $outputPathfile) { $finalCommands = array(); foreach($this->buildCommand($format, $outputPathfile) as $pass => $passCommands) { @@ -121,7 +121,7 @@ class Video extends Audio * @inheritDoc * @return string[][] */ - protected function buildCommand(FormatInterface $format, string $outputPathfile) { + protected function buildCommand(FormatInterface $format, $outputPathfile) { $commands = array('-y', '-i', $this->pathfile); $filters = clone $this->filters;