Version 0.3
This commit is contained in:
parent
0d69145ec3
commit
ad3a5af623
130 changed files with 7283 additions and 2627 deletions
29
src/FFMpeg/Filters/Audio/AudioFilterInterface.php
Normal file
29
src/FFMpeg/Filters/Audio/AudioFilterInterface.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?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\Filters\Audio;
|
||||
|
||||
use FFMpeg\Filters\FilterInterface;
|
||||
use FFMpeg\Format\AudioInterface;
|
||||
use FFMpeg\Media\Audio;
|
||||
|
||||
interface AudioFilterInterface extends FilterInterface
|
||||
{
|
||||
/**
|
||||
* Applies the filter on the the Audio media given an format.
|
||||
*
|
||||
* @param Audio $audio
|
||||
* @param AudioInterface $format
|
||||
*
|
||||
* @return array An array of arguments
|
||||
*/
|
||||
public function apply(Audio $audio, AudioInterface $format);
|
||||
}
|
||||
30
src/FFMpeg/Filters/Audio/AudioFilters.php
Normal file
30
src/FFMpeg/Filters/Audio/AudioFilters.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace FFMpeg\Filters\Audio;
|
||||
|
||||
use FFMpeg\Media\Audio;
|
||||
use FFMpeg\Filters\Audio\AudioResamplableFilter;
|
||||
|
||||
class AudioFilters
|
||||
{
|
||||
private $audio;
|
||||
|
||||
public function __construct(Audio $audio)
|
||||
{
|
||||
$this->audio = $audio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resamples the audio file.
|
||||
*
|
||||
* @param Integer $rate
|
||||
*
|
||||
* @return AudioFilters
|
||||
*/
|
||||
public function resample($rate)
|
||||
{
|
||||
$this->audio->addFilter(new AudioResamplableFilter($rate));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
43
src/FFMpeg/Filters/Audio/AudioResamplableFilter.php
Normal file
43
src/FFMpeg/Filters/Audio/AudioResamplableFilter.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?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\Filters\Audio;
|
||||
|
||||
use FFMpeg\Format\AudioInterface;
|
||||
use FFMpeg\Media\Audio;
|
||||
|
||||
class AudioResamplableFilter implements AudioFilterInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $rate;
|
||||
|
||||
public function __construct($rate)
|
||||
{
|
||||
$this->rate = $rate;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Integer
|
||||
*/
|
||||
public function getRate()
|
||||
{
|
||||
return $this->rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply(Audio $audio, AudioInterface $format)
|
||||
{
|
||||
return array('-ac', 2, '-ar', $this->rate);
|
||||
}
|
||||
}
|
||||
16
src/FFMpeg/Filters/FilterInterface.php
Normal file
16
src/FFMpeg/Filters/FilterInterface.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?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\Filters;
|
||||
|
||||
interface FilterInterface
|
||||
{
|
||||
}
|
||||
45
src/FFMpeg/Filters/FiltersCollection.php
Normal file
45
src/FFMpeg/Filters/FiltersCollection.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?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\Filters;
|
||||
|
||||
class FiltersCollection implements \Countable, \IteratorAggregate
|
||||
{
|
||||
private $filters = array();
|
||||
|
||||
/**
|
||||
* @param FilterInterface $filter
|
||||
*
|
||||
* @return FiltersCollection
|
||||
*/
|
||||
public function add(FilterInterface $filter)
|
||||
{
|
||||
$this->filters[] = $filter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->filters);
|
||||
}
|
||||
}
|
||||
21
src/FFMpeg/Filters/Frame/FrameFilterInterface.php
Normal file
21
src/FFMpeg/Filters/Frame/FrameFilterInterface.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?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\Filters\Frame;
|
||||
|
||||
use FFMpeg\Filters\FilterInterface;
|
||||
use FFMpeg\Media\Frame;
|
||||
use FFMpeg\Format\FrameInterface;
|
||||
|
||||
interface FrameFilterInterface extends FilterInterface
|
||||
{
|
||||
public function apply(Frame $frame, FrameInterface $format);
|
||||
}
|
||||
24
src/FFMpeg/Filters/Frame/FrameFilters.php
Normal file
24
src/FFMpeg/Filters/Frame/FrameFilters.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?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\Filters\Frame;
|
||||
|
||||
use FFMpeg\Media\Frame;
|
||||
|
||||
class FrameFilters
|
||||
{
|
||||
private $frame;
|
||||
|
||||
public function __construct(Frame $frame)
|
||||
{
|
||||
$this->frame = $frame;
|
||||
}
|
||||
}
|
||||
126
src/FFMpeg/Filters/Video/ResizeFilter.php
Normal file
126
src/FFMpeg/Filters/Video/ResizeFilter.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?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\Filters\Video;
|
||||
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\Media\Video;
|
||||
use FFMpeg\Format\VideoInterface;
|
||||
|
||||
class ResizeFilter implements VideoFilterInterface
|
||||
{
|
||||
const RESIZEMODE_FIT = 'fit';
|
||||
const RESIZEMODE_INSET = 'inset';
|
||||
const RESIZEMODE_SCALE_WIDTH = 'width';
|
||||
const RESIZEMODE_SCALE_HEIGHT = 'height';
|
||||
|
||||
/** @var Dimension */
|
||||
private $dimension;
|
||||
/** @var string */
|
||||
private $mode;
|
||||
/** @var Boolean */
|
||||
private $forceStandards;
|
||||
|
||||
public function __construct(Dimension $dimension, $mode = self::RESIZEMODE_FIT, $forceStandards = true)
|
||||
{
|
||||
$this->dimension = $dimension;
|
||||
$this->mode = $mode;
|
||||
$this->forceStandards = $forceStandards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Dimension
|
||||
*/
|
||||
public function getDimension()
|
||||
{
|
||||
return $this->dimension;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMode()
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean
|
||||
*/
|
||||
public function areStandardsForced()
|
||||
{
|
||||
return $this->forceStandards;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply(Video $video, VideoInterface $format)
|
||||
{
|
||||
$originalWidth = $originalHeight = null;
|
||||
|
||||
foreach ($video->getStreams() as $stream) {
|
||||
if ($stream->isVideo()) {
|
||||
if ($stream->has('width')) {
|
||||
$originalWidth = $stream->get('width');
|
||||
}
|
||||
if ($stream->has('height')) {
|
||||
$originalHeight = $stream->get('height');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$commands = array();
|
||||
|
||||
if ($originalHeight !== null && $originalWidth !== null) {
|
||||
$dimensions = $this->getComputedDimensions(new Dimension($originalWidth, $originalHeight), $format->getModulus());
|
||||
|
||||
$commands[] = '-s';
|
||||
$commands[] = $dimensions->getWidth() . 'x' . $dimensions->getHeight();
|
||||
}
|
||||
|
||||
return $commands;
|
||||
}
|
||||
|
||||
private function getComputedDimensions(Dimension $dimension, $modulus)
|
||||
{
|
||||
$originalRatio = $dimension->getRatio($this->forceStandards);
|
||||
|
||||
switch ($this->mode) {
|
||||
case self::RESIZEMODE_SCALE_WIDTH:
|
||||
$height = $this->dimension->getHeight();
|
||||
$width = $originalRatio->calculateWidth($height, $modulus);
|
||||
break;
|
||||
case self::RESIZEMODE_SCALE_HEIGHT:
|
||||
$width = $this->dimension->getWidth();
|
||||
$height = $originalRatio->calculateHeight($width, $modulus);
|
||||
break;
|
||||
case self::RESIZEMODE_INSET:
|
||||
$targetRatio = $this->dimension->getRatio($this->forceStandards);
|
||||
|
||||
if ($targetRatio->getValue() > $originalRatio->getValue()) {
|
||||
$height = $this->dimension->getHeight();
|
||||
$width = $originalRatio->calculateWidth($height, $modulus);
|
||||
} else {
|
||||
$width = $this->dimension->getWidth();
|
||||
$height = $originalRatio->calculateHeight($width, $modulus);
|
||||
}
|
||||
break;
|
||||
case self::RESIZEMODE_FIT:
|
||||
default:
|
||||
$width = $this->dimension->getWidth();
|
||||
$height = $this->dimension->getHeight();
|
||||
break;
|
||||
}
|
||||
|
||||
return new Dimension($width, $height);
|
||||
}
|
||||
}
|
||||
49
src/FFMpeg/Filters/Video/SynchronizeFilter.php
Normal file
49
src/FFMpeg/Filters/Video/SynchronizeFilter.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?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\Filters\Video;
|
||||
|
||||
use FFMpeg\Format\VideoInterface;
|
||||
use FFMpeg\Media\Video;
|
||||
|
||||
class SynchronizeFilter implements VideoFilterInterface
|
||||
{
|
||||
public function apply(Video $video, VideoInterface $format)
|
||||
{
|
||||
$streams = $video->getStreams();
|
||||
|
||||
if (null === $videoStream = $streams->videos()->first()) {
|
||||
return array();
|
||||
}
|
||||
if (!$videoStream->has('start_time')) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'-itsoffset',
|
||||
$videoStream->get('start_time'),
|
||||
'-i',
|
||||
$video->getPathfile(),
|
||||
);
|
||||
|
||||
foreach ($streams as $stream) {
|
||||
if ($videoStream === $stream) {
|
||||
$params[] = '-map';
|
||||
$params[] = '1:' . $stream->get('index');
|
||||
} else {
|
||||
$params[] = '-map';
|
||||
$params[] = '0:' . $stream->get('index');
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
29
src/FFMpeg/Filters/Video/VideoFilterInterface.php
Normal file
29
src/FFMpeg/Filters/Video/VideoFilterInterface.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?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\Filters\Video;
|
||||
|
||||
use FFMpeg\Filters\FilterInterface;
|
||||
use FFMpeg\Format\VideoInterface;
|
||||
use FFMpeg\Media\Video;
|
||||
|
||||
interface VideoFilterInterface extends FilterInterface
|
||||
{
|
||||
/**
|
||||
* Applies the filter on the the Video media given an format.
|
||||
*
|
||||
* @param Video $video
|
||||
* @param VideoInterface $format
|
||||
*
|
||||
* @return array An array of arguments
|
||||
*/
|
||||
public function apply(Video $video, VideoInterface $format);
|
||||
}
|
||||
69
src/FFMpeg/Filters/Video/VideoFilters.php
Normal file
69
src/FFMpeg/Filters/Video/VideoFilters.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?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\Filters\Video;
|
||||
|
||||
use FFMpeg\Media\Video;
|
||||
use FFMpeg\Coordinate\Dimension;
|
||||
use FFMpeg\Coordinate\FrameRate;
|
||||
|
||||
class VideoFilters
|
||||
{
|
||||
private $video;
|
||||
|
||||
public function __construct(Video $video)
|
||||
{
|
||||
$this->video = $video;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes a video to a given dimension
|
||||
*
|
||||
* @param Dimension $dimension
|
||||
* @param string $mode
|
||||
* @param Boolean $forceStandards
|
||||
*
|
||||
* @return VideoFilters
|
||||
*/
|
||||
public function resize(Dimension $dimension, $mode = ResizeFilter::RESIZEMODE_FIT, $forceStandards = true)
|
||||
{
|
||||
$this->video->addFilter(new ResizeFilter($dimension, $mode, $forceStandards));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resamples the video to the given framerate.
|
||||
*
|
||||
* @param FrameRate $framerate
|
||||
* @param type $gop
|
||||
*
|
||||
* @return VideoFilters
|
||||
*/
|
||||
public function resample(FrameRate $framerate, $gop)
|
||||
{
|
||||
$this->video->addFilter(new VideoResampleFilter($framerate, $gop));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes audio and video.
|
||||
*
|
||||
* @return VideoFilters
|
||||
*/
|
||||
public function synchronize()
|
||||
{
|
||||
$this->video->addFilter(new SynchronizeFilter());
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
72
src/FFMpeg/Filters/Video/VideoResampleFilter.php
Normal file
72
src/FFMpeg/Filters/Video/VideoResampleFilter.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?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\Filters\Video;
|
||||
|
||||
use FFMpeg\Coordinate\FrameRate;
|
||||
use FFMpeg\Media\Video;
|
||||
use FFMpeg\Format\VideoInterface;
|
||||
|
||||
class VideoResampleFilter implements VideoFilterInterface
|
||||
{
|
||||
private $rate;
|
||||
private $gop;
|
||||
|
||||
public function __construct(FrameRate $rate, $gop)
|
||||
{
|
||||
$this->rate = $rate;
|
||||
$this->gop = $gop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the frame rate
|
||||
*
|
||||
* @return FrameRate
|
||||
*/
|
||||
public function getFrameRate()
|
||||
{
|
||||
return $this->rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GOP size
|
||||
*
|
||||
* @see https://wikipedia.org/wiki/Group_of_pictures
|
||||
*
|
||||
* @return Integer
|
||||
*/
|
||||
public function getGOP()
|
||||
{
|
||||
return $this->gop;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply(Video $video, VideoInterface $format)
|
||||
{
|
||||
$commands = array('-r', $this->rate->getValue());
|
||||
|
||||
/**
|
||||
* @see http://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping
|
||||
*/
|
||||
if ($format->supportBFrames()) {
|
||||
$commands[] = '-b_strategy';
|
||||
$commands[] = '1';
|
||||
$commands[] = '-bf';
|
||||
$commands[] = '3';
|
||||
$commands[] = '-g';
|
||||
$commands[] = $this->gop;
|
||||
}
|
||||
|
||||
return $commands;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue