Merge pull request #68 from alchemy-fr/video2audio
Add support for video to audio transcoding
This commit is contained in:
		
				commit
				
					
						b3f4f6ccb9
					
				
			
		
					 11 changed files with 127 additions and 59 deletions
				
			
		|  | @ -3,6 +3,9 @@ CHANGELOG | ||||||
| 
 | 
 | ||||||
| * 0.4.0 (xx-xx-xxxx) | * 0.4.0 (xx-xx-xxxx) | ||||||
| 
 | 
 | ||||||
|  |   * Add support for video to audio transcoding | ||||||
|  |   * BC Break : Add FormatInterface::getPasses and FormatInterface::getExtraParams | ||||||
|  | 
 | ||||||
| * 0.3.5 (xx-xx-2013) | * 0.3.5 (xx-xx-2013) | ||||||
| 
 | 
 | ||||||
|   * Add vorbis audio format (@jacobbudin). |   * Add vorbis audio format (@jacobbudin). | ||||||
|  |  | ||||||
|  | @ -103,4 +103,12 @@ abstract class DefaultAudio extends EventEmitter implements AudioInterface, Prog | ||||||
| 
 | 
 | ||||||
|         return array($listener); |         return array($listener); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * {@inheritDoc} | ||||||
|  |      */ | ||||||
|  |     public function getPasses() | ||||||
|  |     { | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,13 +19,6 @@ interface AudioInterface extends FormatInterface | ||||||
|      */ |      */ | ||||||
|     public function getAudioKiloBitrate(); |     public function getAudioKiloBitrate(); | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Returns an array of extra parameters to add to ffmpeg commandline. |  | ||||||
|      * |  | ||||||
|      * @return array() |  | ||||||
|      */ |  | ||||||
|     public function getExtraParams(); |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Returns the audio codec. |      * Returns the audio codec. | ||||||
|      * |      * | ||||||
|  |  | ||||||
|  | @ -12,4 +12,17 @@ namespace FFMpeg\Format; | ||||||
| 
 | 
 | ||||||
| interface FormatInterface | interface FormatInterface | ||||||
| { | { | ||||||
|  |     /** | ||||||
|  |      * Returns the number of passes. | ||||||
|  |      * | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public function getPasses(); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns an array of extra parameters to add to ffmpeg commandline. | ||||||
|  |      * | ||||||
|  |      * @return array() | ||||||
|  |      */ | ||||||
|  |     public function getExtraParams(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -86,14 +86,6 @@ abstract class DefaultVideo extends DefaultAudio implements VideoInterface | ||||||
|         return $this; |         return $this; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * {@inheritDoc} |  | ||||||
|      */ |  | ||||||
|     public function getPasses() |  | ||||||
|     { |  | ||||||
|         return 1; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * @return integer |      * @return integer | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|  | @ -20,13 +20,6 @@ interface VideoInterface extends AudioInterface | ||||||
|      */ |      */ | ||||||
|     public function getKiloBitrate(); |     public function getKiloBitrate(); | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Returns the number of passes. |  | ||||||
|      * |  | ||||||
|      * @return string |  | ||||||
|      */ |  | ||||||
|     public function getPasses(); |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Returns the modulus used by the Resizable video. |      * Returns the modulus used by the Resizable video. | ||||||
|      * |      * | ||||||
|  |  | ||||||
|  | @ -20,6 +20,8 @@ use FFMpeg\Filters\Video\VideoFilters; | ||||||
| use FFMpeg\Filters\FilterInterface; | use FFMpeg\Filters\FilterInterface; | ||||||
| use FFMpeg\Format\FormatInterface; | use FFMpeg\Format\FormatInterface; | ||||||
| use FFMpeg\Format\ProgressableInterface; | use FFMpeg\Format\ProgressableInterface; | ||||||
|  | use FFMpeg\Format\AudioInterface; | ||||||
|  | use FFMpeg\Format\VideoInterface; | ||||||
| use FFMpeg\Media\Frame; | use FFMpeg\Media\Frame; | ||||||
| use Neutron\TemporaryFilesystem\Manager as FsManager; | use Neutron\TemporaryFilesystem\Manager as FsManager; | ||||||
| 
 | 
 | ||||||
|  | @ -67,43 +69,51 @@ class Video extends Audio | ||||||
|         if ($this->driver->getConfiguration()->has('ffmpeg.threads')) { |         if ($this->driver->getConfiguration()->has('ffmpeg.threads')) { | ||||||
|             $filters->add(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads')))); |             $filters->add(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads')))); | ||||||
|         } |         } | ||||||
|         if (null !== $format->getVideoCodec()) { |         if ($format instanceOf VideoInterface) { | ||||||
|             $filters->add(new SimpleFilter(array('-vcodec', $format->getVideoCodec()))); |             if (null !== $format->getVideoCodec()) { | ||||||
|  |                 $filters->add(new SimpleFilter(array('-vcodec', $format->getVideoCodec()))); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         if (null !== $format->getAudioCodec()) { |         if ($format instanceOf AudioInterface) { | ||||||
|             $filters->add(new SimpleFilter(array('-acodec', $format->getAudioCodec()))); |             if (null !== $format->getAudioCodec()) { | ||||||
|  |                 $filters->add(new SimpleFilter(array('-acodec', $format->getAudioCodec()))); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         foreach ($filters as $filter) { |         foreach ($filters as $filter) { | ||||||
|             $commands = array_merge($commands, $filter->apply($this, $format)); |             $commands = array_merge($commands, $filter->apply($this, $format)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $commands[] = '-b:v'; |         if ($format instanceOf VideoInterface) { | ||||||
|         $commands[] = $format->getKiloBitrate() . 'k'; |             $commands[] = '-b:v'; | ||||||
|         $commands[] = '-refs'; |             $commands[] = $format->getKiloBitrate() . 'k'; | ||||||
|         $commands[] = '6'; |             $commands[] = '-refs'; | ||||||
|         $commands[] = '-coder'; |             $commands[] = '6'; | ||||||
|         $commands[] = '1'; |             $commands[] = '-coder'; | ||||||
|         $commands[] = '-sc_threshold'; |             $commands[] = '1'; | ||||||
|         $commands[] = '40'; |             $commands[] = '-sc_threshold'; | ||||||
|         $commands[] = '-flags'; |             $commands[] = '40'; | ||||||
|         $commands[] = '+loop'; |             $commands[] = '-flags'; | ||||||
|         $commands[] = '-me_range'; |             $commands[] = '+loop'; | ||||||
|         $commands[] = '16'; |             $commands[] = '-me_range'; | ||||||
|         $commands[] = '-subq'; |             $commands[] = '16'; | ||||||
|         $commands[] = '7'; |             $commands[] = '-subq'; | ||||||
|         $commands[] = '-i_qfactor'; |             $commands[] = '7'; | ||||||
|         $commands[] = '0.71'; |             $commands[] = '-i_qfactor'; | ||||||
|         $commands[] = '-qcomp'; |             $commands[] = '0.71'; | ||||||
|         $commands[] = '0.6'; |             $commands[] = '-qcomp'; | ||||||
|         $commands[] = '-qdiff'; |             $commands[] = '0.6'; | ||||||
|         $commands[] = '4'; |             $commands[] = '-qdiff'; | ||||||
|         $commands[] = '-trellis'; |             $commands[] = '4'; | ||||||
|         $commands[] = '1'; |             $commands[] = '-trellis'; | ||||||
|  |             $commands[] = '1'; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (null !== $format->getAudioKiloBitrate()) { |         if ($format instanceOf AudioInterface) { | ||||||
|             $commands[] = '-b:a'; |             if (null !== $format->getAudioKiloBitrate()) { | ||||||
|             $commands[] = $format->getAudioKiloBitrate() . 'k'; |                 $commands[] = '-b:a'; | ||||||
|  |                 $commands[] = $format->getAudioKiloBitrate() . 'k'; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $fs = FsManager::create(); |         $fs = FsManager::create(); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								tests/FFMpeg/Tests/Media/AudioProg.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/FFMpeg/Tests/Media/AudioProg.php
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace FFMpeg\Tests\Media; | ||||||
|  | 
 | ||||||
|  | use FFMpeg\Format\ProgressableInterface; | ||||||
|  | use FFMpeg\Format\AudioInterface; | ||||||
|  | 
 | ||||||
|  | abstract class AudioProg implements ProgressableInterface, AudioInterface | ||||||
|  | { | ||||||
|  | } | ||||||
|  | @ -333,7 +333,3 @@ class AudioTest extends AbstractStreamableTestCase | ||||||
|         return 'FFMpeg\Media\Audio'; |         return 'FFMpeg\Media\Audio'; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| abstract class AudioProg implements ProgressableInterface, AudioInterface |  | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								tests/FFMpeg/Tests/Media/Prog.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/FFMpeg/Tests/Media/Prog.php
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace FFMpeg\Tests\Media; | ||||||
|  | 
 | ||||||
|  | use FFMpeg\Format\ProgressableInterface; | ||||||
|  | use FFMpeg\Format\VideoInterface; | ||||||
|  | 
 | ||||||
|  | abstract class Prog implements ProgressableInterface, VideoInterface | ||||||
|  | { | ||||||
|  | } | ||||||
|  | @ -259,6 +259,20 @@ class VideoTest extends AbstractStreamableTestCase | ||||||
|             ->method('getPasses') |             ->method('getPasses') | ||||||
|             ->will($this->returnValue(2)); |             ->will($this->returnValue(2)); | ||||||
| 
 | 
 | ||||||
|  |         $audioFormat = $this->getMock('FFMpeg\Format\AudioInterface'); | ||||||
|  |         $audioFormat->expects($this->any()) | ||||||
|  |             ->method('getExtraParams') | ||||||
|  |             ->will($this->returnValue(array())); | ||||||
|  |         $audioFormat->expects($this->any()) | ||||||
|  |             ->method('getAudioCodec') | ||||||
|  |             ->will($this->returnValue('patati-patata-audio')); | ||||||
|  |         $audioFormat->expects($this->any()) | ||||||
|  |             ->method('getAudioKiloBitrate') | ||||||
|  |             ->will($this->returnValue(92)); | ||||||
|  |         $audioFormat->expects($this->any()) | ||||||
|  |             ->method('getPasses') | ||||||
|  |             ->will($this->returnValue(1)); | ||||||
|  | 
 | ||||||
|         $audioVideoFormat = $this->getMock('FFMpeg\Format\VideoInterface'); |         $audioVideoFormat = $this->getMock('FFMpeg\Format\VideoInterface'); | ||||||
|         $audioVideoFormat->expects($this->any()) |         $audioVideoFormat->expects($this->any()) | ||||||
|             ->method('getExtraParams') |             ->method('getExtraParams') | ||||||
|  | @ -333,6 +347,24 @@ class VideoTest extends AbstractStreamableTestCase | ||||||
|             ->method('getPasses') |             ->method('getPasses') | ||||||
|             ->will($this->returnValue(2)); |             ->will($this->returnValue(2)); | ||||||
| 
 | 
 | ||||||
|  |         $progressableAudioFormat = $this->getMockBuilder('FFMpeg\Tests\Media\AudioProg') | ||||||
|  |             ->disableOriginalConstructor()->getMock(); | ||||||
|  |         $progressableAudioFormat->expects($this->any()) | ||||||
|  |             ->method('getExtraParams') | ||||||
|  |             ->will($this->returnValue(array())); | ||||||
|  |         $progressableAudioFormat->expects($this->any()) | ||||||
|  |             ->method('getAudioCodec') | ||||||
|  |             ->will($this->returnValue('patati-patata-audio')); | ||||||
|  |         $progressableAudioFormat->expects($this->any()) | ||||||
|  |             ->method('createProgressListener') | ||||||
|  |             ->will($this->returnValue($listeners)); | ||||||
|  |         $progressableAudioFormat->expects($this->any()) | ||||||
|  |             ->method('getAudioKiloBitrate') | ||||||
|  |             ->will($this->returnValue(92)); | ||||||
|  |         $progressableAudioFormat->expects($this->any()) | ||||||
|  |             ->method('getPasses') | ||||||
|  |             ->will($this->returnValue(1)); | ||||||
|  | 
 | ||||||
|         return array( |         return array( | ||||||
|             array(false, array(array( |             array(false, array(array( | ||||||
|                     '-y', '-i', __FILE__, '-b:v', '663k', |                     '-y', '-i', __FILE__, '-b:v', '663k', | ||||||
|  | @ -451,6 +483,18 @@ class VideoTest extends AbstractStreamableTestCase | ||||||
|                     '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-pass', '2', '-passlogfile', |                     '-qdiff', '4', '-trellis', '1', '-b:a', '92k', '-pass', '2', '-passlogfile', | ||||||
|                     '/target/file', |                     '/target/file', | ||||||
|                 )), $listeners, $progressableFormat), |                 )), $listeners, $progressableFormat), | ||||||
|  |             array(true, array(array( | ||||||
|  |                     '-y', '-i', __FILE__, | ||||||
|  |                     '-threads', 24, '-acodec', 'patati-patata-audio', | ||||||
|  |                     '-b:a', '92k', | ||||||
|  |                     '/target/file', | ||||||
|  |                 )), null, $audioFormat), | ||||||
|  |             array(true, array(array( | ||||||
|  |                     '-y', '-i', __FILE__, | ||||||
|  |                     '-threads', 24, '-acodec', 'patati-patata-audio', | ||||||
|  |                     '-b:a', '92k', | ||||||
|  |                     '/target/file', | ||||||
|  |                 )), $listeners, $progressableAudioFormat), | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -555,7 +599,3 @@ class VideoTest extends AbstractStreamableTestCase | ||||||
|         return 'FFMpeg\Media\Video'; |         return 'FFMpeg\Media\Video'; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| abstract class Prog implements ProgressableInterface, VideoInterface |  | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue