From 8cfb17682f368053ef3ccf6de2d4cc0f49b362dc Mon Sep 17 00:00:00 2001 From: shadrech Date: Mon, 9 Jan 2017 13:41:32 +0000 Subject: [PATCH] Add metadata to audio files - feature --- README.md | 21 +++++++++ .../Filters/Audio/AddMetadataFilter.php | 42 +++++++++++++++++ src/FFMpeg/Filters/Audio/AudioFilters.php | 22 +++++++++ .../Unit/Filters/Audio/AudioMetadataTest.php | 45 +++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 src/FFMpeg/Filters/Audio/AddMetadataFilter.php create mode 100644 tests/Unit/Filters/Audio/AudioMetadataTest.php diff --git a/README.md b/README.md index 81f809e..0e47a70 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,27 @@ method. It only accepts audio filters. You can build your own filters and some are bundled in PHP-FFMpeg - they are accessible through the `FFMpeg\Media\Audio::filters` method. +#### Metadata + +Add metadata to audio files. Just pass an array of key=value pairs of all +metadata you would like to add. If no arguments are passed into the filter +all metadata will be removed from input file. Currently supported data is +title, artist, album, artist, composer, track, year, description, artwork + +```php +$audio->filters()->addMetadata(["title" => "Some Title", "track" => 1]); + +//remove all metadata and video streams from audio file +$audio->filters()->addMetadata(); +``` + +Add artwork to the audio file +```php +$audio->filters()->addMetadata(["artwork" => "/path/to/image/file.jpg"]); +``` +NOTE: at present ffmpeg (version 3.2.2) only supports artwork output for .mp3 +files + ###### Resample Resamples an audio file. diff --git a/src/FFMpeg/Filters/Audio/AddMetadataFilter.php b/src/FFMpeg/Filters/Audio/AddMetadataFilter.php new file mode 100644 index 0000000..d889f45 --- /dev/null +++ b/src/FFMpeg/Filters/Audio/AddMetadataFilter.php @@ -0,0 +1,42 @@ +metaArr = $data; + } + + public function getPriority() + { + //must be of high priority in case theres a second input stream (artwork) to register with audio + return 9; + } + + public function apply(Audio $audio, AudioInterface $format) + { + if (is_null($this->metaArr)) + return ['-map_metadata', '-1', '-vn']; + + $metadata = []; + + if (array_key_exists("artwork", $this->metaArr)) { + array_push($metadata, "-i", $this->metaArr['artwork'], "-map", "0", "-map", "1"); + unset($this->metaArr['artwork']); + } + + foreach ($this->metaArr as $k => $v) { + array_push($metadata, "-metadata", "$k=$v"); + } + + return $metadata; + } +} diff --git a/src/FFMpeg/Filters/Audio/AudioFilters.php b/src/FFMpeg/Filters/Audio/AudioFilters.php index fe328c5..0eca6f7 100644 --- a/src/FFMpeg/Filters/Audio/AudioFilters.php +++ b/src/FFMpeg/Filters/Audio/AudioFilters.php @@ -2,6 +2,7 @@ namespace FFMpeg\Filters\Audio; +use FFMpeg\Filters\Audio\AddMetadataFilter; use FFMpeg\Media\Audio; class AudioFilters @@ -26,4 +27,25 @@ class AudioFilters return $this; } + + /** + * Add metadata to an audio file. If no arguments are given then filter + * will remove all metadata from the audio file + * @param Array|Null $data If array must contain one of these key/value pairs: + * - "title": Title metadata + * - "artist": Artist metadata + * - "composer": Composer metadata + * - "album": Album metadata + * - "track": Track metadata + * - "artwork": Song artwork. String of file path + * - "year": Year metadata + * - "genre": Genre metadata + * - "description": Description metadata + */ + public function addMetadata($data = null) + { + $this->media->addFilter(new AddMetadataFilter($data)); + + return $this; + } } diff --git a/tests/Unit/Filters/Audio/AudioMetadataTest.php b/tests/Unit/Filters/Audio/AudioMetadataTest.php new file mode 100644 index 0000000..e719fd4 --- /dev/null +++ b/tests/Unit/Filters/Audio/AudioMetadataTest.php @@ -0,0 +1,45 @@ +getAudioMock(); + $audio->expects($this->once()) + ->method('addFilter') + ->with($this->isInstanceOf('FFMpeg\Filters\Audio\AddMetadataFilter')) + ->will($this->returnCallback(function ($filter) use (&$capturedFilter) { + $capturedFilter = $filter; + })); + $format = $this->getMock('FFMpeg\Format\AudioInterface'); + + $filters = new AudioFilters($audio); + $filters->addMetadata(array('title' => "Hello World")); + $this->assertEquals(array(0 => "-metadata", 1 => "title=Hello World"), $capturedFilter->apply($audio, $format)); + } + + public function testRemoveMetadata() + { + $capturedFilter = null; + + $audio = $this->getAudioMock(); + $audio->expects($this->once()) + ->method('addFilter') + ->with($this->isInstanceOf('FFMpeg\Filters\Audio\AddMetadataFilter')) + ->will($this->returnCallback(function ($filter) use (&$capturedFilter) { + $capturedFilter = $filter; + })); + $format = $this->getMock('FFMpeg\Format\AudioInterface'); + + $filters = new AudioFilters($audio); + $filters->addMetadata(); + $this->assertEquals(array(0 => "-map_metadata", 1 => "-1", 2 => "-vn"), $capturedFilter->apply($audio, $format)); + } +}