From 9314f64f54cd434fb6ccdefc5ae7537676cb7a60 Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Thu, 2 Nov 2017 17:28:12 +0200 Subject: [PATCH 01/11] added waveform color option --- .gitignore | 1 + src/FFMpeg/Media/Audio.php | 4 +-- src/FFMpeg/Media/Waveform.php | 52 +++++++++++++++++++++++++++++-- tests/Unit/Media/WaveformTest.php | 2 +- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 7d052cb..4f3f707 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ composer.phar composer.lock phpunit.xml sami.phar +.idea/ \ No newline at end of file diff --git a/src/FFMpeg/Media/Audio.php b/src/FFMpeg/Media/Audio.php index 19f3478..605345b 100644 --- a/src/FFMpeg/Media/Audio.php +++ b/src/FFMpeg/Media/Audio.php @@ -110,8 +110,8 @@ class Audio extends AbstractStreamableMedia * @param integer $height * @return Waveform */ - public function waveform($width = 640, $height = 120) + public function waveform($width = 640, $height = 120, $colors = [Waveform::DEFAULT_COLOR]) { - return new Waveform($this, $this->driver, $this->ffprobe, $width, $height); + return new Waveform($this, $this->driver, $this->ffprobe, $width, $height, $colors); } } diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index 0954c00..6c66ed7 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -20,17 +20,21 @@ use FFMpeg\Exception\RuntimeException; class Waveform extends AbstractMediaType { + const DEFAULT_COLOR = '#000000'; + /** @var Video */ private $audio; private $width; private $height; - public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height) + public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height, $colors = [self::DEFAULT_COLOR]) { parent::__construct($audio->getPathfile(), $driver, $ffprobe); $this->audio = $audio; $this->width = $width; $this->height = $height; + + $this->setColors($colors); } /** @@ -65,6 +69,50 @@ 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 ($value{0} != '#' || strlen($value) != 7) + { + //invalid color + unset($colors[$row]); + } + } + + 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. * @@ -82,7 +130,7 @@ class Waveform extends AbstractMediaType */ $commands = array( '-i', $this->pathfile, '-filter_complex', - 'showwavespic=s='.$this->width.'x'.$this->height, + 'showwavespic=colors='.$this->compileColors().':s='.$this->width.'x'.$this->height, '-frames:v', '1' ); diff --git a/tests/Unit/Media/WaveformTest.php b/tests/Unit/Media/WaveformTest.php index cd4f08f..9e03a58 100644 --- a/tests/Unit/Media/WaveformTest.php +++ b/tests/Unit/Media/WaveformTest.php @@ -62,7 +62,7 @@ class WaveformTest extends AbstractMediaTestCase array( array( '-i', NULL, '-filter_complex', - 'showwavespic=s=640x120', + 'showwavespic=colors=#000000:s=640x120', '-frames:v', '1', ), ), From eb0bc309ef3c593d98e21e05cfb016e05f2035c1 Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Thu, 2 Nov 2017 17:31:39 +0200 Subject: [PATCH 02/11] added waveform color option --- src/FFMpeg/Media/Waveform.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index 6c66ed7..9bdd7ee 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -23,9 +23,14 @@ class Waveform extends AbstractMediaType const DEFAULT_COLOR = '#000000'; /** @var Video */ - private $audio; - private $width; - private $height; + protected $audio; + protected $width; + protected $height; + + /** + * @var array + */ + protected $colors; public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height, $colors = [self::DEFAULT_COLOR]) { From 60534a1dbb7685746ddc86b4ee1549986e1018e8 Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Thu, 2 Nov 2017 17:33:41 +0200 Subject: [PATCH 03/11] added waveform color option --- tests/Unit/Media/WaveformTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Media/WaveformTest.php b/tests/Unit/Media/WaveformTest.php index 9e03a58..49fda37 100644 --- a/tests/Unit/Media/WaveformTest.php +++ b/tests/Unit/Media/WaveformTest.php @@ -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)); } @@ -62,7 +62,7 @@ class WaveformTest extends AbstractMediaTestCase array( array( '-i', NULL, '-filter_complex', - 'showwavespic=colors=#000000:s=640x120', + 'showwavespic=colors=#FFFFFF:s=640x120', '-frames:v', '1', ), ), From 4b1033f8a29ea0097556c5d88099b7b8dba8bd1e Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Thu, 2 Nov 2017 17:44:48 +0200 Subject: [PATCH 04/11] updated README.md to represent the full possible usage of the waveform generation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a92542e..7212bf5 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ documentation below for more information. The ouput file MUST use the PNG extension. ```php -$waveform = $audio->waveform(640, 120); +$waveform = $audio->waveform(640, 120, ['#00FF00']); $waveform->save('waveform.png'); ``` From 456d9c6485d36b9bf7a49a1a2e4eed1854ff9d4f Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Fri, 3 Nov 2017 12:14:00 +0200 Subject: [PATCH 05/11] added -y property to ffmpeg when generating waveforms --- src/FFMpeg/Media/Waveform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index 9bdd7ee..84ccc05 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -134,7 +134,7 @@ class Waveform extends AbstractMediaType * @see http://ffmpeg.org/ffmpeg.html#Main-options */ $commands = array( - '-i', $this->pathfile, '-filter_complex', + '-y', '-i', $this->pathfile, '-filter_complex', 'showwavespic=colors='.$this->compileColors().':s='.$this->width.'x'.$this->height, '-frames:v', '1' ); From 89505982114f2356aa68b2e8ecf998b37e0e83fe Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Sun, 5 Nov 2017 16:28:24 +0200 Subject: [PATCH 06/11] addressing author requested fixes/changes --- src/FFMpeg/Media/Audio.php | 1 + src/FFMpeg/Media/Waveform.php | 5 ++++- tests/Unit/Media/WaveformTest.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/FFMpeg/Media/Audio.php b/src/FFMpeg/Media/Audio.php index 605345b..95d4fd0 100644 --- a/src/FFMpeg/Media/Audio.php +++ b/src/FFMpeg/Media/Audio.php @@ -108,6 +108,7 @@ 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, $colors = [Waveform::DEFAULT_COLOR]) diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index 84ccc05..ae66b49 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -79,13 +79,14 @@ class Waveform extends AbstractMediaType * 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 ($value{0} != '#' || strlen($value) != 7) + if (!preg_match_all('/^#(?:[0-9a-fA-F]{6})$/', $value)) { //invalid color unset($colors[$row]); @@ -102,6 +103,7 @@ class Waveform extends AbstractMediaType * 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() @@ -111,6 +113,7 @@ class Waveform extends AbstractMediaType /** * Compiles the selected colors into a string, using a pipe separator. + * * @return string */ protected function compileColors() diff --git a/tests/Unit/Media/WaveformTest.php b/tests/Unit/Media/WaveformTest.php index 49fda37..5d13c2e 100644 --- a/tests/Unit/Media/WaveformTest.php +++ b/tests/Unit/Media/WaveformTest.php @@ -61,7 +61,7 @@ class WaveformTest extends AbstractMediaTestCase return array( array( array( - '-i', NULL, '-filter_complex', + '-y', '-i', NULL, '-filter_complex', 'showwavespic=colors=#FFFFFF:s=640x120', '-frames:v', '1', ), From ff1a36fdccbbfa983d370c07a2b689448a2f9fc6 Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Sun, 5 Nov 2017 16:35:50 +0200 Subject: [PATCH 07/11] unnecessary use of preg_match_all replaced with preg_match --- src/FFMpeg/Media/Waveform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index ae66b49..8db0af1 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -86,7 +86,7 @@ class Waveform extends AbstractMediaType { foreach ($colors as $row => $value) { - if (!preg_match_all('/^#(?:[0-9a-fA-F]{6})$/', $value)) + if (!preg_match('/^#(?:[0-9a-fA-F]{6})$/', $value)) { //invalid color unset($colors[$row]); From 5d4dd8de3785a38eb9309775f61543a3ee7c152c Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Tue, 7 Nov 2017 11:01:42 +0200 Subject: [PATCH 08/11] forgot to update the README and describe the third waveform() param --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7212bf5..576b564 100644 --- a/README.md +++ b/README.md @@ -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, ['#00FF00']); +$waveform = $audio->waveform(640, 120, ['#00FF00/']); $waveform->save('waveform.png'); ``` From d13fa59759624460722610a5e67d763b5f2fcfdf Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Tue, 7 Nov 2017 11:07:33 +0200 Subject: [PATCH 09/11] updated color setter validation to throw InvalidArgumentException instead of silently unsetting values --- src/FFMpeg/Media/Waveform.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index 8db0af1..975f542 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -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; @@ -89,7 +90,9 @@ class Waveform extends AbstractMediaType if (!preg_match('/^#(?:[0-9a-fA-F]{6})$/', $value)) { //invalid color - unset($colors[$row]); + //unset($colors[$row]); + + throw new InvalidArgumentException("The provided color '$value' is invalid"); } } From fc5bfc691e02ef9629fdfb0580a650a258c42271 Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Tue, 7 Nov 2017 19:43:43 +0200 Subject: [PATCH 10/11] cat walked on keyboard, apparently --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a110d01..79c07d7 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ documentation below for more information. The ouput file MUST use the PNG extension. ```php -$waveform = $audio->waveform(640, 120, ['#00FF00/']); +$waveform = $audio->waveform(640, 120, ['#00FF00']); $waveform->save('waveform.png'); ``` From d5fc9ed9db1142822edbfe25c6558276f9734010 Mon Sep 17 00:00:00 2001 From: Ivan Ganev Date: Wed, 8 Nov 2017 18:32:56 +0200 Subject: [PATCH 11/11] array representation backward compat for php5 --- README.md | 2 +- src/FFMpeg/Media/Audio.php | 2 +- src/FFMpeg/Media/Waveform.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 79c07d7..79259d4 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ documentation below for more information. The ouput file MUST use the PNG extension. ```php -$waveform = $audio->waveform(640, 120, ['#00FF00']); +$waveform = $audio->waveform(640, 120, array('#00FF00')); $waveform->save('waveform.png'); ``` diff --git a/src/FFMpeg/Media/Audio.php b/src/FFMpeg/Media/Audio.php index 71fad6b..c8fddb4 100644 --- a/src/FFMpeg/Media/Audio.php +++ b/src/FFMpeg/Media/Audio.php @@ -135,7 +135,7 @@ class Audio extends AbstractStreamableMedia * @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, $colors = [Waveform::DEFAULT_COLOR]) + public function waveform($width = 640, $height = 120, $colors = array(Waveform::DEFAULT_COLOR)) { return new Waveform($this, $this->driver, $this->ffprobe, $width, $height, $colors); } diff --git a/src/FFMpeg/Media/Waveform.php b/src/FFMpeg/Media/Waveform.php index 975f542..94f1907 100644 --- a/src/FFMpeg/Media/Waveform.php +++ b/src/FFMpeg/Media/Waveform.php @@ -33,7 +33,7 @@ class Waveform extends AbstractMediaType */ protected $colors; - public function __construct(Audio $audio, FFMpegDriver $driver, FFProbe $ffprobe, $width, $height, $colors = [self::DEFAULT_COLOR]) + 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;