/** * @param string $filePath * @param int $timeFrame * * @return string */ public function extractImageFromVideo($filePath, $timeFrame = 1) { $pathInfo = pathinfo($filePath); $extractedImagePath = $pathInfo['dirname'] . DIRECTORY_SEPARATOR . time() . $pathInfo['basename'] . '-' . $timeFrame . '.jpg'; $video = $this->ffmpeg->open($filePath); $video->frame(TimeCode::fromSeconds($timeFrame))->save($extractedImagePath); return $extractedImagePath; }
public function convert(string $file, Conversion $conversion = null) : string { $imageFile = pathinfo($file, PATHINFO_DIRNAME) . '/' . pathinfo($file, PATHINFO_FILENAME) . '.jpg'; $ffmpeg = FFMpeg::create(['ffmpeg.binaries' => config('laravel-medialibrary.ffmpeg_binaries'), 'ffprobe.binaries' => config('laravel-medialibrary.ffprobe_binaries')]); $video = $ffmpeg->open($file); $seconds = $conversion ? $conversion->getExtractVideoFrameAtSecond() : 0; $frame = $video->frame(TimeCode::fromSeconds($seconds)); $frame->save($imageFile); return $imageFile; }
/** * 영상에서 snapshot 추출 * * @param string $content media content * @param int $fromSecond 영상에서의 시간(초 단위) * @return string */ public function getSnapshot($content, $fromSecond = 10) { $videoFile = $this->temp->create($content); $imgPathname = $this->temp->getTempPathname(); $video = $this->ffmpeg->open($videoFile->getPathname()); $video->frame(TimeCode::fromSeconds($fromSecond))->save($imgPathname); $imageContent = file_get_contents($imgPathname); $videoFile->destroy(); @unlink($imgPathname); return $imageContent; }
public function testBatchGenerate() { $times = ['00:00:00:01', '00:00:00:11', '00:00:00:21']; foreach ($times as $time) { $timecode = TimeCode::fromString($time); $this->ffmpeg->open('1.mp4')->willReturn($this->video->reveal())->shouldBeCalled(); $this->video->frame($timecode)->willReturn($this->frame->reveal())->shouldBeCalled(); $this->frame->save(str_replace(':', '.', '/' . $time . '.jpg'))->shouldBeCalled(); } $this->videoThumbnailService->batchGenerate('1.mp4', $times, ''); }
/** * 영상에서 snapshot 추출 * * @param string $content media content * @param int $fromSecond 영상에서의 시간(초 단위) * @return string */ public function getSnapshot($content, $fromSecond = 10) { $tmpPathname = $this->temp->getTempPathname(); $tmpImgPathname = $this->temp->getTempPathname(); $this->temp->createFile($tmpPathname, $content); $video = $this->ffmpeg->open($tmpPathname); $video->frame(TimeCode::fromSeconds($fromSecond))->save($tmpImgPathname); $imageContent = file_get_contents($tmpImgPathname); $this->temp->remove($tmpPathname); $this->temp->remove($tmpImgPathname); return $imageContent; }
public function execute(SpecificationInterface $spec, MediaInterface $source, $dest) { if (!$spec instanceof Animation) { throw new SpecNotSupportedException('Imagine Adapter only supports Image specs'); } if ($source->getType() !== MediaInterface::TYPE_VIDEO) { throw new SpecNotSupportedException('Imagine Adapter only supports Images'); } try { $movie = $this->container['ffmpeg.ffmpeg']->open($source->getFile()->getPathname()); $duration = $source->getDuration(); $time = $pas = Max(1, $duration / 11); $files = array(); while (ceil($time) < floor($duration)) { $files[] = $tmpFile = $this->tmpFileManager->createTemporaryFile(self::TMP_FILE_SCOPE, 'ffmpeg', 'jpg'); $frame = $movie->frame(TimeCode::fromSeconds($time)); $frame->filters()->fixDisplayRatio(); $frame->save($tmpFile); $time += $pas; } foreach ($files as $file) { $image = $this->container['imagine']->open($file); if ($spec->getWidth() && $spec->getHeight()) { $box = $this->boxFromSize($spec, $image->getSize()->getWidth(), $image->getSize()->getHeight()); if ($spec->getResizeMode() == Animation::RESIZE_MODE_OUTBOUND) { /* @var $image \Imagine\Gmagick\Image */ $image = $image->thumbnail($box, ImageInterface::THUMBNAIL_OUTBOUND); } else { $image = $image->resize($box); } } $image->save($file, array('quality' => $spec->getQuality(), 'resolution-units' => $spec->getResolutionUnit(), 'resolution-x' => $spec->getResolutionX(), 'resolution-y' => $spec->getResolutionY())); unset($image); } $image = $this->container['imagine']->open(array_shift($files)); foreach ($files as $file) { $image->layers()->add($this->container['imagine']->open($file)); } $image->save($dest, array('animated' => true, 'animated.delay' => 800, 'animated.loops' => 0)); $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); } catch (FFMpegException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw new RuntimeException('Unable to transmute video to animation due to FFMpeg', null, $e); } catch (ImagineException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw new RuntimeException('Unable to transmute video to animation due to Imagine', null, $e); } catch (RuntimeException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw $e; } return $this; }
/** * 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; }
/** * {@inheritdoc} */ public function generate($file, $time, $destination) { $destination = $this->normalizeFilename($destination); try { $video = $this->ffmpeg->open($file); $timecode = TimeCode::fromString($time); $frame = $video->frame($timecode); $frame->save($destination); } catch (InvalidArgumentException $e) { // there will be no image file - so nothing to do here } return file_exists($destination); }
public function start($params) { exec("pgrep ffmpeg", $pids); if (empty($pids)) { $query = "SELECT video.guid FROM video LEFT JOIN file ON video.video_guid=file.guid WHERE (video.processed != 'true' && video.processed != 'processing' && video.video_type = 'upload');"; $results = Dbase::getResultsArray($query); foreach ($results as $result) { $video_guid = $result['guid']; $video = getEntity($video_guid, true); if (is_a($video, "SocialApparatus\\Video")) { $file_guid = $video->video_guid; if (!file_exists(SITEDATAPATH . "videos/{$file_guid}/video.mp4")) { $file = getEntity($file_guid, true); FileSystem::makePath(SITEDATAPATH . "videos/" . $file_guid, 0777); $file_location = $file->file_location; exec("pgrep ffmpeg", $pids); if (empty($pids)) { if (file_exists($file_location)) { $target_dir = SITEDATAPATH . "videos/" . $file->guid . "/"; ini_set('max_execution_time', 3000); $ffmpeg = \FFMpeg\FFMpeg::create(array('ffmpeg.binaries' => Setting::get("ffmpeg_ffmprobe_executable_path") . "/ffmpeg", 'ffprobe.binaries' => Setting::get("ffmpeg_ffmprobe_executable_path") . "/ffprobe", 'timeout' => 7200, 'ffmpeg.threads' => 6)); $oldmask = umask(0); $video->proccessed = "processing"; $video->save(); $video_file = $ffmpeg->open($file_location); $video_file->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds(10))->save($target_dir . 'frame.jpg'); $video_file->filters()->resize(new \FFMpeg\Coordinate\Dimension(320, 240))->synchronize(); $video_file->save(new \FFMpeg\Format\Video\X264('libfdk_aac', 'libx264'), $target_dir . 'video.mp4')->save(new \FFMpeg\Format\Video\WebM(), $target_dir . 'video.webm')->save(new \FFMpeg\Format\Video\Ogg(), $target_dir . 'video.ogv'); $video = getEntity($video_guid); $video->processed = "true"; $video->save(); umask($oldmask); $user_guid = $video->owner_guid; $message = "Your video has been processed."; $link = $video->getURL(); notifyUser("video_processed", $video->guid, NULL, $user_guid); continue; } else { $video->processed = "true"; $video->save(); } } } else { $video->processed = "true"; $video->save(); } } } } }
/** * {@inheritdoc} */ public function extract($filename, Specification $targetFormat) { if (!file_exists($filename)) { return null; } $imageFilename = null; try { $filesystem = new Filesystem(); if (!$filesystem->exists($this->tempDir)) { $filesystem->mkdir($this->tempDir); } $imageFilename = $this->tempDir . '/' . uniqid() . '.jpg'; $this->converter->open($filename)->frame(TimeCode::fromSeconds(3))->save($imageFilename); } catch (\Exception $e) { $imageFilename = null; } return $imageFilename; }
public function execute(SpecificationInterface $spec, MediaInterface $source, $dest) { if (!$spec instanceof Image) { throw new SpecNotSupportedException('FFMpeg Adapter only supports Video specs'); } /* @var $spec \MediaAlchemyst\Specification\Image */ $tmpDest = $this->tmpFileManager->createTemporaryFile(self::TMP_FILE_SCOPE, 'ffmpeg', 'jpg'); $time = (int) ($source->getDuration() * $this->parseTimeAsRatio(static::$time)); try { $frame = $this->container['ffmpeg.ffmpeg']->open($source->getFile()->getPathname())->frame(TimeCode::fromSeconds($time)); $frame->filters()->fixDisplayRatio(); $frame->save($tmpDest); $image = $this->container['imagine']->open($tmpDest); if ($spec->getWidth() && $spec->getHeight()) { $box = $this->boxFromSize($spec, $image->getSize()->getWidth(), $image->getSize()->getHeight()); if ($spec->getResizeMode() == Image::RESIZE_MODE_OUTBOUND) { /* @var $image \Imagine\Gmagick\Image */ $image = $image->thumbnail($box, ImageInterface::THUMBNAIL_OUTBOUND); } else { $image = $image->resize($box); } } $options = array('quality' => $spec->getQuality(), 'resolution-units' => $spec->getResolutionUnit(), 'resolution-x' => $spec->getResolutionX(), 'resolution-y' => $spec->getResolutionY()); $image->save($dest, $options); $image = null; $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); } catch (FFMpegException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw new RuntimeException('Unable to transmute video to image due to FFMpeg', null, $e); } catch (ImagineException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw new RuntimeException('Unable to transmute video to image due to Imagine', null, $e); } catch (MediaVorusException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw new RuntimeException('Unable to transmute video to image due to Mediavorus', null, $e); } catch (RuntimeException $e) { $this->tmpFileManager->clean(self::TMP_FILE_SCOPE); throw $e; } }
/** * Create Thumbnail Image * * Create a new image from video source based on the specified parameters. * This method will allows video to convert to image. * This method will add watermark to image * * * @access public * @since Method available since Release 1.0.0 * @param video_path Video resource source path * @param storage_path Image resource destination path * @param thumbnail_name Image name for output * @param height [optional] * @param width [optional] * @param tts Time to take screenshot [optional] * @param water_mark Thmbnail paly button image [optional] * @param wm if true the only it inserts play button [optional] * @author lakshmajim <*****@*****.**> * @return boolean */ public function getThumbnail($video_path, $storage_path, $thumnail_name, $height = 320, $width = 240, $tts = 50, $water_mark = '', $wm = false) { try { $ffmpeg = FFMpeg::create(); $video = $ffmpeg->open($video_path); $result_image = $storage_path . '/' . $thumnail_name; $video->filters()->resize(new Coordinate\Dimension($height, $width))->synchronize(); //320, 240 $video->frame(Coordinate\TimeCode::fromSeconds($tts))->save($result_image); if ($video) { if ($wm) { $src = imagecreatefrompng($water_mark); $got_image = imagecreatefromjpeg($result_image); // Get dimensions of image screen shot $width = imagesx($got_image); $height = imagesy($got_image); // final output image dimensions $newwidth = env('THUMBNAIL_IMAGE_WIDTH'); $newheight = env('THUMBNAIL_IMAGE_HEIGHT'); $tmp = imagecreatetruecolor($newwidth, $newheight); imagecopyresampled($tmp, $got_image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); // Set the brush imagesetbrush($tmp, $src); // Draw a couple of brushes, each overlaying each imageline($tmp, imagesx($tmp) / 2, imagesy($tmp) / 2, imagesx($tmp) / 2, imagesy($tmp) / 2, IMG_COLOR_BRUSHED); imagejpeg($tmp, $result_image, 100); } return true; } else { return false; } } catch (Exception $thumbnailException) { // error processing request echo "Got Bad Cookie"; } }
/** * @return \Image */ public function getSourceImage() { $image = new Image(); $video = $this->getFile(); $videoPath = $video->getFullPath(); if (!$video instanceof File) { throw new UploadField_BadFileTypeException(); } try { $video = $this->openVideo($videoPath); } catch (\FFMpeg\Exception\RuntimeException $e) { return $image; } $frame = $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds(10)); // Save the frame as a JPEG and create a file around it list($label, $extension) = explode('.', basename($videoPath)); $frameFile = '/' . $label . '.jpg'; // Absolute path needed for saving of the source image $frame->save(ASSETS_PATH . $frameFile); // Relative path needed for the file object $image->Filename = ASSETS_DIR . $frameFile; $image->write(); return $image; }
public function scaleImage($asset, $width, $height = null) { list($type, $subtype) = explode('/', $asset->mimeType()); switch ($type) { case "video": $workdir = '/tmp/repose/'; $ffmpeg = FFMpeg::create(array('ffmpeg.binaries' => '/usr/bin/ffmpeg', 'ffprobe.binaries' => '/usr/bin/ffprobe', 'timeout' => 3600, 'ffmpeg.threads' => 12)); $video = $ffmpeg->open($this->real_root()); $video->frame(TimeCode::fromSeconds(5))->save($workdir . DS . $asset->uuid() . '.jpg'); $data = file_get_contents($workdir . DS . $asset->uuid() . '.jpg'); $img = imagecreatefromstring($data); if (FALSE !== $img) { return self::scaleJpeg($img, $width, $height); } break; case "image": if ($subtype === 'png') { $img = imagecreatefromstring($this->content); if (FALSE !== $img) { return self::scalePng($img, $width, $height); } } elseif ($subtype === 'jpeg') { $img = imagecreatefromstring($this->content); if (FALSE !== $img) { return self::scaleJpeg($img, $width, $height); } } elseif ($subtype === 'gif') { $img = imagecreatefromstring($this->content); if (FALSE !== $img) { return self::scaleGif($img, $width, $height); } } } var_dump('Failed to load image data: ' . $asset->filename); return FALSE; }
public function createAvatar($entity = false, $filename = false, $copy = false) { $target_dir = getDataPath() . "videos" . "/" . $this->video_guid . "/"; $file_entity = getEntity($this->video_guid); makePath($target_dir, 0777); $ffmpeg = \FFMpeg\FFMpeg::create(array('ffmpeg.binaries' => Setting::get("ffmpeg_ffmprobe_executable_path") . "/ffmpeg", 'ffprobe.binaries' => Setting::get("ffmpeg_ffmprobe_executable_path") . "/ffprobe", 'timeout' => 7200, 'ffmpeg.threads' => 6)); $file_location = $file_entity->file_location; $video = $ffmpeg->open($file_location); $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds(2))->save($target_dir . 'frame.jpg'); }
/** * {@inheritdoc} */ public function getReferenceFile(MediaInterface $media) { $key = $this->generatePrivateUrl($media, 'reference'); // the reference file is a movie, create an image from frame and store it with the reference format if ($this->getFilesystem()->has($key)) { $referenceFile = $this->getFilesystem()->get($key); } else { $dir = $this->getFilesystem()->getAdapter()->getDirectory(); $movie_path = sprintf('%s/%s/%s', $dir, $this->generatePath($media), $media->getProviderReference()); $reference_path = sprintf('%s/%s', $dir, $key); /* $ffmpeg = \FFMpeg\FFMpeg::create(); */ $ffmpeg = $this->getFFMpeg(); $video = $ffmpeg->open($movie_path); $seconds = isset($this->ffmpegConfig['ffmpeg.frame.seconds']) ? $this->ffmpegConfig['ffmpeg.frame.seconds'] : 1; $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds($seconds))->save($reference_path); $referenceFile = $this->getFilesystem()->get($key); } return $referenceFile; }
/** * @param string $file * @param int $size * @return null|string */ public function createVideoIcon($file, $size = 100) { if (!class_exists('FFMpeg\\FFMpeg')) { return null; } try { $preview = tempnam(sys_get_temp_dir(), 'preview-'); $ffmpeg = FFMpeg::create(); $video = $ffmpeg->open($file); $frame = $video->frame(TimeCode::fromString('0:0:0:0.0')); $frame->save($preview); $content = $this->createImageIcon($preview, $size); @unlink($preview); return $content; } catch (\Exception $e) { return null; } }
private function getTimeCode(TimeCode $timeCode, $seconds) { $this->timecode = $timeCode->fromSeconds($seconds); }
/** * @dataProvider provideSeconds */ public function testFromSeconds($seconds, $expected) { $tc = TimeCode::fromSeconds($seconds); $this->assertEquals($expected, (string) $tc); }
/** * @ORM\PostPersist() * @ORM\PostUpdate() */ public function upload() { // Si jamais il n'y a pas de fichier (champ facultatif) if (null === $this->file) { return; } // Si on avait un ancien fichier, on le supprime if (null !== $this->tempFilename) { $oldFile = $this->getUploadRootDir() . '/' . $this->id . '.' . $this->tempFilename; if (file_exists($oldFile)) { unlink($oldFile); } } // On déplace le fichier envoyé dans le répertoire de notre choix $this->file->move($this->getUploadRootDir(), $this->id . '.' . $this->extension); //here we will convert the video to mp4 and webm and save the thumbnail. //this is the code to convert the file we receive into mp4. We need to change to accept all file sizes. $ffmpeg = FFMpeg::create(array('ffmpeg.binaries' => '/home/joris/bin/ffmpeg', 'ffprobe.binaries' => '/home/joris/bin/ffprobe', 'timeout' => 3600, 'ffmpeg.threads' => 12)); // Open video $video = $ffmpeg->open($this->getUploadRootDir() . '/' . $this->id . '.' . $this->extension); // Resize to 1280x720 to compact the video ! $video->filters()->resize(new Dimension(1280, 720), ResizeFilter::RESIZEMODE_SCALE_HEIGHT)->synchronize(); $video->frame(TimeCode::fromSeconds(1))->save('/var/www/v.bestfootball.fr/thumbnail/' . $this->name . '.jpg'); // Start transcoding and save video if ($this->extension != 'mp4') { $video->save(new X264(), '/var/www/v.bestfootball.fr/' . $this->name . '.mp4'); unlink($this->getUploadRootDir() . '/' . $this->id . '.' . $this->extension); } else { rename($this->getUploadRootDir() . '/' . $this->id . '.' . $this->extension, '/var/www/v.bestfootball.fr/' . $this->name . '.mp4'); } }
/** * Consume method with retrieved queue value * * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * @param Mixed $payload Data retrieved and unserialized from queue */ protected function consumeVideo(InputInterface $input, OutputInterface $output, $payload) { if (isset($payload['id']) && ($id = $payload['id'])) { /** @var Media $media */ if ($media = $this->getMediaById($id)) { $output->writeln(sprintf('Processing media with ID=%d', $id)); $video = $this->getFFMpeg()->open($this->getProvider($media)->getReferenceFilePath($media)); if ($video->getStreams()->videos()->count() > 0) { $videoParams = $video->getStreams()->videos()->first(); $media->setWidth($videoParams->getDimensions()->getWidth()); $media->setHeight($videoParams->getDimensions()->getHeight()); $screenshotAt = $media->getMetadataValue(VidequeProvider::FIELD_NAME_SCREENSHOT_AT); $duration = intval($video->getFormat()->get('duration')); if ($screenshotAt == 0 || $duration <= $screenshotAt) { if ($video->getFormat()->get('duration') > 0) { $screenshotAt = floatval($video->getFormat()->get('duration')) / 2; } } // reference screenshot $screenshotPath = $this->getProvider($media)->generateThumbPath($media, 'reference'); $output->writeln(sprintf(' Creating screenshot to %s', $screenshotPath)); $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($screenshotAt))->save($screenshotPath); $provider = $this->getProvider($media); $formatList = $provider->getFormats(); try { foreach ($formatList as $format => $params) { if ($format !== 'admin') { $_w = $params['width']; $_h = $params['height']; $ratio = $videoParams->getDimensions()->getRatio(); if ($_w and !$_h) { $_h = $ratio->calculateHeight($_w); } elseif (!$_w and $_h) { $_w = $ratio->calculateWidth($_h); } // resize video $video->filters()->resize(new Dimension($_w, $_h), ResizeFilter::RESIZEMODE_INSET)->synchronize(); $savePath = $this->generatePath($media, $format); $output->writeln(sprintf(' Resizing media according format %s to %dx%s to %s ...', $format, $_w, $_h, $savePath)); //$video->save(new X264($this->getContainer()->getParameter('videque.codec.audio'), $this->getContainer()->getParameter('videque.codec.video')), $savePath); $video->save(new X264SinglePass($this->getContainer()->getParameter('videque.codec.audio'), $this->getContainer()->getParameter('videque.codec.video')), $savePath); // screnshoot generation $screenshotPath = $this->getProvider($media)->generateThumbPath($media, $format); $output->writeln(sprintf(' Creating thumb %dx%s to %s ...', $_w, $_h, $screenshotPath)); $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($screenshotAt))->save($screenshotPath); } } $media->setProviderStatus(MediaInterface::STATUS_OK); $this->saveMedia($media); } catch (\Exception $e) { $this->logger()->error(sprintf('Error occurred during processing media with id=%d: %s', $id, $e->getMessage())); } $output->writeln('Completed.'); $output->writeln(''); } else { $this->logger()->error(sprintf('No video stream found in media with id %d', $id)); } } } }
/** * Get Picture. * * @param int $time * * @return string */ public function getPicture($time = 30) { $duration = $this->video->getStreams()->first()->get('duration'); $this->video->frame(BFFC\TimeCode::fromSeconds($duration * ($time / 100)))->save('/tmp/picture.jpg'); return file_get_contents('/tmp/picture.jpg'); }
public function __construct($config) { $this->start = TimeCode::fromSeconds($config['start']); $this->duration = TimeCode::fromSeconds($config['duration']); }
/** * 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)); } }
/** * @param StoreVideoRequest $request * @param $file_hash */ private function extractVideoFrame(StoreVideoRequest $request, $file_hash) { $ffmpeg = FFMpeg::create(); $video = $ffmpeg->open(base_path() . '/files/video/' . $file_hash . '.' . $request->file('video')->getClientOriginalExtension()); $frame = $video->frame(TimeCode::fromSeconds(5)); $frame->save(base_path() . '/files/video/' . $file_hash . '.jpg'); }
/** * @param int $frameNumber * * @return Frame */ public function getFrame($frameNumber) { return $this->movie->frame(TimeCode::fromSeconds($frameNumber)); }
private function setThumbnails() { $thumbnailsToCreate = ['small', 'large']; // Set the point in the video to extract the frame at approximately 10% of the video length; $frameExtractionPoint = (int) round($this->getLength() / 10); // Open the video and extract a frame at 10% of the video's duration $video = $this->ffmpeg->open($this->directory['full'] . $this->fileinfo['filename']); $frame = $video->frame(TimeCode::fromSeconds($frameExtractionPoint)); // Save frame to temporary location create_if_does_not_exist(public_path($this->directory['frames'])); $frame->save($this->directory['frames'] . $this->fileinfo['filename_without_extension'] . '.jpg'); foreach ($thumbnailsToCreate as $size) { $lengthDimension = $size == 'small' ? $this->smallThumbnailSize : $this->largeThumbnailSize; // create an Imagick instance $image = new \Imagick(public_path($this->directory['frames'] . $this->fileinfo['filename_without_extension'] . '.jpg')); $image->thumbnailImage($lengthDimension, $lengthDimension, true); create_if_does_not_exist(public_path($this->directory[$size])); $image->writeImage(public_path($this->directory[$size] . $this->fileinfo['filename_without_extension'] . '.jpg')); } // Delete the temporary frame unlink($this->directory['frames'] . $this->fileinfo['filename_without_extension'] . '.jpg'); }