Skip to content

Commit 4c8d117

Browse files
committed
This is a much faster way to grab frames from a video. Seeking aftering the -i flag causes the video to load all frames right up to $frameTime. In a large movie file this is extremely slow. Instead, you can seek quickly before the input file is loaded with -i, but this isn't quite as accurate as having the -ss after the -i. But, there's a fast & accurate way to seek ahead, which is to quick-seek to a point close to $frameTime, and then accurately seek from there to $frameTime using a second -ss option. See http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg for a thorough explanation. This makes grabbing frames more than a minute or two into a large movie 100x (or more) faster as it gets progressively slower the further into the video the frame is with -i before -ss.
1 parent 94f6fb5 commit 4c8d117

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

FFmpegMovie.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,11 +675,24 @@ public function getFrameAtTime($seconds = null, $width = null, $height = null, $
675675

676676
$output = array();
677677

678+
// fast and accurate way to seek. First quick-seek before input up to
679+
// a point just before the frame, and then accurately seek after input
680+
// to the exact point.
681+
// See: http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg
682+
if ($frameTime > 30) {
683+
$seek1 = $frameTime - 30;
684+
$seek2 = 30;
685+
} else {
686+
$seek1 = 0;
687+
$seek2 = $frameTime;
688+
}
689+
678690
exec(implode(' ', array(
679691
$this->ffmpegBinary,
692+
'-ss '.$seek1,
680693
'-i '.escapeshellarg($this->movieFile),
681694
'-f image2',
682-
'-ss '.$frameTime,
695+
'-ss '.$seek2,
683696
'-vframes 1',
684697
$image_size,
685698
$quality,
@@ -745,4 +758,4 @@ public function unserialize($serialized) {
745758
) = unserialize($serialized);
746759

747760
}
748-
}
761+
}

0 commit comments

Comments
 (0)