public function testCreateAndDestroy() { $fs = new Tempdir(); $dir = $fs->getPath(); $this->assertTrue(is_dir($dir)); unset($fs); $this->assertTrue(!file_exists($dir)); }
/** * 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); }