/** * Extract a frame from a movie file. Valid movie_options are start_time (in seconds), * input_args (extra ffmpeg input args) and output_args (extra ffmpeg output args). Extra args * are added at the end of the list, so they can override any prior args. * * @param string $input_file * @param string $output_file * @param array $movie_options (optional) */ static function extract_frame($input_file, $output_file, $movie_options = null) { $ffmpeg = movie::find_ffmpeg(); if (empty($ffmpeg)) { throw new Exception("@todo MISSING_FFMPEG"); } list($width, $height, $mime_type, $extension, $duration) = movie::get_file_metadata($input_file); if (isset($movie_options["start_time"]) && is_numeric($movie_options["start_time"])) { $start_time = max(0, $movie_options["start_time"]); // ensure it's non-negative } else { $start_time = module::get_var("gallery", "movie_extract_frame_time", 3); // use default } // extract frame at start_time, unless movie is too short $start_time_arg = $duration >= $start_time + 0.1 ? "-ss " . movie::seconds_to_hhmmssdd($start_time) : ""; $input_args = isset($movie_options["input_args"]) ? $movie_options["input_args"] : ""; $output_args = isset($movie_options["output_args"]) ? $movie_options["output_args"] : ""; $cmd = escapeshellcmd($ffmpeg) . " {$input_args} -i " . escapeshellarg($input_file) . " -an {$start_time_arg} -an -r 1 -vframes 1" . " -s {$width}x{$height}" . " -y -f mjpeg {$output_args} " . escapeshellarg($output_file) . " 2>&1"; exec($cmd, $exec_output, $exec_return); clearstatcache(); // use $filename parameter when PHP_version is 5.3+ if (filesize($output_file) == 0 || $exec_return) { // Maybe the movie needs the "-threads 1" argument added // (see http://sourceforge.net/apps/trac/gallery/ticket/1924) $cmd = escapeshellcmd($ffmpeg) . " -threads 1 {$input_args} -i " . escapeshellarg($input_file) . " -an {$start_time_arg} -an -r 1 -vframes 1" . " -s {$width}x{$height}" . " -y -f mjpeg {$output_args} " . escapeshellarg($output_file) . " 2>&1"; exec($cmd, $exec_output, $exec_return); clearstatcache(); if (filesize($output_file) == 0 || $exec_return) { throw new Exception("@todo FFMPEG_FAILED"); } } }
public function seconds_to_hhmmssdd_test() { $times = array("00:00:00.50" => 0.5, "00:00:06.00" => 6, "00:00:59.99" => 59.999, "00:01:00.00" => 60.001, "00:07:00.00" => 7 * 60, "00:45:19.00" => 45 * 60 + 19, "03:45:19.00" => 3 * 3600 + 45 * 60 + 19, "126:45:19.00" => 126 * 3600 + 45 * 60 + 19); foreach ($times as $hhmmssdd => $seconds) { $this->assert_equal($hhmmssdd, movie::seconds_to_hhmmssdd($seconds)); } }