Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
liamwhite committed Dec 26, 2024
2 parents 75955fc + 0a48359 commit 8563700
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 36 deletions.
38 changes: 30 additions & 8 deletions lib/philomena_media/gif_preview.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 =
Expand All @@ -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] ...
Expand All @@ -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 =
[
Expand Down
47 changes: 38 additions & 9 deletions lib/philomena_media/processors/webm.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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"}]

[
Expand Down Expand Up @@ -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"},
Expand All @@ -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")
Expand All @@ -113,6 +114,8 @@ defmodule PhilomenaMedia.Processors.Webm do
"-loglevel",
"0",
"-y",
"-c:v",
decoder,
"-i",
file,
"-c:v",
Expand Down Expand Up @@ -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")

Expand All @@ -171,6 +174,8 @@ defmodule PhilomenaMedia.Processors.Webm do
"-loglevel",
"0",
"-y",
"-c:v",
decoder,
"-i",
file,
"-c:v",
Expand All @@ -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"
Expand Down
11 changes: 0 additions & 11 deletions lib/philomena_web/controllers/api/json/theme_controller.ex

This file was deleted.

9 changes: 9 additions & 0 deletions lib/philomena_web/controllers/theme_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule PhilomenaWeb.ThemeController do
use PhilomenaWeb, :controller

alias PhilomenaWeb.SettingView

def index(conn, _params) do
json(conn, SettingView.theme_paths())
end
end
4 changes: 2 additions & 2 deletions lib/philomena_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/philomena_web/templates/setting/edit.html.slime
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
8 changes: 3 additions & 5 deletions lib/philomena_web/views/setting_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8563700

Please sign in to comment.