public function register(Application $app)
 {
     $app['ffmpeg.configuration'] = array();
     $app['ffmpeg.default.configuration'] = array('ffmpeg.threads' => 4, 'ffmpeg.timeout' => 300, 'ffmpeg.binaries' => array('avconv', 'ffmpeg'), 'ffprobe.timeout' => 30, 'ffprobe.binaries' => array('avprobe', 'ffprobe'));
     $app['ffmpeg.logger'] = null;
     $app['ffmpeg.configuration.build'] = $app->share(function (Application $app) {
         return array_replace($app['ffmpeg.default.configuration'], $app['ffmpeg.configuration']);
     });
     $app['ffmpeg'] = $app['ffmpeg.ffmpeg'] = $app->share(function (Application $app) {
         $configuration = $app['ffmpeg.configuration.build'];
         if (isset($configuration['ffmpeg.timeout'])) {
             $configuration['timeout'] = $configuration['ffmpeg.timeout'];
         }
         return FFMpeg::create($configuration, $app['ffmpeg.logger'], $app['ffmpeg.ffprobe']);
     });
     $app['ffprobe.cache'] = $app->share(function () {
         return new ArrayCache();
     });
     $app['ffmpeg.ffprobe'] = $app->share(function (Application $app) {
         $configuration = $app['ffmpeg.configuration.build'];
         if (isset($configuration['ffmpeg.timeout'])) {
             $configuration['timeout'] = $configuration['ffprobe.timeout'];
         }
         return FFProbe::create($configuration, $app['ffmpeg.logger'], $app['ffprobe.cache']);
     });
 }
 /**
  * @covers MediaVorus\MediaCollection::match
  */
 public function testMatch()
 {
     $logger = new Logger('test');
     $logger->pushHandler(new NullHandler());
     $mediavorus = new MediaVorus(Reader::create($logger), Writer::create($logger), FFProbe::create());
     $collection = $mediavorus->inspectDirectory(__DIR__ . '/../../files/');
     $audio = $collection->match(new MediaType(MediaInterface::TYPE_AUDIO));
     $this->assertInstanceOf('\\Doctrine\\Common\\Collections\\ArrayCollection', $audio);
     $this->assertGreaterThan(0, $audio->count());
     foreach ($audio as $audio) {
         $this->assertEquals(MediaInterface::TYPE_AUDIO, $audio->getType());
     }
     $notAudio = $collection->match(new MediaType(MediaInterface::TYPE_AUDIO), true);
     $this->assertGreaterThan(0, $notAudio->count());
     $this->assertInstanceOf('\\Doctrine\\Common\\Collections\\ArrayCollection', $notAudio);
     foreach ($notAudio as $audio) {
         $this->assertFalse(MediaInterface::TYPE_AUDIO === $audio->getType());
     }
 }
Beispiel #3
0
 /**
  * Instantiate mediavorus to register the mime types
  */
 public function setUp()
 {
     parent::setUp();
     $logger = new Logger('test');
     $logger->pushHandler(new NullHandler());
     $mediavorus = new MediaVorus(Reader::create($logger), Writer::create($logger), FFProbe::create());
 }
 public function getProbe()
 {
     try {
         return FFProbe::create();
     } catch (FFMpegExecutableNotFound $e) {
     }
     return null;
 }
Beispiel #5
0
 public function __construct($file, $screenshotDirectory = '/tmp')
 {
     $this->file = $file;
     $this->screenshotDirectory = $screenshotDirectory;
     $this->ffmpeg = FFMpeg::create();
     $this->ffprobe = FFProbe::create();
     $this->movie = $this->ffmpeg->open($file);
     $this->info = $this->ffprobe->format($file);
 }
Beispiel #6
0
 public function setUp()
 {
     if (!class_exists('FFMpeg\\FFProbe')) {
         $this->markTestSkipped('FFMpeg\\FFProbe not available.');
     }
     try {
         $this->reader = new FfprobeReader(FFProbe::create());
     } catch (\Exception $e) {
         $this->markTestSkipped('FfprobeReader not available.');
     }
 }
Beispiel #7
0
 /**
  * Create screenshot from uploaded video
  * @param  \App\Models\Video $video The object we created
  * @return boolean	Always true
  */
 private function capture(\App\Models\Video $video)
 {
     //that's easier
     $video_path = public_path('/videos/' . $video->video);
     //find duration
     $ffprobe = \FFMpeg\FFProbe::create();
     $duration = $ffprobe->format($video_path)->get('duration');
     //take the shot
     $ffmpeg = \FFMpeg\FFMpeg::create();
     $capture = $ffmpeg->open($video_path);
     $capture->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds($duration > 5 ? 5 : (int) ($duration / 2)))->save(public_path('/previews/' . $video->getKey() . '.jpg'));
     return true;
 }
Beispiel #8
0
 protected function __construct()
 {
     $basedir = dirname(dirname(dirname(__DIR__)));
     StitchLib::$log_dir = $basedir . DIRECTORY_SEPARATOR . 'logs';
     StitchLib::$tmp_dir = sys_get_temp_dir();
     if (!is_dir(StitchLib::$log_dir)) {
         mkdir(StitchLib::$log_dir);
     }
     if (!is_dir(StitchLib::$tmp_dir)) {
         mkdir(StitchLib::$tmp_dir, 0777, true);
     }
     $this->logger = new Logger(StitchLib::$log_dir);
     $this->ffprobe = \FFMpeg\FFProbe::create([], $this->logger);
 }
 public function setUp()
 {
     parent::setUp();
     $logger = new Logger('Tests');
     $logger->pushHandler(new NullHandler());
     $this->reader = Reader::create($logger);
     $this->writer = Writer::create($logger);
     $file = __DIR__ . '/../../../files/ExifTool.jpg';
     $this->object = new Image(new File($file), $this->reader->reset()->files($file)->first(), $this->writer);
     $logger = new Logger('test');
     $logger->pushHandler(new NullHandler());
     $this->ffprobe = FFProbe::create();
     $this->mediavorus = new MediaVorus($this->reader, $this->writer, $this->ffprobe);
 }
Beispiel #10
0
 /**
  * Create.
  *
  * This method creates the thumbnail from the video.
  *
  * @param string   $videoFile     Video file to process
  * @param string   $thumbnailFile Output gif
  * @param int|null $count         Number of frames to use
  * @param int|null $interval      The interval beetween the frames of the gif
  * @param int|null $width         Width of the gif
  * @param int|null $height        Height of the gif
  * @param int|null $start         The start of the video part
  * @param int|null $end           The end of the video part
  *
  * @throws VideoException If error during procession or writing.
  */
 public function create($videoFile, $thumbnailFile, $count = null, $interval = null, $width = null, $height = null, $start = null, $end = null)
 {
     $count = $count ?: $this->defaults['count'];
     $interval = $interval ?: $this->defaults['interval'];
     $width = $width ?: $this->defaults['width'];
     $height = $height ?: $this->defaults['height'];
     try {
         $ffmpeg = FFMpeg::create();
         $ffprobe = FFProbe::create();
     } catch (\Exception $e) {
         throw new VideoException('Cannot start FFMpeg or FFProbe', 0, $e);
     }
     try {
         // Determine the duration of the video
         $duration = $ffprobe->format($videoFile)->get('duration');
     } catch (\Exception $e) {
         throw new VideoException(sprintf('Cannot determine the duration of %s', $videoFile), 0, $e);
     }
     // If invalid start or end time, assume it is the start and the end
     // of the video.
     $start = max(0, $start ?: 0);
     $end = min($duration, $end ?: $duration);
     $delay = (double) ($end - $start) / ($count + 1);
     $video = $ffmpeg->open($videoFile);
     $hashDir = $this->tmpDir . '/video-gif/' . md5($videoFile . time());
     if (!file_exists($hashDir)) {
         mkdir($hashDir, 0777, true);
     }
     $pos = $start;
     $frames = array();
     $durations = array();
     // Grab frames
     for ($i = 0; $i < $count; ++$i) {
         $pos += $delay;
         $video->frame(TimeCode::fromSeconds($pos))->save(sprintf($hashDir . '/tmp-frame%03d.jpg', $i));
         Image::open(sprintf($hashDir . '/tmp-frame%03d.jpg', $i))->cropResize($width, $height)->save(sprintf($hashDir . '/frame%03d.jpg', $i));
         $frames[] = sprintf($hashDir . '/frame%03d.jpg', $i);
         $durations[] = $interval;
     }
     $gc = new GifCreator();
     $gc->create($frames, $durations, 0);
     $this->removeDirectory($hashDir);
     if (false === @file_put_contents($thumbnailFile, $gc->getGif())) {
         throw new VideoException(sprintf('Cannot write %s', $thumbnailFile));
     }
 }
Beispiel #11
0
 /**
  * Get video properties
  *
  * @param $path
  * @return array|null
  * @throws ErrorException
  */
 public static function getProperties($path)
 {
     if (is_file($path)) {
         // init
         $ffprobe = FFProbe::create();
         $streams = $ffprobe->streams($path);
         // extracts streams informations
         // get video data
         $video = $streams->videos()->first();
         // filters video first streams
         $dimensions = $video->getDimensions();
         // get audio data
         $audio = $streams->audios()->first();
         // filters audio first streams
         return ['screen_width' => $dimensions->getWidth(), 'screen_height' => $dimensions->getHeight(), 'video_bitrate' => $video->get('bit_rate'), 'audio_bitrate' => $audio->get('bit_rate')];
     }
     throw new ErrorException('Not found file: ' . $path);
 }
Beispiel #12
0
 /**
  * Create MediaVorus
  *
  * @return MediaVorus
  */
 public static function create()
 {
     $logger = new Logger('MediaVorus');
     $logger->pushHandler(new NullHandler());
     return new static(Reader::create($logger), Writer::create($logger), FFProbe::create(array(), $logger));
 }
 public function __construct($file)
 {
     parent::__construct($file);
     $this->ffprobe = FFProbe::create(['ffmpeg.binaries' => env('FFMPEG'), 'ffprobe.binaries' => env('FFPROBE')]);
     $this->ffmpeg = FFMpeg::create(['ffmpeg.binaries' => env('FFMPEG'), 'ffprobe.binaries' => env('FFPROBE')]);
 }
Beispiel #14
0
 public function testProbeOnRemoteFile()
 {
     $ffprobe = FFProbe::create();
     $this->assertGreaterThan(0, count($ffprobe->streams('http://vjs.zencdn.net/v/oceans.mp4')));
 }
 /**
  * Generates sprite and WebVTT for selected video
  *
  * @throws \Exception
  */
 public function generate()
 {
     // create temporay directory
     $tempDir = new Tempdir('sprite');
     $tempDir->addPlugin(new ListFiles());
     // get basic info about video
     $ffprobe = FFProbe::create()->format($this->getSource());
     $duration = floatval($ffprobe->get('duration'));
     // check if sample rate is high enough to reach desired minimum amount of thumbnails
     if ($duration <= $this->getMinThumbs()) {
         // we only have a 1 second resolution, so we can't get lower than 1 obviously
         $this->setRate(1);
     } else {
         if ($duration / $this->getRate() < $this->getMinThumbs()) {
             // sample rate too high, let's adjust rate a little
             $this->setRate(floor($duration / $this->getMinThumbs()));
         }
     }
     // capture images to tempdir
     for ($i = 0; $i <= $duration; $i += $this->getRate()) {
         $cmd = sprintf('ffmpeg -y -ss %d -i %s -frames:v 1 -filter:v scale=%d:-1 %s/%04d.jpg', $i, $this->getSource(), $this->getWidth(), $tempDir->getPath(), floor($i / $this->getRate()));
         $proc = new Process($cmd);
         $proc->setTimeout(null);
         $proc->run();
         if (!$proc->isSuccessful()) {
             throw new \RuntimeException($cmd . ":" . $proc->getErrorOutput());
         }
     }
     // combine all images to one sprite with quadratic tiling
     $gridSize = ceil(sqrt(count($tempDir->listFiles())));
     $firstImage = Image::make(sprintf('%s/0001.jpg', $tempDir->getPath()));
     $spriteFile = sprintf('%s/%s.jpg', $this->getOutputDirectory(), $this->getPrefix());
     $spriteUrl = empty($this->getUrlPrefix()) ? basename($spriteFile) : sprintf('%s/%s', $this->getUrlPrefix(), basename($spriteFile));
     $cmd = sprintf('montage %1$s/*.jpg -tile %2$dx -geometry %3$dx%4$d+0+0 %5$s', $tempDir->getPath(), $gridSize, $firstImage->width(), $firstImage->height(), $spriteFile);
     $proc = new Process($cmd);
     $proc->run();
     if (!$proc->isSuccessful()) {
         throw new RuntimeException($proc->getErrorOutput());
     }
     // create WebVTT output
     $vttFile = sprintf('%s/%s.vtt', $this->getOutputDirectory(), $this->getPrefix());
     $vtt = new WebvttFile();
     for ($i = 0; $i < count($tempDir->listFiles()); $i++) {
         $start = $i * $this->getRate();
         $end = ($i + 1) * $this->getRate();
         $x = $i % $gridSize * $firstImage->width();
         $y = floor($i / $gridSize) * $firstImage->height();
         $vtt->addCue(new WebvttCue($this->secondsToCue($start), $this->secondsToCue($end), sprintf('%s#xywh=%d,%d,%d,%d', $spriteUrl, $x, $y, $firstImage->width(), $firstImage->height())));
     }
     $vtt->build();
     $vtt->save($vttFile);
 }
Beispiel #16
0
 /**
  * Creates a new FFMpeg instance.
  *
  * @param array|ConfigurationInterface $configuration
  * @param LoggerInterface              $logger
  * @param FFProbe                      $probe
  *
  * @return FFMpeg
  */
 public static function create($configuration = array(), LoggerInterface $logger = null, FFProbe $probe = null)
 {
     if (null === $probe) {
         $probe = FFProbe::create($configuration, $logger, null);
     }
     return new static(FFMpegDriver::create($logger, $configuration), $probe);
 }
 private function ingestImageAsset($filepath, $type, $ffprobe_config)
 {
     $msg = "Creating probe, for file: {$filepath}";
     $this->report[] = $msg;
     static::$logger->info($msg);
     try {
         $probe = FFProbe::create($ffprobe_config, static::$logger);
         if (!$probe) {
             throw new \Exception('FFProbe failed to create.');
         } else {
             $msg = "Probe created";
             $this->report[] = $msg;
             static::$logger->info($msg);
         }
     } catch (Exception $e) {
         $msg = "Probe creation failed: " . $e->getMessage();
         $this->report[] = $msg;
         static::$logger->info($msg);
     }
     $assignedProperties = [];
     $msg = "Probing file properties: {$filepath}";
     $this->report[] = $msg;
     static::$logger->info($msg);
     try {
         $props = $probe->format($filepath)->all();
         if ($props) {
             $assignedProperties[] = $this->formatToJsonArray($props);
         }
     } catch (ExecutionFailureException $e) {
         $msg = $e->getMessage();
         static::$logger->addWarning($msg);
         return false;
         // triggers rejection in ingest
     }
     $msg = "Probing exif properties";
     $this->report[] = $msg;
     static::$logger->info($msg);
     $exif = new Exif($filepath);
     $msg = "Encoding derived metadata";
     $this->report[] = $msg;
     static::$logger->info($msg);
     $exif_json = json_encode($exif->toArray(), JSON_UNESCAPED_SLASHES);
     $exif_obj = Util::decode_json($exif_json);
     $msg = "Encoding assignedProperties";
     $this->report[] = $msg;
     static::$logger->info($msg);
     $json_props = implode(",\n", $assignedProperties);
     $data = Util::decode_json($json_props);
     if ($exif_obj) {
         $msg = "Attaching derived exif props";
         $this->report[] = $msg;
         static::$logger->info($msg);
         $data->{'exif'} = $exif_obj;
     }
     $msg = "Returning derived data object";
     $this->report[] = $msg;
     static::$logger->info($msg);
     return $data;
 }
 public function getVideoLength($videoPath)
 {
     $ffprobe = \FFMpeg\FFProbe::create();
     return $ffprobe->streams($videoPath)->videos()->first()->get('duration');
 }
 /**
  *  Get FFProbe
  */
 private function getFFProbe()
 {
     return $ffmpeg = \FFMpeg\FFProbe::create($this->getFFMpegConfig());
 }
 /**
  * @dataProvider provideCreateOptions
  */
 public function testCreate($logger, $conf, $cache)
 {
     $finder = new ExecutableFinder();
     $found = false;
     foreach (array('avprobe', 'ffprobe') as $name) {
         if (null !== $finder->find($name)) {
             $found = true;
         }
     }
     if (!$found) {
         $this->markTestSkipped("Unable to find avprobe or ffprobe on system");
     }
     $ffprobe = FFProbe::create();
     $this->assertInstanceOf('FFMpeg\\FFprobe', $ffprobe);
     $ffprobe = FFProbe::create($conf, $logger, $cache);
     $this->assertInstanceOf('FFMpeg\\FFprobe', $ffprobe);
     if (null !== $cache) {
         $this->assertSame($cache, $ffprobe->getCache());
     }
     if (null !== $logger) {
         $this->assertSame($logger, $ffprobe->getFFProbeDriver()->getProcessRunner()->getLogger());
     }
     if ($conf instanceof ConfigurationInterface) {
         $this->assertSame($conf, $ffprobe->getFFProbeDriver()->getConfiguration());
     }
 }
 public function __construct()
 {
     $this['logger.name'] = 'Media-Alchemyst drivers logger';
     $this['logger.level'] = function (Pimple $container) {
         return Logger::DEBUG;
     };
     $this['logger.handler'] = $this->share(function (Pimple $container) {
         return new NullHandler($container['logger.level']);
     });
     $bridge = class_exists('Symfony\\Bridge\\Monolog\\Logger');
     $this['logger.class'] = $bridge ? 'Symfony\\Bridge\\Monolog\\Logger' : 'Monolog\\Logger';
     $this['logger'] = $this->share(function (Pimple $container) {
         $logger = new $container['logger.class']($container['logger.name']);
         $logger->pushHandler($container['logger.handler']);
         return $logger;
     });
     $this['default.configuration'] = array('ffmpeg.threads' => 4, 'ffmpeg.ffmpeg.timeout' => 3600, 'ffmpeg.ffprobe.timeout' => 60, 'ffmpeg.ffmpeg.binaries' => null, 'ffmpeg.ffprobe.binaries' => null, 'imagine.driver' => null, 'gs.timeout' => 60, 'gs.binaries' => null, 'mp4box.timeout' => 60, 'mp4box.binaries' => null, 'swftools.timeout' => 60, 'swftools.pdf2swf.binaries' => null, 'swftools.swfrender.binaries' => null, 'swftools.swfextract.binaries' => null, 'unoconv.binaries' => null, 'unoconv.timeout' => 60);
     $this['configuration'] = array();
     $this['configuration.merged'] = $this->share(function (Pimple $container) {
         return array_replace($container['default.configuration'], $container['configuration']);
     });
     $this['ffmpeg.ffmpeg'] = $this->share(function (Pimple $container) {
         try {
             return FFMpeg::create(array_filter(array('ffmpeg.threads' => $container['configuration.merged']['ffmpeg.threads'], 'timeout' => $container['configuration.merged']['ffmpeg.ffmpeg.timeout'], 'ffmpeg.binaries' => $container['configuration.merged']['ffmpeg.ffmpeg.binaries'])), $container['logger'], $container['ffmpeg.ffprobe']);
         } catch (FFMpegExecutableNotFound $e) {
             throw new RuntimeException('Unable to create FFMpeg driver', $e->getCode(), $e);
         }
     });
     $this['ffmpeg.ffprobe.cache'] = $this->share(function (Pimple $container) {
         return new ArrayCache();
     });
     $this['ffmpeg.ffprobe'] = $this->share(function (Pimple $container) {
         try {
             return FFProbe::create(array_filter(array('timeout' => $container['configuration.merged']['ffmpeg.ffprobe.timeout'], 'ffprobe.binaries' => $container['configuration.merged']['ffmpeg.ffprobe.binaries'])), $container['logger'], $container['ffmpeg.ffprobe.cache']);
         } catch (FFMpegExecutableNotFound $e) {
             throw new RuntimeException('Unable to create FFProbe driver', $e->getCode(), $e);
         }
     });
     $this['imagine'] = $this->share(function (Pimple $container) {
         $driver = $container['configuration.merged']['imagine.driver'];
         switch (true) {
             case 'imagick' === strtolower($driver):
             case null === $driver && class_exists('Imagick'):
                 $driver = 'Imagine\\Imagick\\Imagine';
                 break;
             case 'gmagick' === strtolower($driver):
             case null === $driver && class_exists('Gmagick'):
                 $driver = 'Imagine\\Gmagick\\Imagine';
                 break;
             case 'gd' === strtolower($driver):
             case null === $driver && extension_loaded('gd'):
                 $driver = 'Imagine\\Gd\\Imagine';
                 break;
         }
         if (false === class_exists($driver) || false === in_array('Imagine\\Image\\ImagineInterface', class_implements($driver))) {
             throw new InvalidArgumentException(sprintf('Invalid Imagine driver %s', $driver));
         }
         return new $driver();
     });
     $this['swftools.driver-container'] = $this->share(function (Pimple $container) {
         return DriverContainer::create(array_filter(array('pdf2swf.binaries' => $container['configuration.merged']['swftools.pdf2swf.binaries'], 'swfrender.binaries' => $container['configuration.merged']['swftools.swfrender.binaries'], 'swfextract.binaries' => $container['configuration.merged']['swftools.swfextract.binaries'], 'timeout' => $container['configuration.merged']['swftools.timeout'])), $container['logger']);
     });
     $this['swftools.flash-file'] = $this->share(function (Pimple $container) {
         return new FlashFile($container['swftools.driver-container']);
     });
     $this['swftools.pdf-file'] = $this->share(function (Pimple $container) {
         return new PDFFile($container['swftools.driver-container']);
     });
     $this['unoconv'] = $this->share(function (Pimple $container) {
         try {
             return Unoconv::create(array_filter(array('unoconv.binaries' => $container['configuration.merged']['unoconv.binaries'], 'timeout' => $container['configuration.merged']['unoconv.timeout'])), $container['logger']);
         } catch (ExecutableNotFoundException $e) {
             throw new RuntimeException('Unable to create Unoconv driver', $e->getCode(), $e);
         }
     });
     $this['exiftool.exiftool'] = $this->share(function (Pimple $container) {
         return new Exiftool($container['logger']);
     });
     $this['exiftool.rdf-parser'] = $this->share(function (Pimple $container) {
         return new RDFParser();
     });
     $this['exiftool.reader'] = $this->share(function (Pimple $container) {
         return new Reader($container['exiftool.exiftool'], $container['exiftool.rdf-parser']);
     });
     $this['exiftool.writer'] = $this->share(function (Pimple $container) {
         return new Writer($container['exiftool.exiftool']);
     });
     $this['exiftool.preview-extractor'] = $this->share(function (Pimple $container) {
         return new PreviewExtractor($container['exiftool.exiftool']);
     });
     $this['ghostscript.transcoder'] = $this->share(function (Pimple $container) {
         try {
             return Transcoder::create(array_filter(array('gs.binaries' => $container['configuration.merged']['gs.binaries'], 'timeout' => $container['configuration.merged']['gs.timeout'])), $container['logger']);
         } catch (ExecutableNotFoundException $e) {
             throw new RuntimeException('Unable to create Unoconv driver', $e->getCode(), $e);
         }
     });
     $this['mp4box'] = $this->share(function (Pimple $container) {
         try {
             return MP4Box::create(array_filter(array('mp4box.binaries' => $container['configuration.merged']['mp4box.binaries'], 'timeout' => $container['configuration.merged']['mp4box.timeout'])));
         } catch (ExecutableNotFoundException $e) {
             throw new RuntimeException('Unable to create Unoconv driver', $e->getCode(), $e);
         }
     });
     $this['mediavorus'] = $this->share(function (Pimple $container) {
         $ffprobe = null;
         try {
             $ffprobe = $container['ffmpeg.ffprobe'];
         } catch (RuntimeException $e) {
         }
         return new MediaVorus($container['exiftool.reader'], $container['exiftool.writer'], $ffprobe);
     });
 }
Beispiel #22
0
 public function testProbeOnRemoteFile()
 {
     $ffprobe = FFProbe::create();
     $this->assertGreaterThan(0, count($ffprobe->streams('http://video-js.zencoder.com/oceans-clip.mp4')));
 }