From ce68177ba0dc27010435e55b79cbea453751f8ee Mon Sep 17 00:00:00 2001 From: shadlaws Date: Tue, 18 Dec 2012 15:58:13 +0100 Subject: [#1928 - Make thumbnail generation more flexible for movies (graphics and movie helpers)] - graphics helper: add movie_extract_frame event to generate function (allows modules to add to the options sent to movie::extract_frame or to generate the thumbnail on their own without movie::extract_frame) - movie helper: add extra optional argument to movie::extract_frame (can add ffmpeg arguments and/or change the frame extract time) - gallery_installer: add movie_extract_time module variable, update to v53 - module.info: update to v53 - install.sql: update to v53 --- modules/gallery/helpers/gallery_installer.php | 10 +++++++- modules/gallery/helpers/graphics.php | 26 +++++++++++++++----- modules/gallery/helpers/movie.php | 34 ++++++++++++++++++++------- 3 files changed, 55 insertions(+), 15 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index 1f190800..597771f3 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -313,8 +313,9 @@ class gallery_installer { module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin"); module::set_var("gallery", "timezone", null); module::set_var("gallery", "lock_timeout", 1); + module::set_var("gallery", "movie_extract_frame_time", 3); - module::set_version("gallery", 52); + module::set_version("gallery", 53); } static function upgrade($version) { @@ -735,6 +736,13 @@ class gallery_installer { ->execute(); module::set_version("gallery", $version = 52); } + + if ($version == 52) { + // In v53, we added the ability to change the default time used when extracting frames from + // movies. Previously we hard-coded this at 3 seconds, so we use that as the default. + module::set_var("gallery", "movie_extract_frame_time", 3); + module::set_version("gallery", $version = 53); + } } static function uninstall() { diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index c19fbe6d..c7f87403 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -155,13 +155,27 @@ class graphics_Core { try { foreach ($ops as $target => $output_file) { if ($input_item->is_movie()) { - // Convert the movie to a JPG first + // Convert the movie filename to a JPG first, delete anything that might already be there $output_file = legal_file::change_extension($output_file, "jpg"); - try { - movie::extract_frame($input_file, $output_file); - } catch (Exception $e) { - // Assuming this is MISSING_FFMPEG for now - copy(MODPATH . "gallery/images/missing_movie.jpg", $output_file); + unlink($output_file); + // Run movie_extract_frame events, which can either: + // - generate an output file, bypassing the ffmpeg-based movie::extract_frame + // - add to the options sent to movie::extract_frame (e.g. change frame extract time, + // add de-interlacing arguments to ffmpeg... see movie helper for more info) + // Note that the args are similar to those of the events in gallery_graphics + $movie_options_wrapper = new stdClass(); + $movie_options_wrapper->movie_options = array(); + module::event("movie_extract_frame", $input_file, $output_file, + $movie_options_wrapper, $input_item); + // If no output_file generated by events, run movie::extract_frame with movie_options + clearstatcache(); + if (@filesize($output_file) == 0) { + try { + movie::extract_frame($input_file, $output_file, $movie_options_wrapper->movie_options); + } catch (Exception $e) { + // Didn't work, likely because of MISSING_FFMPEG - copy missing_movie instead + copy(MODPATH . "gallery/images/missing_movie.jpg", $output_file); + } } $working_file = $output_file; } else { diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index ddc513ea..6d70ab2d 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -57,7 +57,16 @@ class movie_Core { return $form; } - static function extract_frame($input_file, $output_file) { + /** + * 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"); @@ -65,23 +74,32 @@ class movie_Core { list($width, $height, $mime_type, $extension, $duration) = movie::get_file_metadata($input_file); - // extract frame at 0:03, unless movie is shorter than 4 sec. - $start_time_arg = ($duration > 4) ? " -ss 00:00:03" : ""; - - $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($input_file) . + if (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 " . date("H:i:s", mktime(0,0,$start_time,0,0,0,0)) : ""; + + $input_args = $movie_options["input_args"] ? $movie_options["input_args"] : ""; + $output_args = $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 " . escapeshellarg($output_file) . " 2>&1"; + " -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 -i " . escapeshellarg($input_file) . + $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 " . escapeshellarg($output_file) . " 2>&1"; + " -y -f mjpeg $output_args " . escapeshellarg($output_file) . " 2>&1"; exec($cmd, $exec_output, $exec_return); clearstatcache(); -- cgit v1.2.3 From 7910084224315b2d26b447381863603ea3e4e649 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Tue, 18 Dec 2012 13:56:28 -0800 Subject: Check for "add" instead of "edit" in item_rest::post. Fixes #1929. --- modules/gallery/helpers/item_rest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php index 14580cd9..43fec3ab 100644 --- a/modules/gallery/helpers/item_rest.php +++ b/modules/gallery/helpers/item_rest.php @@ -150,7 +150,7 @@ class item_rest_Core { static function post($request) { $parent = rest::resolve($request->url); - access::required("edit", $parent); + access::required("add", $parent); $entity = $request->params->entity; $item = ORM::factory("item"); -- cgit v1.2.3 From ff6688b48b2eb083f82d803249f61dc08efb5b92 Mon Sep 17 00:00:00 2001 From: shadlaws Date: Tue, 1 Jan 2013 15:47:04 +0100 Subject: #1919 - change `convert -v` to `convert -version` --- modules/gallery/helpers/graphics.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index c7f87403..bfc0085d 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -335,7 +335,7 @@ class graphics_Core { // ImageMagick & GraphicsMagick $magick_kits = array( "imagemagick" => array( - "name" => "ImageMagick", "binary" => "convert", "version_arg" => "-v", + "name" => "ImageMagick", "binary" => "convert", "version_arg" => "-version", "version_regex" => "/Version: \S+ (\S+)/"), "graphicsmagick" => array( "name" => "GraphicsMagick", "binary" => "gm", "version_arg" => "version", -- cgit v1.2.3 From 9d684b7b83f0aa026e9d6f06228294f179a3bcaa Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 14 Jan 2013 12:52:47 -0500 Subject: Fix up some indentation. --- modules/gallery/helpers/graphics.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'modules/gallery/helpers') diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php index bfc0085d..e7c5da68 100644 --- a/modules/gallery/helpers/graphics.php +++ b/modules/gallery/helpers/graphics.php @@ -166,7 +166,7 @@ class graphics_Core { $movie_options_wrapper = new stdClass(); $movie_options_wrapper->movie_options = array(); module::event("movie_extract_frame", $input_file, $output_file, - $movie_options_wrapper, $input_item); + $movie_options_wrapper, $input_item); // If no output_file generated by events, run movie::extract_frame with movie_options clearstatcache(); if (@filesize($output_file) == 0) { @@ -215,7 +215,7 @@ class graphics_Core { // Something went wrong rebuilding the image. Leave it dirty and move on. // @todo we should handle this better. Kohana_Log::add("error", "Caught exception rebuilding image: {$item->title}\n" . - $e->getMessage() . "\n" . $e->getTraceAsString()); + $e->getMessage() . "\n" . $e->getTraceAsString()); throw $e; } } @@ -274,13 +274,13 @@ class graphics_Core { $count = graphics::find_dirty_images_query()->count_records(); if ($count) { site_status::warning( - t2("One of your photos is out of date. Click here to fix it", - "%count of your photos are out of date. Click here to fix them", - $count, - array("attrs" => html::mark_clean(sprintf( - 'href="%s" class="g-dialog-link"', - url::site("admin/maintenance/start/gallery_task::rebuild_dirty_images?csrf=__CSRF__"))))), - "graphics_dirty"); + t2("One of your photos is out of date. Click here to fix it", + "%count of your photos are out of date. Click here to fix them", + $count, + array("attrs" => html::mark_clean(sprintf( + 'href="%s" class="g-dialog-link"', + url::site("admin/maintenance/start/gallery_task::rebuild_dirty_images?csrf=__CSRF__"))))), + "graphics_dirty"); } } @@ -334,12 +334,12 @@ class graphics_Core { } else { // ImageMagick & GraphicsMagick $magick_kits = array( - "imagemagick" => array( - "name" => "ImageMagick", "binary" => "convert", "version_arg" => "-version", - "version_regex" => "/Version: \S+ (\S+)/"), - "graphicsmagick" => array( - "name" => "GraphicsMagick", "binary" => "gm", "version_arg" => "version", - "version_regex" => "/\S+ (\S+)/")); + "imagemagick" => array( + "name" => "ImageMagick", "binary" => "convert", "version_arg" => "-version", + "version_regex" => "/Version: \S+ (\S+)/"), + "graphicsmagick" => array( + "name" => "GraphicsMagick", "binary" => "gm", "version_arg" => "version", + "version_regex" => "/\S+ (\S+)/")); // Loop through the kits foreach ($magick_kits as $index => $settings) { $path = system::find_binary( -- cgit v1.2.3