Audio Clip (#314)
* 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...
This commit is contained in:
parent
ce99075059
commit
ecd50cd5f1
6 changed files with 201 additions and 0 deletions
|
|
@ -89,4 +89,32 @@ class TimeCode
|
|||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
84
src/FFMpeg/Filters/Audio/AudioClipFilter.php
Normal file
84
src/FFMpeg/Filters/Audio/AudioClipFilter.php
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -48,4 +58,17 @@ class AudioFilters
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
47
tests/Unit/Filters/Audio/AudioClipTest.php
Normal file
47
tests/Unit/Filters/Audio/AudioClipTest.php
Normal file
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue