Merge pull request #318 from philomena-dev/anamorphic

Support anamorphic videos
This commit is contained in:
liamwhite 2024-07-02 15:14:15 -04:00 committed by GitHub
commit 01da4f4fdb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 16 deletions

View file

@ -17,9 +17,7 @@ defmodule PhilomenaMedia.GifPreview do
Generate a GIF preview of the given video input with evenly-spaced sample points. Generate a GIF preview of the given video input with evenly-spaced sample points.
The input should have pre-computed duration `duration`. The `dimensions` The input should have pre-computed duration `duration`. The `dimensions`
are a `{target_width, target_height}` tuple of the largest dimensions desired, are a `{target_width, target_height}` tuple.
and the image will be resized to fit inside the box of those dimensions,
preserving aspect ratio.
Depending on the input file, this may take a long time to process. 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]" "#{concat_input_pads} concat=n=#{num_images}, settb=1/#{target_framerate}, setpts=N [concat]"
scale_filter = scale_filter =
"[concat] scale=width=#{target_width}:height=#{target_height}:" <> "[concat] scale=width=#{target_width}:height=#{target_height},setsar=1 [scale]"
"force_original_aspect_ratio=decrease [scale]"
split_filter = "[scale] split [s0][s1]" split_filter = "[scale] split [s0][s1]"

View file

@ -87,7 +87,7 @@ defmodule PhilomenaMedia.Processors.Webm do
cond do cond do
thumb_name in [:thumb, :thumb_small, :thumb_tiny] -> 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"}, {:copy, webm, "#{thumb_name}.webm"},
@ -104,10 +104,9 @@ defmodule PhilomenaMedia.Processors.Webm do
end end
defp scale_videos(file, dimensions, target_dimensions) do 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") webm = Briefly.create!(extname: ".webm")
mp4 = Briefly.create!(extname: ".mp4") mp4 = Briefly.create!(extname: ".mp4")
scale_filter = "scale=w=#{width}:h=#{height}"
{_output, 0} = {_output, 0} =
System.cmd("ffmpeg", [ System.cmd("ffmpeg", [
@ -131,7 +130,7 @@ defmodule PhilomenaMedia.Processors.Webm do
"-crf", "-crf",
"31", "31",
"-vf", "-vf",
scale_filter, filter,
"-threads", "-threads",
"4", "4",
"-max_muxing_queue_size", "-max_muxing_queue_size",
@ -152,7 +151,7 @@ defmodule PhilomenaMedia.Processors.Webm do
"-b:v", "-b:v",
"5M", "5M",
"-vf", "-vf",
scale_filter, filter,
"-threads", "-threads",
"4", "4",
"-max_muxing_queue_size", "-max_muxing_queue_size",
@ -164,9 +163,8 @@ defmodule PhilomenaMedia.Processors.Webm do
end end
defp scale_mp4_only(file, dimensions, target_dimensions) do 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") mp4 = Briefly.create!(extname: ".mp4")
scale_filter = "scale=w=#{width}:h=#{height}"
{_output, 0} = {_output, 0} =
System.cmd("ffmpeg", [ System.cmd("ffmpeg", [
@ -188,7 +186,7 @@ defmodule PhilomenaMedia.Processors.Webm do
"-b:v", "-b:v",
"5M", "5M",
"-vf", "-vf",
scale_filter, filter,
"-threads", "-threads",
"4", "4",
"-max_muxing_queue_size", "-max_muxing_queue_size",
@ -199,17 +197,23 @@ defmodule PhilomenaMedia.Processors.Webm do
mp4 mp4
end 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") gif = Briefly.create!(extname: ".gif")
GifPreview.preview(file, gif, duration, dimensions) GifPreview.preview(file, gif, duration, {width, height})
gif gif
end 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 # x264 requires image dimensions to be a multiple of 2
# -2 = ~1 # -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) ratio = min(target_width / width, target_height / height)
new_width = min(max(trunc(width * ratio) &&& -2, 2), target_width) new_width = min(max(trunc(width * ratio) &&& -2, 2), target_width)
new_height = min(max(trunc(height * ratio) &&& -2, 2), target_height) new_height = min(max(trunc(height * ratio) &&& -2, 2), target_height)