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); |         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 | <?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; | namespace FFMpeg\Filters\Audio; | ||||||
| 
 | 
 | ||||||
| use FFMpeg\Filters\Audio\AudioFilterInterface; | 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 | <?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; | namespace FFMpeg\Filters\Audio; | ||||||
| 
 | 
 | ||||||
| use FFMpeg\Filters\Audio\AddMetadataFilter; | use FFMpeg\Filters\Audio\AddMetadataFilter; | ||||||
| use FFMpeg\Media\Audio; | use FFMpeg\Media\Audio; | ||||||
|  | use FFMpeg\Coordinate\TimeCode; | ||||||
| 
 | 
 | ||||||
| class AudioFilters | class AudioFilters | ||||||
| { | { | ||||||
|  | @ -48,4 +58,17 @@ class AudioFilters | ||||||
| 
 | 
 | ||||||
|         return $this; |         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 | <?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; | namespace FFMpeg\Filters\Audio; | ||||||
| 
 | 
 | ||||||
| use FFMpeg\Media\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