FFmpegPHP gets thumbnail of external URL

I am trying to create thumbnails from external videos, mainly MP4 and FLV. I am using FFmpegPHP . I already have work on thumbnails, but I need to upload the video on my server first. Will it be possible to transfer only a small part of the video, and then extract the thumbnail from it?

Here is the code that I still have:

require_once PRIV . 'Vendor/FFmpegPHP/FFmpegAutoloader.php'; // Download the whole video. $video = file_get_contents($_PUT['video']); $file = 'path_to_cache'; file_put_contents($file, $video); $movie = new FFmpegMovie($file); // Generate the thumbnail. $thumb = $movie->getFrame($movie->getFrameCount() / 2); $thumb->resize(320, 240); imagejpeg($thumb->toGDImage(), 'path_to_thumb'); 

Anyone have a suggestion?

EDIT

As Brad suggested, here is the updated code:

 $file = CACHE . 'moodboard_video_' . rand(); $fh = fopen($file, 'w'); $size = 0; curl_setopt($ch, CURLOPT_URL, $_PUT['video']); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) use($fh, &$size){ $length = fwrite($fh, $data); if($length === FALSE) { return 0; } else { $size += $length; } // Downloads 1MB. return $size < 1024 * 1024 * XXXXXX ? $length : 0; }); curl_exec($ch); fclose($fh); curl_close($ch); // Create the thumbnail. $thumb = $movie->getFrame(XXXXXX); $thumb->resize(static::DEFAULT_THUMBNAIL_WIDTH, $thumb->getHeight() / $thumb->getWidth() * static::DEFAULT_THUMBNAIL_WIDTH); $image = $thumb->toGDImage(); imagejpeg($image, PRIV . static::THUMBNAILS_PATH . $item->getLastInsertIdentifier() . '_' . static::DEFAULT_THUMBNAIL_WIDTH); 
+6
source share
2 answers

FFMPEG is very good at dealing with broken threads. Because of this, I think you should try downloading the first few megabytes of this remote media and try to get a thumbnail from an incomplete file.

First remove file_get_contents() and use cURL. You can set the CURLOPT_WRITEFUNCTION option to a user-defined function that writes to a temporary file on disk, piece by piece. When you have received enough data, return 0 from your function, and cURL will stop loading. You need to experiment to find out what the optimal size is. If you have too little data, you will have only the earliest scope for work or no frames at all. Too late and you lose bandwidth.

For some types of containers, file information is at the end of the file. For them, I have no suggestion for you. With the exception of writing my own decoder and splicing information at the end with something from the very beginning, I don’t know how to do this without downloading the whole file.

+3
source

code works with PHP 5, ffmpeg and CURL with a class-based structure:

 require_once 'PHP_CURFN/ffmpeg-php-master/FFmpegFrame.php'; require_once 'PHP_CURFN/ffmpeg-php-master/FFmpegAutoloader.php'; class MyVideoTest{ private $fh=""; private $size=0; private $ch=""; public function __construct(){ $video = 'http://[hosturl]/video/41a669911fd635167475d7530bffcc9f.mp4'; $file = 'PHP_CURFN/cache/tmp_video_' . rand(); $this->ch = curl_init(); $this->fh = fopen ($file, 'w+'); $this->ch = curl_init($video); $this->size = 0; curl_setopt($this->ch, CURLOPT_URL, $video); curl_setopt($this->ch, CURLOPT_HEADER, 0); curl_setopt($this->ch, CURLOPT_WRITEFUNCTION, array($this, "myfunction")); curl_exec($this->ch); fclose($this->fh); curl_close($this->ch); $movie = new FFmpegMovie($file); // Create the thumbnail. $thumb = $movie->getFrame(2); $thumb->resize(320, 240); $image = $thumb->toGDImage(); imagejpeg($image, 'PHP_CURFN/cache' . $item->getLastInsertIdentifier() . '_' . 320); } function myfunction($ch, $data) { $length = fwrite($this->fh, $data); $size=&$this->size; if($length === FALSE) { return 0; } else { $size += $length; } // Downloads 1MB. return $size < 1024 * 1024 *1 ? $length : 0; } } $MyVideoTest= new MyVideoTest(); pr($MyVideoTest); exit; 
0
source

Source: https://habr.com/ru/post/926393/


All Articles