Support metadata for video files too
authorMark Felder <feld@feld.me>
Thu, 3 Jun 2021 21:58:18 +0000 (16:58 -0500)
committerMark Felder <feld@feld.me>
Tue, 8 Jun 2021 17:54:09 +0000 (12:54 -0500)
lib/pleroma/application_requirements.ex
lib/pleroma/upload/filter/analyze_metadata.ex

index ee6ee9516e7af24e45fecc8b1861cb72d91e828e..a56311a65e623f7352ea5e2013e5646ae306cfef 100644 (file)
@@ -168,7 +168,8 @@ defmodule Pleroma.ApplicationRequirements do
       check_filter(Pleroma.Upload.Filter.Mogrify, "mogrify"),
       check_filter(Pleroma.Upload.Filter.Mogrifun, "mogrify"),
       check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "mogrify"),
-      check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "convert")
+      check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "convert"),
+      check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "ffprobe")
     ]
 
     preview_proxy_commands_status =
index 8c23076d424b4caaf826f9b3571d857cfc424844..c89c30fc1a8dd79be02034215721bd00ac4b341e 100644 (file)
@@ -33,6 +33,23 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
     end
   end
 
+  def filter(%Pleroma.Upload{tempfile: file, content_type: "video" <> _} = upload) do
+    try do
+      result = media_dimensions(file)
+
+      upload =
+        upload
+        |> Map.put(:width, result.width)
+        |> Map.put(:height, result.height)
+
+      {:ok, :filtered, upload}
+    rescue
+      e in ErlangError ->
+        Logger.warn("#{__MODULE__}: #{inspect(e)}")
+        {:ok, :noop}
+    end
+  end
+
   def filter(_), do: {:ok, :noop}
 
   defp get_blurhash(file) do
@@ -42,4 +59,25 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
       _ -> nil
     end
   end
+
+  defp media_dimensions(file) do
+    with executable when is_binary(executable) <- System.find_executable("ffprobe"),
+         args = [
+           "-v",
+           "error",
+           "-show_entries",
+           "stream=width,height",
+           "-of",
+           "csv=p=0:s=x",
+           file
+         ],
+         {result, 0} <- System.cmd(executable, args),
+         [width, height] <-
+           String.split(String.trim(result), "x") |> Enum.map(&String.to_integer(&1)) do
+      %{width: width, height: height}
+    else
+      nil -> {:error, {:ffprobe, :command_not_found}}
+      {:error, _} = error -> error
+    end
+  end
 end