Question

I am using php ffmpeg in a laravel project, to do multiple things probe, extract frame and encode. I am having an issue when creating a frame from the uploaded video file. This is how the frame is created:

    $video = $ffmpeg->open($destinationPath.'/'.$filename);

    $video
        ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10))
        ->save(public_path().$frame_path);

This is sometimes working and creates the frame but other times is not. I noticed that this bug comes up when I am trying to open a .mov file.

Was it helpful?

Solution

It's possible that your version of ffmpeg does not support the codec that is used in the source video file, and hence it is not able to decompress the video and extract an image.

You could try processing the file from the command line to see if you can extract an image that way, and ffmpeg may give you some more information on the problem.

An example command line to extract a png frame from a video file

ffmpeg -y -ss 30 -i [source_file] -vframes 1 [target_file]

Add -f image2 as an output option if your output name is a variable.

OTHER TIPS

The PHP-FFMpeg library appends the -ss argument by default before the input file which requires the timestamp to be accurate in order to obtain the frame. I encountered this problem in case of mkv file. Files such as mkv and mov can not be accurately seeked.

https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Media/Frame.php#L79

You need to pass true as the second argument to the save function in order to give a Frame closest to the given point. It changes the position of -ss argument in ffmpeg command.

-ss position (input/output)

When used as an input option (before -i), seeks in this input file to position. Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it will be preserved.

When used as an output option (before an output filename), decodes but discards input until the timestamps reach position.

position must be a time duration specification, see (ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual.

Here is the code I've been using with PHP:

https://totaldev.com/extract-image-frame-video-php-ffmpeg/

<?php

// Full path to ffmpeg (make sure this binary has execute permission for PHP)
$ffmpeg = "/full/path/to/ffmpeg";

// Full path to the video file
$videoFile = "/full/path/to/video.mp4";

// Full path to output image file (make sure the containing folder has write permissions!)
$imgOut = "/full/path/to/frame.jpg";

// Number of seconds into the video to extract the frame
$second = 0;

// Setup the command to get the frame image
$cmd = $ffmpeg." -i \"".$videoFile."\" -an -ss ".$second.".001 -y -f mjpeg \"".$imgOut."\" 2>&1";

// Get any feedback from the command
$feedback = `$cmd`;

// Use $imgOut (the extracted frame) however you need to 
// ... 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top