Merge pull request #281 from shadrech/addAudioMetadata

Add audio metadata filter
This commit is contained in:
Romain Biard 2017-01-13 12:28:14 -03:00 committed by GitHub
commit 8577cdbb7f
4 changed files with 151 additions and 0 deletions

View file

@ -344,6 +344,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.

View file

@ -0,0 +1,45 @@
<?php
namespace FFMpeg\Filters\Audio;
use FFMpeg\Filters\Audio\AudioFilterInterface;
use FFMpeg\Format\AudioInterface;
use FFMpeg\Media\Audio;
class AddMetadataFilter implements AudioFilterInterface
{
/** @var Array */
private $metaArr;
/** @var Integer */
private $priority;
function __construct($data = null, $priority = 9)
{
$this->metaArr = $data;
$this->priority = $priority;
}
public function getPriority()
{
//must be of high priority in case theres a second input stream (artwork) to register with audio
return $this->priority;
}
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;
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace Tests\FFMpeg\Unit\Filters\Audio;
use FFMpeg\Filters\Audio\AudioFilters;
use Tests\FFMpeg\Unit\TestCase;
class AudioMetadataTest extends TestCase
{
public function testAddMetadata()
{
$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(array('title' => "Hello World"));
$this->assertEquals(array(0 => "-metadata", 1 => "title=Hello World"), $capturedFilter->apply($audio, $format));
}
public function testAddArtwork()
{
$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(array('genre' => 'Some Genre', 'artwork' => "/path/to/file.jpg"));
$this->assertEquals(array(0 => "-i", 1 => "/path/to/file.jpg", 2 => "-map", 3 => "0", 4 => "-map", 5 => "1", 6 => "-metadata", 7 => "genre=Some Genre"), $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));
}
}