使用PHP + FFMPEG生成随机缩略图

时间:2010-04-07 09:18:54

标签: php ffmpeg

我正在尝试使用FFMPEG和FFMPEG-PHP扩展从电影中的随机点生成缩略图。

我的脚本运行正常..但是只需要20分钟就可以生成5-10个缩略图!!

该脚本的工作原理是生成随机数,以后用作帧数。生成的所有数字都在电影帧数内。

你能弄清楚为什么这个剧本需要20分钟才能完成吗? 如果没有,更好的解决方案?

<?php

//Dont' timeout
set_time_limit(0);

//Load the file (This can be any file - still takes ages) 
$mov = new ffmpeg_movie('1486460.mp4');

//Get the total frames within the movie
$total_frames = $mov->getFrameCount();

//Loop 5-10 times to generate random frames 5-10 times
for ($i = 1; $i <= 5; ) {
    // Generate a number within 200 and the total number of frames.
 $frame = mt_rand(200,$total_frames);
 $getframe = $mov->getFrame($frame);
 // Check if the frame exists within the movie
 // If it does, place the frame number inside an array and break the current loop
 if($getframe){
  $frames[$frame] = $getframe ;
  $i++;
 }
}

//For each frame found generate a thumbnail
foreach ($frames as $key => $getframe) {
 $gd_image = $getframe->toGDImage();
 imagejpeg($gd_image, "images/shot_".$key.'.jpeg');
 imagedestroy($gd_image);
 echo $key.'<br/>';
}

?>

脚本应该生成有效的帧号吗? START - END中的任何内容都应该是有效的帧编号?然而,循环需要很长时间!

4 个答案:

答案 0 :(得分:4)

您可以从命令行调用ffmpeg,使用-ss开关寻找适当的起点(及时,而不是帧数)和-vframes 1告诉它准确提取一帧,例如:

ffmpeg -i 1486460.mp4 -ss 10 -vframes 1 images/shot_10.jpg

将从10秒内提取一帧,并将其称为images/shot_10.jpg

答案 1 :(得分:1)

这里的问题是随机这个词。我成功获得了视频的持续时间,然后尝试使用该随机持续时间获得一帧。可以轻松修改更多帧:

    $cmd = "ffmpeg -i {$src} 2>&1 |grep Duration";

    $output = array ();

    exec($cmd, $output);

    if(count($output)) {
        $duration = explode(':', trim(str_replace('Duration:', NULL, current(explode(',', current($output))))));
        list($hour, $min, $sec) = $duration;
        $sec = sprintf("%02d:%02d:%02d", rand(0, $hour), rand(0, $min), rand(0, $sec));
    } else {
        $sec = "00:00:12"; //12sec it's ok :)
    }

    $cmd = "ffmpeg -ss {$sec} -i {$src} -s {$w}x{$h} -f image2 -vframes 1 {$destination}";

    $output = array ();

    exec($cmd, $output);

答案 2 :(得分:0)

我对电影格式知之甚少,但由于压缩可能依赖于带参考帧的单通道增量压缩,如果没有定义参考帧的位置,这意味着系统必须播放获得特定偏移量的完整电影。通过总是加载来检查这一点很容易,比如,在偏移量20和帧数除以某个值之间寻找一个帧。

假设是这种情况,您还有一个问题,就是您设计算法的方式,您需要回退到开始并向前搜索5帧中的每一帧 - 如果您提前生成了偏移量,然后对列表进行排序,ffmpeg可以一次性获取帧。

HTH

下进行。

答案 3 :(得分:-5)

你在循环中写错了。

if($getframe) {
  $frames[$frame] = $getframe;
  $i++;
}

让我们说for循环无限运行直到它被破坏。如果第一次if语句为false,则无法访问$i++,循环就无止境。

您需要将$i++放在for循环的底部,然后执行将是2秒而不是20分钟。