From 0d21e49fffb04ff27863d2de1f44a71541e9b307 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 20 Dec 2024 12:54:55 -0500 Subject: [PATCH 1/3] fixup --- .../controllers/api/json/theme_controller.ex | 4 +--- lib/philomena_web/templates/setting/edit.html.slime | 2 +- lib/philomena_web/views/setting_view.ex | 8 +++----- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/philomena_web/controllers/api/json/theme_controller.ex b/lib/philomena_web/controllers/api/json/theme_controller.ex index 34f195f22..d9e2c28fe 100644 --- a/lib/philomena_web/controllers/api/json/theme_controller.ex +++ b/lib/philomena_web/controllers/api/json/theme_controller.ex @@ -4,8 +4,6 @@ defmodule PhilomenaWeb.Api.Json.ThemeController do alias PhilomenaWeb.SettingView def index(conn, _params) do - conn - |> put_resp_content_type("application/json") - |> send_resp(200, SettingView.theme_paths_json(conn)) + json(conn, SettingView.theme_paths()) end end diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index 0604e3830..829c3cd27 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -88,7 +88,7 @@ h1 Content Settings = error_tag f, :theme_color .fieldlabel: i Color of the theme .fieldlabel: strong Don't forget to save the settings to apply the theme! - .hidden#js-theme-paths data-theme-paths=theme_paths_json(@conn) + .hidden#js-theme-paths data-theme-paths=Jason.encode!(theme_paths()) .field => label f, :scale_large_images => select f, :scale_large_images, scale_options(), class: "input" diff --git a/lib/philomena_web/views/setting_view.ex b/lib/philomena_web/views/setting_view.ex index 601307bbe..d6826e0e0 100644 --- a/lib/philomena_web/views/setting_view.ex +++ b/lib/philomena_web/views/setting_view.ex @@ -15,12 +15,10 @@ defmodule PhilomenaWeb.SettingView do end) end - def theme_paths_json(conn) do - User.themes() - |> Map.new(fn name -> - {name, static_path(conn, "/css/#{name}.css")} + def theme_paths do + Map.new(User.themes(), fn name -> + {name, static_path(PhilomenaWeb.Endpoint, "/css/#{name}.css")} end) - |> Jason.encode!() end def scale_options do From d695bf18f033b8793560e2282d3a44c0e58a5300 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 20 Dec 2024 14:10:55 -0500 Subject: [PATCH 2/3] use as internal API --- .../controllers/{api/json => }/theme_controller.ex | 2 +- lib/philomena_web/router.ex | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename lib/philomena_web/controllers/{api/json => }/theme_controller.ex (74%) diff --git a/lib/philomena_web/controllers/api/json/theme_controller.ex b/lib/philomena_web/controllers/theme_controller.ex similarity index 74% rename from lib/philomena_web/controllers/api/json/theme_controller.ex rename to lib/philomena_web/controllers/theme_controller.ex index d9e2c28fe..e00289c48 100644 --- a/lib/philomena_web/controllers/api/json/theme_controller.ex +++ b/lib/philomena_web/controllers/theme_controller.ex @@ -1,4 +1,4 @@ -defmodule PhilomenaWeb.Api.Json.ThemeController do +defmodule PhilomenaWeb.ThemeController do use PhilomenaWeb, :controller alias PhilomenaWeb.SettingView diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index a0744ac70..50b839f04 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -157,8 +157,6 @@ defmodule PhilomenaWeb.Router do resources "/posts", Forum.Topic.PostController, only: [:show, :index] end end - - resources "/themes", ThemeController, only: [:index] end scope "/", PhilomenaWeb do @@ -492,6 +490,8 @@ defmodule PhilomenaWeb.Router do resources "/tags", TagController, only: [:index] end + resources "/themes", ThemeController, only: [:index] + resources "/tags", TagController, only: [:index, :show] do resources "/tag_changes", Tag.TagChangeController, only: [:index] end From 9b022e7c3a4b8336ba59eab7a2856956aed6d6e2 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 23 Dec 2024 10:52:46 -0500 Subject: [PATCH 3/3] Fix transparency issues in webm videos --- lib/philomena_media/gif_preview.ex | 38 ++++++++++++++++----- lib/philomena_media/processors/webm.ex | 47 +++++++++++++++++++++----- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/lib/philomena_media/gif_preview.ex b/lib/philomena_media/gif_preview.ex index fe3f79140..ac40044b4 100644 --- a/lib/philomena_media/gif_preview.ex +++ b/lib/philomena_media/gif_preview.ex @@ -13,6 +13,9 @@ defmodule PhilomenaMedia.GifPreview do target_framerate: target_framerate() ] + @typedoc "One of av1, h264, libvpx, libvpx-vp9" + @type decoder :: String.t() + @doc """ Generate a GIF preview of the given video input with evenly-spaced sample points. @@ -31,8 +34,8 @@ defmodule PhilomenaMedia.GifPreview do * 1 or above: 5 images * otherwise: 2 images """ - @spec preview(Path.t(), Path.t(), duration(), dimensions(), opts()) :: :ok - def preview(video, gif, duration, dimensions, opts \\ []) do + @spec preview(decoder(), Path.t(), Path.t(), duration(), dimensions(), opts()) :: :ok + def preview(decoder, video, gif, duration, dimensions, opts \\ []) do target_framerate = Keyword.get(opts, :target_framerate, 2) num_images = @@ -48,22 +51,41 @@ defmodule PhilomenaMedia.GifPreview do {_output, 0} = System.cmd( "ffmpeg", - commands(video, gif, clamp(duration), dimensions, num_images, target_framerate) + commands(decoder, video, gif, clamp(duration), dimensions, num_images, target_framerate) ) :ok end - @spec commands(Path.t(), Path.t(), duration(), dimensions(), num_images(), target_framerate()) :: + @spec commands( + decoder(), + Path.t(), + Path.t(), + duration(), + dimensions(), + num_images(), + target_framerate() + ) :: [String.t()] - defp commands(video, gif, duration, {target_width, target_height}, num_images, target_framerate) do + defp commands( + decoder, + video, + gif, + duration, + {target_width, target_height}, + num_images, + target_framerate + ) do # Compute range [0, num_images) image_range = 0..(num_images - 1) # Generate input list in the following form: - # -ss 0.0 -i input.webm + # -ss 0.0 -c:v libvpx -i input.webm input_arguments = - Enum.flat_map(image_range, &["-ss", "#{&1 * duration / num_images}", "-i", video]) + Enum.flat_map( + image_range, + &["-ss", "#{&1 * duration / num_images}", "-c:v", decoder, "-i", video] + ) # Generate graph in the following form: # [0:v] trim=end_frame=1 [t0]; [1:v] trim=end_frame=1 [t1] ... @@ -87,7 +109,7 @@ defmodule PhilomenaMedia.GifPreview do "[s0] palettegen=stats_mode=single:max_colors=255:reserve_transparent=1 [palettegen]" paletteuse_filter = - "[s1][palettegen] paletteuse=dither=bayer:bayer_scale=5:new=1:alpha_threshold=255" + "[s1][palettegen] paletteuse=dither=bayer:bayer_scale=5:new=1:alpha_threshold=251" filter_graph = [ diff --git a/lib/philomena_media/processors/webm.ex b/lib/philomena_media/processors/webm.ex index 22c54a6d8..0fcc11296 100644 --- a/lib/philomena_media/processors/webm.ex +++ b/lib/philomena_media/processors/webm.ex @@ -29,11 +29,12 @@ defmodule PhilomenaMedia.Processors.Webm do duration = analysis.duration stripped = strip(file) preview = preview(duration, stripped) - mp4 = scale_mp4_only(stripped, dimensions, dimensions) + decoder = select_decoder(file) + mp4 = scale_mp4_only(decoder, stripped, dimensions, dimensions) {:ok, intensities} = Intensities.file(preview) - scaled = Enum.flat_map(versions, &scale(stripped, duration, dimensions, &1)) + scaled = Enum.flat_map(versions, &scale(decoder, stripped, duration, dimensions, &1)) mp4 = [{:copy, mp4, "full.mp4"}] [ @@ -82,12 +83,12 @@ defmodule PhilomenaMedia.Processors.Webm do stripped end - defp scale(file, duration, dimensions, {thumb_name, target_dimensions}) do - {webm, mp4} = scale_videos(file, dimensions, target_dimensions) + defp scale(decoder, file, duration, dimensions, {thumb_name, target_dimensions}) do + {webm, mp4} = scale_videos(decoder, file, dimensions, target_dimensions) cond do thumb_name in [:thumb, :thumb_small, :thumb_tiny] -> - gif = scale_gif(file, duration, dimensions, target_dimensions) + gif = scale_gif(decoder, file, duration, dimensions, target_dimensions) [ {:copy, webm, "#{thumb_name}.webm"}, @@ -103,7 +104,7 @@ defmodule PhilomenaMedia.Processors.Webm do end end - defp scale_videos(file, dimensions, target_dimensions) do + defp scale_videos(decoder, file, dimensions, target_dimensions) do filter = scale_filter(dimensions, target_dimensions) webm = Briefly.create!(extname: ".webm") mp4 = Briefly.create!(extname: ".mp4") @@ -113,6 +114,8 @@ defmodule PhilomenaMedia.Processors.Webm do "-loglevel", "0", "-y", + "-c:v", + decoder, "-i", file, "-c:v", @@ -162,7 +165,7 @@ defmodule PhilomenaMedia.Processors.Webm do {webm, mp4} end - defp scale_mp4_only(file, dimensions, target_dimensions) do + defp scale_mp4_only(decoder, file, dimensions, target_dimensions) do filter = scale_filter(dimensions, target_dimensions) mp4 = Briefly.create!(extname: ".mp4") @@ -171,6 +174,8 @@ defmodule PhilomenaMedia.Processors.Webm do "-loglevel", "0", "-y", + "-c:v", + decoder, "-i", file, "-c:v", @@ -197,15 +202,39 @@ defmodule PhilomenaMedia.Processors.Webm do mp4 end - defp scale_gif(file, duration, dimensions, target_dimensions) do + defp scale_gif(decoder, file, duration, dimensions, target_dimensions) do {width, height} = box_dimensions(dimensions, target_dimensions) gif = Briefly.create!(extname: ".gif") - GifPreview.preview(file, gif, duration, {width, height}) + GifPreview.preview(decoder, file, gif, duration, {width, height}) gif end + defp select_decoder(file) do + {output, 0} = + System.cmd("ffprobe", [ + "-loglevel", + "0", + "-select_streams", + "v:0", + "-show_entries", + "stream=codec_name", + "-of", + "default=noprint_wrappers=1:nokey=1", + "-i", + file + ]) + + # Mediatools verifies that we only have one video stream and that it is + # one of the supported formats, so the following is safe to do: + case output do + "vp8\n" -> "libvpx" + "vp9\n" -> "libvpx-vp9" + "av1\n" -> "av1" + end + end + defp scale_filter(dimensions, target_dimensions) do {width, height} = box_dimensions(dimensions, target_dimensions) "scale=w=#{width}:h=#{height},setsar=1"