Skip to content

Commit

Permalink
Audio Clip (PHP-FFMpeg#314)
Browse files Browse the repository at this point in the history
* add missing headers
* add audio clip filter and improve timecode
* php 5.4 :(
* prevent audio from being reencoded
* php 5.x: Really?
* fix tests... I need to concentrate...
  • Loading branch information
jens1o authored and Romain committed Mar 6, 2017
1 parent ce99075 commit ecd50cd
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/FFMpeg/Coordinate/TimeCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,32 @@ public static function fromSeconds($quantity)

return new static($hours, $minutes, $seconds, $frames);
}

/**
* Returns this timecode in seconds
* @return int
*/
public function toSeconds() {
$seconds = 0;

$seconds += $this->hours * 60 * 60;
$seconds += $this->minutes * 60;
$seconds += $this->seconds;

// TODO: Handle frames?
return (int) $seconds;
}

/**
* Helper function wether `$timecode` is after this one
*
* @param TimeCode $timecode The Timecode to compare
* @return bool
*/
public function isAfter(TimeCode $timecode) {
// convert everything to seconds and compare
return ($this->toSeconds() > $timecode->toSeconds());
}

}
10 changes: 10 additions & 0 deletions src/FFMpeg/Filters/Audio/AddMetadataFilter.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?php

/*
* This file is part of PHP-FFmpeg.
*
* (c) Alchemy <info@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\Audio\AudioFilterInterface;
Expand Down
84 changes: 84 additions & 0 deletions src/FFMpeg/Filters/Audio/AudioClipFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

/*
* This file is part of PHP-FFmpeg.
*
* (c) Alchemy <info@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\Coordinate\TimeCode;
use FFMpeg\Format\AudioInterface;
use FFMpeg\Media\Audio;

class AudioClipFilter implements AudioFilterInterface {

/**
* @var TimeCode
*/
private $start;

/**
* @var TimeCode
*/
private $duration;

/**
* @var int
*/
private $priority;


public function __construct(TimeCode $start, TimeCode $duration = null, $priority = 0) {
$this->start = $start;
$this->duration = $duration;
$this->priority = $priority;
}

/**
* @inheritDoc
*/
public function getPriority() {
return $this->priority;
}

/**
* Returns the start position the audio is being cutted
*
* @return TimeCode
*/
public function getStart() {
return $this->start;
}

/**
* Returns how long the audio is being cutted. Returns null when the duration is infinite,
*
* @return TimeCode|null
*/
public function getDuration() {
return $this->duration;
}

/**
* @inheritDoc
*/
public function apply(Audio $audio, AudioInterface $format) {
$commands = array('-ss', (string) $this->start);

if ($this->duration !== null) {
$commands[] = '-t';
$commands[] = (string) $this->duration;
}

$commands[] = '-acodec';
$commands[] = 'copy';

return $commands;
}

}
23 changes: 23 additions & 0 deletions src/FFMpeg/Filters/Audio/AudioFilters.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
<?php

/*
* This file is part of PHP-FFmpeg.
*
* (c) Alchemy <info@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\Audio\AddMetadataFilter;
use FFMpeg\Media\Audio;
use FFMpeg\Coordinate\TimeCode;

class AudioFilters
{
Expand Down Expand Up @@ -48,4 +58,17 @@ public function addMetadata($data = null)

return $this;
}

/**
* Cuts the audio at `$start`, optionally define the end
*
* @param TimeCode $start Where the clipping starts(seek to time)
* @param TimeCode $duration How long the clipped audio should be
* @return AudioFilters
*/
public function clip($start, $duration = null) {
$this->media->addFilter(new AudioClipFilter($start, $duration));

return $this;
}
}
9 changes: 9 additions & 0 deletions src/FFMpeg/Filters/Audio/SimpleFilter.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<?php

/*
* This file is part of PHP-FFmpeg.
*
* (c) Alchemy <info@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\Media\Audio;
Expand Down
47 changes: 47 additions & 0 deletions tests/Unit/Filters/Audio/AudioClipTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Tests\FFMpeg\Unit\Filters\Audio;

use FFMpeg\Filters\Audio\AudioFilters;
use FFMpeg\Coordinate\TimeCode;
use Tests\FFMpeg\Unit\TestCase;

class AudioClipTest extends TestCase {

public function testClipping() {
$capturedFilter = null;

$audio = $this->getAudioMock();
$audio->expects($this->once())
->method('addFilter')
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AudioClipFilter'))
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
$capturedFilter = $filter;
}));
$format = $this->getMock('FFMpeg\Format\AudioInterface');

$filters = new AudioFilters($audio);

$filters->clip(TimeCode::fromSeconds(5));
$this->assertEquals(array(0 => '-ss', 1 => '00:00:05.00', 2 => '-acodec', 3 => 'copy'), $capturedFilter->apply($audio, $format));
}

public function testClippingWithDuration() {
$capturedFilter = null;

$audio = $this->getAudioMock();
$audio->expects($this->once())
->method('addFilter')
->with($this->isInstanceOf('FFMpeg\Filters\Audio\AudioClipFilter'))
->will($this->returnCallback(function ($filter) use (&$capturedFilter) {
$capturedFilter = $filter;
}));
$format = $this->getMock('FFMpeg\Format\AudioInterface');

$filters = new AudioFilters($audio);

$filters->clip(TimeCode::fromSeconds(5), TimeCode::fromSeconds(5));
$this->assertEquals(array(0 => '-ss', 1 => '00:00:05.00', 2 => '-t', 3 => '00:00:05.00', 4 => '-acodec', 5 => 'copy'), $capturedFilter->apply($audio, $format));
}

}

0 comments on commit ecd50cd

Please sign in to comment.