diff options
author | Ivan Tashkinov <ivantashkinov@gmail.com> | 2020-05-20 20:26:43 +0300 |
---|---|---|
committer | Ivan Tashkinov <ivantashkinov@gmail.com> | 2020-05-20 20:26:43 +0300 |
commit | 1871a5ddb4a803ebe4fae6943a9b9c94f1f9c1a8 (patch) | |
tree | 4068e23fc380346f5fdf531ce3672cd051d363d2 /lib/pleroma/helpers/media_helper.ex | |
parent | 978ccf8f974e7ee398faa3e5bfb7c081144e9325 (diff) | |
download | pleroma-1871a5ddb4a803ebe4fae6943a9b9c94f1f9c1a8.tar.gz |
[#2497] Image preview proxy: implemented ffmpeg-based resizing, removed eimp & mogrify-based resizing.
Diffstat (limited to 'lib/pleroma/helpers/media_helper.ex')
-rw-r--r-- | lib/pleroma/helpers/media_helper.ex | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/pleroma/helpers/media_helper.ex b/lib/pleroma/helpers/media_helper.ex new file mode 100644 index 000000000..6d1f8ab22 --- /dev/null +++ b/lib/pleroma/helpers/media_helper.ex @@ -0,0 +1,62 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Helpers.MediaHelper do + @moduledoc """ + Handles common media-related operations. + """ + + @ffmpeg_opts [{:sync, true}, {:stdout, true}] + + def ffmpeg_resize_remote(uri, max_width, max_height) do + cmd = ~s""" + curl -L "#{uri}" | + ffmpeg -i pipe:0 -vf \ + "scale='min(#{max_width},iw)':min'(#{max_height},ih)':force_original_aspect_ratio=decrease" \ + -f image2 pipe:1 | \ + cat + """ + + with {:ok, [stdout: stdout_list]} <- Exexec.run(cmd, @ffmpeg_opts) do + {:ok, Enum.join(stdout_list)} + end + end + + @doc "Returns a temporary path for an URI" + def temporary_path_for(uri) do + name = Path.basename(uri) + random = rand_uniform(999_999) + Path.join(System.tmp_dir(), "#{random}-#{name}") + end + + @doc "Stores binary content fetched from specified URL as a temporary file." + @spec store_as_temporary_file(String.t(), binary()) :: {:ok, String.t()} | {:error, atom()} + def store_as_temporary_file(url, body) do + path = temporary_path_for(url) + with :ok <- File.write(path, body), do: {:ok, path} + end + + @doc "Modifies image file at specified path by resizing to specified limit dimensions." + @spec mogrify_resize_to_limit(String.t(), String.t()) :: :ok | any() + def mogrify_resize_to_limit(path, resize_dimensions) do + with %Mogrify.Image{} <- + path + |> Mogrify.open() + |> Mogrify.resize_to_limit(resize_dimensions) + |> Mogrify.save(in_place: true) do + :ok + end + end + + defp rand_uniform(high) do + Code.ensure_loaded(:rand) + + if function_exported?(:rand, :uniform, 1) do + :rand.uniform(high) + else + # Erlang/OTP < 19 + apply(:crypto, :rand_uniform, [1, high]) + end + end +end |