From a3a986638d846d6b0891da4760e2c8fed13cdda1 Mon Sep 17 00:00:00 2001 From: asonix Date: Mon, 19 Jun 2023 14:25:22 -0500 Subject: [PATCH] Improve gif handling. - Allow a fast-path exif cleaning if we'd re-encode a gif to a gif - Use single-frame palettes to better map transparency from frame to frame Unrelated: - decrease ffmpeg logging when creating thumbnails --- src/ffmpeg.rs | 17 ++++++++++++++++- src/validate.rs | 21 +++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/ffmpeg.rs b/src/ffmpeg.rs index 0e9693a..68b54b2 100644 --- a/src/ffmpeg.rs +++ b/src/ffmpeg.rs @@ -50,6 +50,13 @@ impl TranscodeOptions { } } + pub(crate) const fn needs_reencode(&self) -> bool { + !matches!( + (self.input_format, &self.output), + (VideoFormat::Gif, TranscodeOutputOptions::Gif) + ) + } + const fn input_file_extension(&self) -> &'static str { self.input_format.to_file_extension() } @@ -92,10 +99,12 @@ impl TranscodeOptions { match self.output { TranscodeOutputOptions::Gif => Process::run("ffmpeg", &[ "-hide_banner", + "-v", + "warning", "-i", input_path, "-filter_complex", - "[0:v] split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse", + "[0:v] split [a][b]; [a] palettegen=stats_mode=single [p]; [b][p] paletteuse=new=1", "-an", "-f", self.output_ffmpeg_format(), @@ -108,6 +117,8 @@ impl TranscodeOptions { "ffmpeg", &[ "-hide_banner", + "-v", + "warning", "-i", input_path, "-pix_fmt", @@ -129,6 +140,8 @@ impl TranscodeOptions { "ffmpeg", &[ "-hide_banner", + "-v", + "warning", "-i", input_path, "-pix_fmt", @@ -576,6 +589,8 @@ pub(crate) async fn thumbnail( "ffmpeg", &[ "-hide_banner", + "-v", + "warning", "-i", input_file_str, "-frames:v", diff --git a/src/validate.rs b/src/validate.rs index ea80c23..922ba5d 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -59,12 +59,21 @@ pub(crate) async fn validate_bytes( } let transcode_options = TranscodeOptions::new(media, &details, video_format); - Ok(( - transcode_options.output_type(), - Either::right(Either::left(Either::left( - crate::ffmpeg::transcode_bytes(bytes, transcode_options).await?, - ))), - )) + if transcode_options.needs_reencode() { + Ok(( + transcode_options.output_type(), + Either::right(Either::left(Either::left( + crate::ffmpeg::transcode_bytes(bytes, transcode_options).await?, + ))), + )) + } else { + Ok(( + transcode_options.output_type(), + Either::right(Either::right(crate::exiftool::clear_metadata_bytes_read( + bytes, + )?)), + )) + } } (FileFormat::Image(image_format), Some(format)) if image_format != format => Ok(( ValidInputType::from_format(format),