2012-03-30 187 views
1

我想要從與FFMPEG一個視頻中提取的縮略圖,因此我使用命令行:FFmpeg的視頻縮略圖幀提取

ffmpeg -i video.mp4 -vframes 1 -an -f image2 -y thumbmail.png 2>&1 

但在大多數情況下,第一幀是全黑。 所以,我在做什麼是:

for($i = 1; $i < MAX_FRAME_CHECKING; $i++) 
{ 
    $cmd = sprintf('ffmpeg -i video.mp4 -vframes 1 -an -vf select="eq(n\,%d)"-f image2 -y thumbmail.png 2>&1', $i); 

    @exec($cmd, $aOutput, $iReturnValue); 

    if(self::isGoodKeyFrame('thumbmail.png')) 
    break; 
} 

凡isGoodKeyFrame方法定義爲:

private static function isGoodKeyFrame($sImagePath) 
{ 
    if(class_exists('Imagick')) 
    { 
    $hImagick = new Imagick(); 

    try 
    { 
     if ($hImagick->readImage($sImagePath) && $hImagick->valid()) 
     { 
     $hQuantized = @$hImagick->clone(); 
     $hQuantized->quantizeImage(255, Imagick::COLORSPACE_RGB, 0, TRUE, FALSE); 

     return count($hQuantized->getImageHistogram()) > self::HISTOGRAM_SIZE_THRESHOLD; 
     } 
     else 
     error_log("'$sImagePath' is not a valid image."); 
    } 
    catch(Exception $e) 
    { 
     error_log($e->getMessage()); 
    } 

    $hImagick->clear(); 
    $hImagick->destroy(); 

    } 
    else 
    error_log('Imagick not installed.'); 

    return TRUE; 
} 

所以基本上我在做什麼是捕獲1〜MAX_FRAME_CHECKING幀,檢查其顏色直方圖當我發現顏色比我的最低閾值還要多時,我會打斷循環並返回該幀。

有沒有辦法與ffmpeg本地做到這一點?

謝謝

回答

1

不是我所知道的。我認爲最簡單的解決方案之一是使用-ss命令來尋找一個提取縮略圖的位置。

每ffmpeg的文檔:

「-ss位置(輸入/輸出)」 當作爲(前-I)的輸入選項一起使用,尋求在該輸入文件到位置。當用作輸出選項時(在輸出文件名之前),解碼但丟棄輸入,直到時間戳到達位置。這比較慢,但更準確。

位置可以是在幾秒鐘內或在HH:MM:SS [.XXX]形式。

+0

好吧,我不能肯定,在位置X有一個非黑幀,所以我想我的解決方案是更好的現在:( – 2012-03-30 13:26:09

+0

除非你提取框架,你可以使用一個庫,以檢查在像素圖像來查看它是否全黑,然後如果是,則選擇不同的幀號,否則使用該幀。 – SB2017 2012-07-01 11:41:00