From b8666b56a45c574e00b975cca1f91304de04e074 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 2 Jul 2024 00:25:44 -0400 Subject: [PATCH] Support anamorphic videos --- lib/philomena_media/gif_preview.ex | 7 ++----- lib/philomena_media/processors/webm.ex | 26 +++++++++++++++----------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/philomena_media/gif_preview.ex b/lib/philomena_media/gif_preview.ex index f1c6fce6..fe3f7914 100644 --- a/lib/philomena_media/gif_preview.ex +++ b/lib/philomena_media/gif_preview.ex @@ -17,9 +17,7 @@ defmodule PhilomenaMedia.GifPreview do Generate a GIF preview of the given video input with evenly-spaced sample points. The input should have pre-computed duration `duration`. The `dimensions` - are a `{target_width, target_height}` tuple of the largest dimensions desired, - and the image will be resized to fit inside the box of those dimensions, - preserving aspect ratio. + are a `{target_width, target_height}` tuple. Depending on the input file, this may take a long time to process. @@ -81,8 +79,7 @@ defmodule PhilomenaMedia.GifPreview do "#{concat_input_pads} concat=n=#{num_images}, settb=1/#{target_framerate}, setpts=N [concat]" scale_filter = - "[concat] scale=width=#{target_width}:height=#{target_height}:" <> - "force_original_aspect_ratio=decrease [scale]" + "[concat] scale=width=#{target_width}:height=#{target_height},setsar=1 [scale]" split_filter = "[scale] split [s0][s1]" diff --git a/lib/philomena_media/processors/webm.ex b/lib/philomena_media/processors/webm.ex index ad446645..22c54a6d 100644 --- a/lib/philomena_media/processors/webm.ex +++ b/lib/philomena_media/processors/webm.ex @@ -87,7 +87,7 @@ defmodule PhilomenaMedia.Processors.Webm do cond do thumb_name in [:thumb, :thumb_small, :thumb_tiny] -> - gif = scale_gif(file, duration, target_dimensions) + gif = scale_gif(file, duration, dimensions, target_dimensions) [ {:copy, webm, "#{thumb_name}.webm"}, @@ -104,10 +104,9 @@ defmodule PhilomenaMedia.Processors.Webm do end defp scale_videos(file, dimensions, target_dimensions) do - {width, height} = box_dimensions(dimensions, target_dimensions) + filter = scale_filter(dimensions, target_dimensions) webm = Briefly.create!(extname: ".webm") mp4 = Briefly.create!(extname: ".mp4") - scale_filter = "scale=w=#{width}:h=#{height}" {_output, 0} = System.cmd("ffmpeg", [ @@ -131,7 +130,7 @@ defmodule PhilomenaMedia.Processors.Webm do "-crf", "31", "-vf", - scale_filter, + filter, "-threads", "4", "-max_muxing_queue_size", @@ -152,7 +151,7 @@ defmodule PhilomenaMedia.Processors.Webm do "-b:v", "5M", "-vf", - scale_filter, + filter, "-threads", "4", "-max_muxing_queue_size", @@ -164,9 +163,8 @@ defmodule PhilomenaMedia.Processors.Webm do end defp scale_mp4_only(file, dimensions, target_dimensions) do - {width, height} = box_dimensions(dimensions, target_dimensions) + filter = scale_filter(dimensions, target_dimensions) mp4 = Briefly.create!(extname: ".mp4") - scale_filter = "scale=w=#{width}:h=#{height}" {_output, 0} = System.cmd("ffmpeg", [ @@ -188,7 +186,7 @@ defmodule PhilomenaMedia.Processors.Webm do "-b:v", "5M", "-vf", - scale_filter, + filter, "-threads", "4", "-max_muxing_queue_size", @@ -199,17 +197,23 @@ defmodule PhilomenaMedia.Processors.Webm do mp4 end - defp scale_gif(file, duration, dimensions) do + defp scale_gif(file, duration, dimensions, target_dimensions) do + {width, height} = box_dimensions(dimensions, target_dimensions) gif = Briefly.create!(extname: ".gif") - GifPreview.preview(file, gif, duration, dimensions) + GifPreview.preview(file, gif, duration, {width, height}) gif end + defp scale_filter(dimensions, target_dimensions) do + {width, height} = box_dimensions(dimensions, target_dimensions) + "scale=w=#{width}:h=#{height},setsar=1" + end + # x264 requires image dimensions to be a multiple of 2 # -2 = ~1 - def box_dimensions({width, height}, {target_width, target_height}) do + defp box_dimensions({width, height}, {target_width, target_height}) do ratio = min(target_width / width, target_height / height) new_width = min(max(trunc(width * ratio) &&& -2, 2), target_width) new_height = min(max(trunc(height * ratio) &&& -2, 2), target_height)