2010-04-07 75 views
6

我試圖從使用FFMPEG和FFMPEG-PHP擴展的電影中的隨機點生成縮略圖。使用PHP + FFMPEG生成隨機縮略圖

我的腳本工作正常..但需要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內的任何內容應該是有效的幀數?然而,循環需要很長時間!

+0

30分鐘?什麼?我會轉換1TB的視頻。 – 2015-03-05 23:31:50

回答

4

你可以從命令行調用ffmpeg,使用-ss開關尋求一個approrpriate開始點(在時間上,而不是在幀數)和-vframes 1告訴它提取恰好是一幀,例如:

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

將從10秒鐘,提取幀,並調用它images/shot_10.jpg

0

我不知道電影格式很多,但由於壓縮可能依賴於單次增量壓縮參考幀,如果參考幀的位置i沒有定義,這意味着系統必須播放完整的電影以獲得特定的偏移量。通過總是加載來檢查這一點很容易,例如,在偏移量20和幀數除以某個值之間尋找幀。

假設是這種情況,您有一個進一步的問題,就是您設計算法的方式,您需要倒退到開始並向前搜索每個5幀 - 如果您事先生成了偏移量,然後對列表進行排序,ffmpeg可能能夠在一次傳遞中獲取幀。

HTH

C.

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); 
+0

這真的很棒的編碼:) – danielad 2014-12-30 13:19:09

+0

我認爲把if(count(output))的東西放在for循環中會讓隨機值的縮略圖更多嗎? – danielad 2014-12-30 13:25:09

-5

您在循環中寫入了錯誤。

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

可以說for循環運行無限,直到它被打破。如果第一次if語句錯誤,那麼無法訪問$i++,因此循環是無止境的。

您需要將$i++放在for循環的底部,然後執行將是2秒而不是20分鐘。

+0

該行爲是有意的。該循環應該執行直到選擇了五個幀,因此只有在隨機選擇的幀存在時計數纔會增加。 – joequincy 2012-11-24 21:22:06