我正在尝试从外部视频创建缩略图,主要是MP4和FLV。我正在使用FFmpegPHP。我已经将缩略图生成工作正常,但是,我需要首先在我的服务器上完全加载视频。是否可以只传输视频的一小部分,然后从中提取缩略图?
这是我到目前为止的代码:
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');
有人有建议吗?
修改
正如Brad所说,这是更新后的代码:
$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);
答案 0 :(得分:3)
FFMPEG非常适合处理损坏的流。因此,我认为您应该尝试下载该远程媒体的前几个megs,并尝试从不完整的文件中获取缩略图。
首先,删除file_get_contents()
并使用cURL。您可以将CURLOPT_WRITEFUNCTION
选项设置为您的自定义函数,该函数写入磁盘上的临时文件,按块查看。收到足够的数据后,从函数返回0
,cURL将停止下载。您将不得不进行试验以了解最佳尺寸。如果数据太少,您将只能使用最早的帧,或者根本没有帧。太晚了,你在浪费带宽。
对于某些容器类型,文件信息位于文件末尾。对那些人,我没有你的建议。如果没有编写自己的解码器并在最后用一些东西拼接信息,我不知道如何在不下载整个文件的情况下完成它。
答案 1 :(得分:0)
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;