Simone Margaritelli
Simone Margaritelli

Reputation: 4733

FFMpeg video thumbnail frame extraction

i'm trying to extract a thumbnail from a video with ffmpeg, therefore i'm using the command line:

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

But in most cases, the first frame is completely black. So, what i'm doing is :

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;
}

Where the isGoodKeyFrame method is defined as:

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;
}

So basically what i'm doing is capture 1 to MAX_FRAME_CHECKING frames, check their color histogram and when i find something with much colors than my minimum threshold i break the loop and return that frame.

Is there a way to do this natively with ffmpeg ?

Thanks

Upvotes: 1

Views: 2004

Answers (1)

smb
smb

Reputation: 589

Not that I'm aware of. I think that one of the easiest solutions would be to use the -ss command to seek to a position to extract the thumbnail.

Per the ffmpeg documentation:

‘-ss position (input/output)’ When used as an input option (before -i), seeks in this input file to position. When used as an output option (before an output filename), decodes but discards input until the timestamps reach position. This is slower, but more accurate.

position may be either in seconds or in hh:mm:ss[.xxx] form.

Upvotes: 2

Related Questions