Merge pull request #437 from iganev/master

Added color option to waveform generation
This commit is contained in:
Jens Hausdorf 2017-11-08 18:05:52 +01:00 committed by GitHub
commit d17f802958
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 14 deletions

1
.gitignore vendored
View file

@ -5,3 +5,4 @@ composer.phar
composer.lock
phpunit.xml
sami.phar
.idea/

View file

@ -159,13 +159,13 @@ You can generate a waveform of an audio file using the `FFMpeg\Media\Audio::wave
method.
This code returns a `FFMpeg\Media\Waveform` instance.
You can optionally pass dimensions as arguments, see dedicated
You can optionally pass dimensions as the first two arguments and an array of hex string colors for ffmpeg to use for the waveform, see dedicated
documentation below for more information.
The ouput file MUST use the PNG extension.
```php
$waveform = $audio->waveform(640, 120);
$waveform = $audio->waveform(640, 120, array('#00FF00'));
$waveform->save('waveform.png');
```

View file

@ -132,10 +132,11 @@ class Audio extends AbstractStreamableMedia
*
* @param integer $width
* @param integer $height
* @param array $colors Array of colors for ffmpeg to use. Color format is #000000 (RGB hex string with #)
* @return Waveform
*/
public function waveform($width = 640, $height = 120)
public function waveform($width = 640, $height = 120, $colors = array(Waveform::DEFAULT_COLOR))
{
return new Waveform($this, $this->driver, $this->ffprobe, $width, $height);
return new Waveform($this, $this->driver, $this->ffprobe, $width, $height, $colors);
}
}

View file

@ -12,6 +12,7 @@
namespace FFMpeg\Media;
use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
use FFMpeg\Exception\InvalidArgumentException;
use FFMpeg\Filters\Waveform\WaveformFilterInterface;
use FFMpeg\Filters\Waveform\WaveformFilters;
use FFMpeg\Driver\FFMpegDriver;
@ -20,17 +21,26 @@ use FFMpeg\Exception\RuntimeException;
class Waveform extends AbstractMediaType
{
/** @var Video */
private $audio;
private $width;
private $height;
const DEFAULT_COLOR = '#000000';
public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height)
/** @var Video */
protected $audio;
protected $width;
protected $height;
/**
* @var array
*/
protected $colors;
public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height, $colors = array(self::DEFAULT_COLOR))
{
parent::__construct($audio->getPathfile(), $driver, $ffprobe);
$this->audio = $audio;
$this->width = $width;
$this->height = $height;
$this->setColors($colors);
}
/**
@ -65,6 +75,55 @@ class Waveform extends AbstractMediaType
return $this;
}
/**
* Parameter should be an array containing at least one valid color represented as a HTML color string. For
* example #FFFFFF or #000000. By default the color is set to black. Keep in mind that if you save the waveform
* as jpg file, it will appear completely black and to avoid this you can set the waveform color to white (#FFFFFF).
* Saving waveforms to png is strongly suggested.
*
* @param array $colors
*/
public function setColors(array $colors)
{
foreach ($colors as $row => $value)
{
if (!preg_match('/^#(?:[0-9a-fA-F]{6})$/', $value))
{
//invalid color
//unset($colors[$row]);
throw new InvalidArgumentException("The provided color '$value' is invalid");
}
}
if (count($colors))
{
$this->colors = $colors;
}
}
/**
* Returns an array of colors that will be passed to ffmpeg to use for waveform generation. Colors are applied ONLY
* to the waveform. Background cannot be controlled that easily and it is probably easier to save the waveform
* as a transparent png file and then add background of choice.
*
* @return array
*/
public function getColors()
{
return $this->colors;
}
/**
* Compiles the selected colors into a string, using a pipe separator.
*
* @return string
*/
protected function compileColors()
{
return implode('|', $this->colors);
}
/**
* Saves the waveform in the given filename.
*
@ -81,8 +140,8 @@ class Waveform extends AbstractMediaType
* @see http://ffmpeg.org/ffmpeg.html#Main-options
*/
$commands = array(
'-i', $this->pathfile, '-filter_complex',
'showwavespic=s='.$this->width.'x'.$this->height,
'-y', '-i', $this->pathfile, '-filter_complex',
'showwavespic=colors='.$this->compileColors().':s='.$this->width.'x'.$this->height,
'-frames:v', '1'
);

View file

@ -52,7 +52,7 @@ class WaveformTest extends AbstractMediaTestCase
->method('command')
->with($commands);
$waveform = new Waveform($this->getAudioMock(__FILE__), $driver, $ffprobe, 640, 120);
$waveform = new Waveform($this->getAudioMock(__FILE__), $driver, $ffprobe, 640, 120, ['#FFFFFF']);
$this->assertSame($waveform, $waveform->save($pathfile));
}
@ -61,8 +61,8 @@ class WaveformTest extends AbstractMediaTestCase
return array(
array(
array(
'-i', NULL, '-filter_complex',
'showwavespic=s=640x120',
'-y', '-i', NULL, '-filter_complex',
'showwavespic=colors=#FFFFFF:s=640x120',
'-frames:v', '1',
),
),