/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/AbstractMediaType.php |
@@ -0,0 +1,113 @@ |
<?php |
|
/* |
* This file is part of PHP-FFmpeg. |
* |
* (c) Alchemy <dev.team@alchemy.fr> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace FFMpeg\Media; |
|
use FFMpeg\Driver\FFMpegDriver; |
use FFMpeg\FFProbe; |
use FFMpeg\Filters\FiltersCollection; |
|
abstract class AbstractMediaType implements MediaTypeInterface |
{ |
/** @var string */ |
protected $pathfile; |
/** @var FFMpegDriver */ |
protected $driver; |
/** @var FFProbe */ |
protected $ffprobe; |
/** @var FiltersCollection */ |
protected $filters; |
|
public function __construct($pathfile, FFMpegDriver $driver, FFProbe $ffprobe) |
{ |
$this->pathfile = $pathfile; |
$this->driver = $driver; |
$this->ffprobe = $ffprobe; |
$this->filters = new FiltersCollection(); |
} |
|
/** |
* @return FFMpegDriver |
*/ |
public function getFFMpegDriver() |
{ |
return $this->driver; |
} |
|
/** |
* @param FFMpegDriver $driver |
* |
* @return MediaTypeInterface |
*/ |
public function setFFMpegDriver(FFMpegDriver $driver) |
{ |
$this->driver = $driver; |
|
return $this; |
} |
|
/** |
* @return FFProbe |
*/ |
public function getFFProbe() |
{ |
return $this->ffprobe; |
} |
|
/** |
* @param FFProbe $ffprobe |
* |
* @return MediaTypeInterface |
*/ |
public function setFFProbe(FFProbe $ffprobe) |
{ |
$this->ffprobe = $ffprobe; |
|
return $this; |
} |
|
/** |
* @return string |
*/ |
public function getPathfile() |
{ |
return $this->pathfile; |
} |
|
/** |
* @param FiltersCollection $filters |
* |
* @return MediaTypeInterface |
*/ |
public function setFiltersCollection(FiltersCollection $filters) |
{ |
$this->filters = $filters; |
|
return $this; |
} |
|
/** |
* @return MediaTypeInterface |
*/ |
public function getFiltersCollection() |
{ |
return $this->filters; |
} |
|
protected function cleanupTemporaryFile($filename) |
{ |
if (file_exists($filename) && is_writable($filename)) { |
unlink($filename); |
} |
|
return $this; |
} |
} |
/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/Audio.php |
@@ -0,0 +1,117 @@ |
<?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\Media; |
|
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; |
use FFMpeg\Filters\Audio\AudioFilters; |
use FFMpeg\Format\FormatInterface; |
use FFMpeg\Filters\Audio\SimpleFilter; |
use FFMpeg\Exception\RuntimeException; |
use FFMpeg\Exception\InvalidArgumentException; |
use FFMpeg\Filters\Audio\AudioFilterInterface; |
use FFMpeg\Filters\FilterInterface; |
use FFMpeg\Format\ProgressableInterface; |
|
class Audio extends AbstractStreamableMedia |
{ |
/** |
* {@inheritdoc} |
* |
* @return AudioFilters |
*/ |
public function filters() |
{ |
return new AudioFilters($this); |
} |
|
/** |
* {@inheritdoc} |
* |
* @return Audio |
*/ |
public function addFilter(FilterInterface $filter) |
{ |
if (!$filter instanceof AudioFilterInterface) { |
throw new InvalidArgumentException('Audio only accepts AudioFilterInterface filters'); |
} |
|
$this->filters->add($filter); |
|
return $this; |
} |
|
/** |
* Exports the audio in the desired format, applies registered filters. |
* |
* @param FormatInterface $format |
* @param string $outputPathfile |
* |
* @return Audio |
* |
* @throws RuntimeException |
*/ |
public function save(FormatInterface $format, $outputPathfile) |
{ |
$listeners = null; |
|
if ($format instanceof ProgressableInterface) { |
$listeners = $format->createProgressListener($this, $this->ffprobe, 1, 1); |
} |
|
$commands = array('-y', '-i', $this->pathfile); |
|
$filters = clone $this->filters; |
$filters->add(new SimpleFilter($format->getExtraParams(), 10)); |
|
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) { |
$filters->add(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads')))); |
} |
if (null !== $format->getAudioCodec()) { |
$filters->add(new SimpleFilter(array('-acodec', $format->getAudioCodec()))); |
} |
|
foreach ($filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this, $format)); |
} |
|
if (null !== $format->getAudioKiloBitrate()) { |
$commands[] = '-b:a'; |
$commands[] = $format->getAudioKiloBitrate() . 'k'; |
} |
if (null !== $format->getAudioChannels()) { |
$commands[] = '-ac'; |
$commands[] = $format->getAudioChannels(); |
} |
$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; |
} |
|
/** |
* Gets the waveform of the video. |
* |
* @param integer $width |
* @param integer $height |
* @return Waveform |
*/ |
public function waveform($width = 640, $height = 120) |
{ |
return new Waveform($this, $this->driver, $this->ffprobe, $width, $height); |
} |
} |
/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/Concat.php |
@@ -0,0 +1,264 @@ |
<?php |
|
/* |
* This file is part of PHP-FFmpeg. |
* |
* (c) Strime <contact@strime.io> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace FFMpeg\Media; |
|
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; |
use Alchemy\BinaryDriver\Exception\InvalidArgumentException; |
use FFMpeg\Filters\Concat\ConcatFilterInterface; |
use FFMpeg\Filters\Concat\ConcatFilters; |
use FFMpeg\Driver\FFMpegDriver; |
use FFMpeg\FFProbe; |
use FFMpeg\Filters\Audio\SimpleFilter; |
use FFMpeg\Exception\RuntimeException; |
use FFMpeg\Format\FormatInterface; |
use FFMpeg\Filters\FilterInterface; |
use FFMpeg\Format\ProgressableInterface; |
use FFMpeg\Format\AudioInterface; |
use FFMpeg\Format\VideoInterface; |
use Neutron\TemporaryFilesystem\Manager as FsManager; |
|
class Concat extends AbstractMediaType |
{ |
/** @var array */ |
private $sources; |
|
public function __construct($sources, FFMpegDriver $driver, FFProbe $ffprobe) |
{ |
parent::__construct($sources, $driver, $ffprobe); |
$this->sources = $sources; |
} |
|
/** |
* Returns the path to the sources. |
* |
* @return string |
*/ |
public function getSources() |
{ |
return $this->sources; |
} |
|
/** |
* {@inheritdoc} |
* |
* @return ConcatFilters |
*/ |
public function filters() |
{ |
return new ConcatFilters($this); |
} |
|
/** |
* {@inheritdoc} |
* |
* @return Concat |
*/ |
public function addFilter(ConcatFilterInterface $filter) |
{ |
$this->filters->add($filter); |
|
return $this; |
} |
|
/** |
* Saves the concatenated video in the given array, considering that the sources videos are all encoded with the same codec. |
* |
* @param array $outputPathfile |
* @param string $streamCopy |
* |
* @return Concat |
* |
* @throws RuntimeException |
*/ |
public function saveFromSameCodecs($outputPathfile, $streamCopy = TRUE) |
{ |
/** |
* @see https://ffmpeg.org/ffmpeg-formats.html#concat |
* @see https://trac.ffmpeg.org/wiki/Concatenate |
*/ |
|
// Create the file which will contain the list of videos |
$fs = FsManager::create(); |
$sourcesFile = $fs->createTemporaryFile('ffmpeg-concat'); |
|
// Set the content of this file |
$fileStream = @fopen($sourcesFile, 'w'); |
|
if($fileStream === false) { |
throw new ExecutionFailureException('Cannot open the temporary file.'); |
} |
|
$count_videos = 0; |
if(is_array($this->sources) && (count($this->sources) > 0)) { |
foreach ($this->sources as $videoPath) { |
$line = ""; |
|
if($count_videos != 0) |
$line .= "\n"; |
|
$line .= "file ".$videoPath; |
|
fwrite($fileStream, $line); |
|
$count_videos++; |
} |
} |
else { |
throw new InvalidArgumentException('The list of videos is not a valid array.'); |
} |
fclose($fileStream); |
|
|
$commands = array( |
'-f', 'concat', '-safe', '0', |
'-i', $sourcesFile |
); |
|
// Check if stream copy is activated |
if($streamCopy === TRUE) { |
$commands[] = '-c'; |
$commands[] = 'copy'; |
} |
|
// If not, we can apply filters |
else { |
foreach ($this->filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this)); |
} |
} |
|
// Set the output file in the command |
$commands = array_merge($commands, array($outputPathfile)); |
|
// Execute the command |
try { |
$this->driver->command($commands); |
} catch (ExecutionFailureException $e) { |
$this->cleanupTemporaryFile($outputPathfile); |
$this->cleanupTemporaryFile($sourcesFile); |
throw new RuntimeException('Unable to save concatenated video', $e->getCode(), $e); |
} |
|
$this->cleanupTemporaryFile($sourcesFile); |
return $this; |
} |
|
/** |
* Saves the concatenated video in the given filename, considering that the sources videos are all encoded with the same codec. |
* |
* @param string $outputPathfile |
* |
* @return Concat |
* |
* @throws RuntimeException |
*/ |
public function saveFromDifferentCodecs(FormatInterface $format, $outputPathfile) |
{ |
/** |
* @see https://ffmpeg.org/ffmpeg-formats.html#concat |
* @see https://trac.ffmpeg.org/wiki/Concatenate |
*/ |
|
// Check the validity of the parameter |
if(!is_array($this->sources) || (count($this->sources) == 0)) { |
throw new InvalidArgumentException('The list of videos is not a valid array.'); |
} |
|
// Create the commands variable |
$commands = array(); |
|
// Prepare the parameters |
$nbSources = 0; |
$files = array(); |
|
// For each source, check if this is a legit file |
// and prepare the parameters |
foreach ($this->sources as $videoPath) { |
$files[] = '-i'; |
$files[] = $videoPath; |
$nbSources++; |
} |
|
$commands = array_merge($commands, $files); |
|
// Set the parameters of the request |
$commands[] = '-filter_complex'; |
|
$complex_filter = ''; |
for($i=0; $i<$nbSources; $i++) { |
$complex_filter .= '['.$i.':v:0] ['.$i.':a:0] '; |
} |
$complex_filter .= 'concat=n='.$nbSources.':v=1:a=1 [v] [a]'; |
|
$commands[] = $complex_filter; |
$commands[] = '-map'; |
$commands[] = '[v]'; |
$commands[] = '-map'; |
$commands[] = '[a]'; |
|
// Prepare the filters |
$filters = clone $this->filters; |
$filters->add(new SimpleFilter($format->getExtraParams(), 10)); |
|
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) { |
$filters->add(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads')))); |
} |
if ($format instanceof VideoInterface) { |
if (null !== $format->getVideoCodec()) { |
$filters->add(new SimpleFilter(array('-vcodec', $format->getVideoCodec()))); |
} |
} |
if ($format instanceof AudioInterface) { |
if (null !== $format->getAudioCodec()) { |
$filters->add(new SimpleFilter(array('-acodec', $format->getAudioCodec()))); |
} |
} |
|
// Add the filters |
foreach ($this->filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this)); |
} |
|
if ($format instanceof AudioInterface) { |
if (null !== $format->getAudioKiloBitrate()) { |
$commands[] = '-b:a'; |
$commands[] = $format->getAudioKiloBitrate() . 'k'; |
} |
if (null !== $format->getAudioChannels()) { |
$commands[] = '-ac'; |
$commands[] = $format->getAudioChannels(); |
} |
} |
|
// If the user passed some additional parameters |
if ($format instanceof VideoInterface) { |
if (null !== $format->getAdditionalParameters()) { |
foreach ($format->getAdditionalParameters() as $additionalParameter) { |
$commands[] = $additionalParameter; |
} |
} |
} |
|
// Set the output file in the command |
$commands[] = $outputPathfile; |
|
$failure = null; |
|
try { |
$this->driver->command($commands); |
} catch (ExecutionFailureException $e) { |
throw new RuntimeException('Encoding failed', $e->getCode(), $e); |
} |
|
return $this; |
} |
} |
/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/Frame.php |
@@ -0,0 +1,133 @@ |
<?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\Media; |
|
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; |
use FFMpeg\Filters\Frame\FrameFilterInterface; |
use FFMpeg\Filters\Frame\FrameFilters; |
use FFMpeg\Driver\FFMpegDriver; |
use FFMpeg\FFProbe; |
use FFMpeg\Exception\RuntimeException; |
use FFMpeg\Coordinate\TimeCode; |
|
class Frame extends AbstractMediaType |
{ |
/** @var TimeCode */ |
private $timecode; |
/** @var Video */ |
private $video; |
|
public function __construct(Video $video, FFMpegDriver $driver, FFProbe $ffprobe, TimeCode $timecode) |
{ |
parent::__construct($video->getPathfile(), $driver, $ffprobe); |
$this->timecode = $timecode; |
$this->video = $video; |
} |
|
/** |
* Returns the video related to the frame. |
* |
* @return Video |
*/ |
public function getVideo() |
{ |
return $this->video; |
} |
|
/** |
* {@inheritdoc} |
* |
* @return FrameFilters |
*/ |
public function filters() |
{ |
return new FrameFilters($this); |
} |
|
/** |
* {@inheritdoc} |
* |
* @return Frame |
*/ |
public function addFilter(FrameFilterInterface $filter) |
{ |
$this->filters->add($filter); |
|
return $this; |
} |
|
/** |
* @return TimeCode |
*/ |
public function getTimeCode() |
{ |
return $this->timecode; |
} |
|
/** |
* Saves the frame in the given filename. |
* |
* Uses the `unaccurate method by default.` |
* |
* @param string $pathfile |
* @param Boolean $accurate |
* |
* @return Frame |
* |
* @throws RuntimeException |
*/ |
public function save($pathfile, $accurate = false, $returnBase64 = false) |
{ |
/** |
* might be optimized with http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg |
* @see http://ffmpeg.org/ffmpeg.html#Main-options |
*/ |
$outputFormat = $returnBase64 ? "image2pipe" : "image2"; |
if (!$accurate) { |
$commands = array( |
'-y', '-ss', (string) $this->timecode, |
'-i', $this->pathfile, |
'-vframes', '1', |
'-f', $outputFormat |
); |
} else { |
$commands = array( |
'-y', '-i', $this->pathfile, |
'-vframes', '1', '-ss', (string) $this->timecode, |
'-f', $outputFormat |
); |
} |
|
if($returnBase64) { |
array_push($commands, "-"); |
} |
|
foreach ($this->filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this)); |
} |
|
$commands = array_merge($commands, array($pathfile)); |
|
try { |
if(!$returnBase64) { |
$this->driver->command($commands); |
return $this; |
} |
else { |
return $this->driver->command($commands); |
} |
} catch (ExecutionFailureException $e) { |
$this->cleanupTemporaryFile($pathfile); |
throw new RuntimeException('Unable to save frame', $e->getCode(), $e); |
} |
} |
} |
/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/Gif.php |
@@ -0,0 +1,137 @@ |
<?php |
|
/* |
* This file is part of PHP-FFmpeg. |
* |
* (c) Strime <contact@strime.io> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace FFMpeg\Media; |
|
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; |
use FFMpeg\Filters\Gif\GifFilterInterface; |
use FFMpeg\Filters\Gif\GifFilters; |
use FFMpeg\Driver\FFMpegDriver; |
use FFMpeg\FFProbe; |
use FFMpeg\Exception\RuntimeException; |
use FFMpeg\Coordinate\TimeCode; |
use FFMpeg\Coordinate\Dimension; |
|
class Gif extends AbstractMediaType |
{ |
/** @var TimeCode */ |
private $timecode; |
/** @var Dimension */ |
private $dimension; |
/** @var integer */ |
private $duration; |
/** @var Video */ |
private $video; |
|
public function __construct(Video $video, FFMpegDriver $driver, FFProbe $ffprobe, TimeCode $timecode, Dimension $dimension, $duration = null) |
{ |
parent::__construct($video->getPathfile(), $driver, $ffprobe); |
$this->timecode = $timecode; |
$this->dimension = $dimension; |
$this->duration = $duration; |
$this->video = $video; |
} |
|
/** |
* Returns the video related to the gif. |
* |
* @return Video |
*/ |
public function getVideo() |
{ |
return $this->video; |
} |
|
/** |
* {@inheritdoc} |
* |
* @return GifFilters |
*/ |
public function filters() |
{ |
return new GifFilters($this); |
} |
|
/** |
* {@inheritdoc} |
* |
* @return Gif |
*/ |
public function addFilter(GifFilterInterface $filter) |
{ |
$this->filters->add($filter); |
|
return $this; |
} |
|
/** |
* @return TimeCode |
*/ |
public function getTimeCode() |
{ |
return $this->timecode; |
} |
|
/** |
* @return Dimension |
*/ |
public function getDimension() |
{ |
return $this->dimension; |
} |
|
/** |
* Saves the gif in the given filename. |
* |
* @param string $pathfile |
* |
* @return Gif |
* |
* @throws RuntimeException |
*/ |
public function save($pathfile) |
{ |
/** |
* @see http://ffmpeg.org/ffmpeg.html#Main-options |
*/ |
$commands = array( |
'-ss', (string)$this->timecode |
); |
|
if(null !== $this->duration) { |
$commands[] = '-t'; |
$commands[] = (string)$this->duration; |
} |
|
$commands[] = '-i'; |
$commands[] = $this->pathfile; |
$commands[] = '-vf'; |
$commands[] = 'scale=' . $this->dimension->getWidth() . ':-1'; |
$commands[] = '-gifflags'; |
$commands[] = '+transdiff'; |
$commands[] = '-y'; |
|
foreach ($this->filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this)); |
} |
|
$commands = array_merge($commands, array($pathfile)); |
|
try { |
$this->driver->command($commands); |
} catch (ExecutionFailureException $e) { |
$this->cleanupTemporaryFile($pathfile); |
throw new RuntimeException('Unable to save gif', $e->getCode(), $e); |
} |
|
return $this; |
} |
} |
/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/Video.php |
@@ -0,0 +1,268 @@ |
<?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\Media; |
|
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; |
use FFMpeg\Coordinate\TimeCode; |
use FFMpeg\Coordinate\Dimension; |
use FFMpeg\Filters\Audio\SimpleFilter; |
use FFMpeg\Exception\InvalidArgumentException; |
use FFMpeg\Exception\RuntimeException; |
use FFMpeg\Filters\Video\VideoFilters; |
use FFMpeg\Filters\FilterInterface; |
use FFMpeg\Format\FormatInterface; |
use FFMpeg\Format\ProgressableInterface; |
use FFMpeg\Format\AudioInterface; |
use FFMpeg\Format\VideoInterface; |
use Neutron\TemporaryFilesystem\Manager as FsManager; |
|
class Video extends Audio |
{ |
/** |
* {@inheritdoc} |
* |
* @return VideoFilters |
*/ |
public function filters() |
{ |
return new VideoFilters($this); |
} |
|
/** |
* {@inheritdoc} |
* |
* @return Video |
*/ |
public function addFilter(FilterInterface $filter) |
{ |
$this->filters->add($filter); |
|
return $this; |
} |
|
/** |
* Exports the video in the desired format, applies registered filters. |
* |
* @param FormatInterface $format |
* @param string $outputPathfile |
* |
* @return Video |
* |
* @throws RuntimeException |
*/ |
public function save(FormatInterface $format, $outputPathfile) |
{ |
$commands = array('-y', '-i', $this->pathfile); |
|
$filters = clone $this->filters; |
$filters->add(new SimpleFilter($format->getExtraParams(), 10)); |
|
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) { |
$filters->add(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads')))); |
} |
if ($format instanceof VideoInterface) { |
if (null !== $format->getVideoCodec()) { |
$filters->add(new SimpleFilter(array('-vcodec', $format->getVideoCodec()))); |
} |
} |
if ($format instanceof AudioInterface) { |
if (null !== $format->getAudioCodec()) { |
$filters->add(new SimpleFilter(array('-acodec', $format->getAudioCodec()))); |
} |
} |
|
foreach ($filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this, $format)); |
} |
|
if ($format instanceof VideoInterface) { |
$commands[] = '-b:v'; |
$commands[] = $format->getKiloBitrate() . 'k'; |
$commands[] = '-refs'; |
$commands[] = '6'; |
$commands[] = '-coder'; |
$commands[] = '1'; |
$commands[] = '-sc_threshold'; |
$commands[] = '40'; |
$commands[] = '-flags'; |
$commands[] = '+loop'; |
$commands[] = '-me_range'; |
$commands[] = '16'; |
$commands[] = '-subq'; |
$commands[] = '7'; |
$commands[] = '-i_qfactor'; |
$commands[] = '0.71'; |
$commands[] = '-qcomp'; |
$commands[] = '0.6'; |
$commands[] = '-qdiff'; |
$commands[] = '4'; |
$commands[] = '-trellis'; |
$commands[] = '1'; |
} |
|
if ($format instanceof AudioInterface) { |
if (null !== $format->getAudioKiloBitrate()) { |
$commands[] = '-b:a'; |
$commands[] = $format->getAudioKiloBitrate() . 'k'; |
} |
if (null !== $format->getAudioChannels()) { |
$commands[] = '-ac'; |
$commands[] = $format->getAudioChannels(); |
} |
} |
|
// If the user passed some additional parameters |
if ($format instanceof VideoInterface) { |
if (null !== $format->getAdditionalParameters()) { |
foreach ($format->getAdditionalParameters() as $additionalParameter) { |
$commands[] = $additionalParameter; |
} |
} |
} |
|
// Merge Filters into one command |
$videoFilterVars = $videoFilterProcesses = []; |
for($i=0;$i<count($commands);$i++) { |
$command = $commands[$i]; |
if ( $command == '-vf' ) { |
$commandSplits = explode(";", $commands[$i + 1]); |
if ( count($commandSplits) == 1 ) { |
$commandSplit = $commandSplits[0]; |
$command = trim($commandSplit); |
if ( preg_match("/^\[in\](.*?)\[out\]$/is", $command, $match) ) { |
$videoFilterProcesses[] = $match[1]; |
} else { |
$videoFilterProcesses[] = $command; |
} |
} else { |
foreach($commandSplits as $commandSplit) { |
$command = trim($commandSplit); |
if ( preg_match("/^\[[^\]]+\](.*?)\[[^\]]+\]$/is", $command, $match) ) { |
$videoFilterProcesses[] = $match[1]; |
} else { |
$videoFilterVars[] = $command; |
} |
} |
} |
unset($commands[$i]); |
unset($commands[$i + 1]); |
$i++; |
} |
} |
$videoFilterCommands = $videoFilterVars; |
$lastInput = 'in'; |
foreach($videoFilterProcesses as $i => $process) { |
$command = '[' . $lastInput .']'; |
$command .= $process; |
$lastInput = 'p' . $i; |
if ( $i == count($videoFilterProcesses) - 1 ) { |
$command .= '[out]'; |
} else { |
$command .= '[' . $lastInput . ']'; |
} |
|
$videoFilterCommands[] = $command; |
} |
$videoFilterCommand = implode(";", $videoFilterCommands); |
|
if ( $videoFilterCommand ) { |
$commands[] = '-vf'; |
$commands[] = $videoFilterCommand; |
} |
|
$fs = FsManager::create(); |
$fsId = uniqid('ffmpeg-passes'); |
$passPrefix = $fs->createTemporaryDirectory(0777, 50, $fsId) . '/' . uniqid('pass-'); |
$passes = array(); |
$totalPasses = $format->getPasses(); |
|
if (1 > $totalPasses) { |
throw new InvalidArgumentException('Pass number should be a positive value.'); |
} |
|
for ($i = 1; $i <= $totalPasses; $i++) { |
$pass = $commands; |
|
if ($totalPasses > 1) { |
$pass[] = '-pass'; |
$pass[] = $i; |
$pass[] = '-passlogfile'; |
$pass[] = $passPrefix; |
} |
|
$pass[] = $outputPathfile; |
|
$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; |
} |
|
/** |
* Gets the frame at timecode. |
* |
* @param TimeCode $at |
* @return Frame |
*/ |
public function frame(TimeCode $at) |
{ |
return new Frame($this, $this->driver, $this->ffprobe, $at); |
} |
|
/** |
* Extracts a gif from a sequence of the video. |
* |
* @param TimeCode $at |
* @param Dimension $dimension |
* @param integer $duration |
* @return Gif |
*/ |
public function gif(TimeCode $at, Dimension $dimension, $duration = null) |
{ |
return new Gif($this, $this->driver, $this->ffprobe, $at, $dimension, $duration); |
} |
|
/** |
* Concatenates a list of videos into one unique video. |
* |
* @param array $sources |
* @return Concat |
*/ |
public function concat($sources) |
{ |
return new Concat($sources, $this->driver, $this->ffprobe); |
} |
} |
/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/Waveform.php |
@@ -0,0 +1,104 @@ |
<?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\Media; |
|
use Alchemy\BinaryDriver\Exception\ExecutionFailureException; |
use FFMpeg\Filters\Waveform\WaveformFilterInterface; |
use FFMpeg\Filters\Waveform\WaveformFilters; |
use FFMpeg\Driver\FFMpegDriver; |
use FFMpeg\FFProbe; |
use FFMpeg\Exception\RuntimeException; |
|
class Waveform extends AbstractMediaType |
{ |
/** @var Video */ |
private $audio; |
private $width; |
private $height; |
|
public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height) |
{ |
parent::__construct($audio->getPathfile(), $driver, $ffprobe); |
$this->audio = $audio; |
$this->width = $width; |
$this->height = $height; |
} |
|
/** |
* Returns the audio related to the waveform. |
* |
* @return Audio |
*/ |
public function getAudio() |
{ |
return $this->audio; |
} |
|
/** |
* {@inheritdoc} |
* |
* @return WaveformFilters |
*/ |
public function filters() |
{ |
return new WaveformFilters($this); |
} |
|
/** |
* {@inheritdoc} |
* |
* @return Waveform |
*/ |
public function addFilter(WaveformFilterInterface $filter) |
{ |
$this->filters->add($filter); |
|
return $this; |
} |
|
/** |
* Saves the waveform in the given filename. |
* |
* @param string $pathfile |
* |
* @return Waveform |
* |
* @throws RuntimeException |
*/ |
public function save($pathfile) |
{ |
/** |
* might be optimized with http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg |
* @see http://ffmpeg.org/ffmpeg.html#Main-options |
*/ |
$commands = array( |
'-i', $this->pathfile, '-filter_complex', |
'showwavespic=s='.$this->width.'x'.$this->height, |
'-frames:v', '1' |
); |
|
foreach ($this->filters as $filter) { |
$commands = array_merge($commands, $filter->apply($this)); |
} |
|
$commands = array_merge($commands, array($pathfile)); |
|
try { |
$this->driver->command($commands); |
} catch (ExecutionFailureException $e) { |
$this->cleanupTemporaryFile($pathfile); |
throw new RuntimeException('Unable to save waveform', $e->getCode(), $e); |
} |
|
return $this; |
} |
} |