51

Is there a way in PHP given a video file (.mov, .mp4) to generate a thumbnail image preview?

Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
JD Isaacks
  • 56,088
  • 93
  • 276
  • 422

3 Answers3

57

Solution #1 (Older) (not recommended)

Firstly install ffmpeg-php project (http://ffmpeg-php.sourceforge.net/)

And then you can use of this simple code:

<?php
$frame = 10;
$movie = 'test.mp4';
$thumbnail = 'thumbnail.png';

$mov = new ffmpeg_movie($movie);
$frame = $mov->getFrame($frame);
if ($frame) {
    $gd_image = $frame->toGDImage();
    if ($gd_image) {
        imagepng($gd_image, $thumbnail);
        imagedestroy($gd_image);
        echo '<img src="'.$thumbnail.'">';
    }
}
?>

Description: This project use binary extension .so file, It's very old and last update was for 2008. So, maybe don't works with newer version of FFMpeg or PHP.


Solution #2 (Update 2018) (recommended)

Firstly install PHP-FFMpeg project (https://github.com/PHP-FFMpeg/PHP-FFMpeg)
(just run for install: composer require php-ffmpeg/php-ffmpeg)

And then you can use of this simple code:

<?php
require 'vendor/autoload.php';

$sec = 10;
$movie = 'test.mp4';
$thumbnail = 'thumbnail.png';

$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open($movie);
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($sec));
$frame->save($thumbnail);
echo '<img src="'.$thumbnail.'">';

Description: It's newer and more modern project and works with latest version of FFMpeg and PHP. Note that it's required to proc_open() PHP function.

Nabi K.A.Z.
  • 9,887
  • 6
  • 59
  • 81
  • 4
    The API has changed and this answer needs an update ;) – tobias47n9e Dec 18 '17 at 10:53
  • @tobias47n9e I checked again, but the old url well works! and also the API not changed (last update of project was for 2008) anyway I added new better solution. – Nabi K.A.Z. Jun 14 '18 at 00:52
  • Remember: This library requires a working FFMpeg install. You will need both FFMpeg and FFProbe binaries to use it. (My hoster does not allow installation of own binaries.) – Sarah Trees Jun 14 '18 at 15:35
  • 1
    @SarahTrees Sure. Try to upload binary ffmpeg and config with `FFMpeg\FFMpeg::create(array( 'ffmpeg.binaries' => '/opt/local/ffmpeg/bin/ffmpeg', 'ffprobe.binaries' => '/opt/local/ffmpeg/bin/ffprobe',` maybe works. – Nabi K.A.Z. Jun 14 '18 at 21:31
  • Binaries found on https://www.ffmpeg.org/download.html for Windows, Linux, OS X ... – Sarah Trees Jun 20 '18 at 08:02
  • I am facing this error, Can anyone help `Fatal error: Uncaught exception 'Alchemy\BinaryDriver\Exception\ExecutableNotFoundException' with message 'Executable not found, proposed : avprobe, ffprobe' in D:\Projects\wamp\www\code_build\PHP-FFMpeg-master\src\FFMpeg\Driver\FFProbeDriver.php on line 50` – Sudharshan Nair Sep 19 '18 at 12:36
9

Two ways come to mind:

  • Using a command-line tool like the popular ffmpeg, however you will almost always need an own server (or a very nice server administrator / hosting company) to get that

  • Using the "screenshoot" plugin for the LongTail Video player that allows the creation of manual screenshots that are then sent to a server-side script.

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
1

I recommend php-ffmpeg library.

Extracting image

You can extract a frame at any timecode using the FFMpeg\Media\Video::frame method.

This code returns a FFMpeg\Media\Frame instance corresponding to the second 42. You can pass any FFMpeg\Coordinate\TimeCode as argument, see dedicated documentation below for more information.

$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42));
$frame->save('image.jpg');

If you want to extract multiple images from the video, you can use the following filter:

$video
    ->filters()
    ->extractMultipleFrames(FFMpeg\Filters\Video\ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, '/path/to/destination/folder/')
    ->synchronize();

$video
    ->save(new FFMpeg\Format\Video\X264(), '/path/to/new/file');

By default, this will save the frames as jpg images.

You are able to override this using setFrameFileType to save the frames in another format:

$frameFileType = 'jpg'; // either 'jpg', 'jpeg' or 'png'
$filter = new ExtractMultipleFramesFilter($frameRate, $destinationFolder);
$filter->setFrameFileType($frameFileType);

$video->addFilter($filter);
hakki
  • 6,181
  • 6
  • 62
  • 106