使用Arc和FFmpeg在Elixir中上传视频创建的背景版本

时间:2017-12-01 15:40:16

标签: ffmpeg elixir automatic-ref-counting

我尝试使用Arc在Elixir phoenix项目上进行视频上传。我需要有不同大小的视频版本。所以我使用FFmpeg来做到这一点:

def transform(:large, {file, scope}) do
  {:ffmpeg, fn(input, output) -> "-i #{input} -c:a copy -s 1920x1080 -f mp4 #{output}" end, :mp4}
end

然而,即使是小视频,也需要花费大量时间来创建这个版本。所以,我决定在后台制作版本。我希望Arc上传视频,然后在其他版本创建的同时给出上传原文的回复。

我希望在https://github.com/stavro/arc找到这样的选项,但我没有成功。我只找到"要禁用异步处理,请将@async false添加到您的上传定义"但是我不想禁用它,对吧?

我尝试使用Exq https://github.com/akira/exq进行后台处理,但我并没有在上传程序中使用它。

有人可以告诉我应该如何以适当的方式制作它,或者给我一些肮脏的黑客建议来使其发挥作用。感谢。

我按照评论中的建议尝试了Task,但我不确定如何在这种情况下使用它们。当我尝试

{:ffmpeg, fn(input, output) -> Task.async(fn -> "-i #{input} -c:a copy -s 1920x1080 -f mp4 #{output}" end) end, :mp4}

{:ffmpeg, Task.async(fn -> fn(input, output) ->  "-i #{input} -c:a copy -s 1920x1080 -f mp4 #{output}" end end), :mp4}

我得到了"协议String.Chars没有为%Task"。

实现

当我尝试

{:ffmpeg, Task.async(fn(input, output) ->  "-i #{input} -c:a copy -s 1920x1080 -f mp4 #{output}" end), :mp4}

我在MyWebSite.Content.transform / 2>中得到了#34;#Function< 20.83953603 / 2;与arity 2调用没有参数"。我试图将函数作为参数传递给"&"但它也失败了。

我的上传者:

defmodule MyWebSite.Content do
use Arc.Definition
use Arc.Ecto.Definition

@acl :public_read

@versions [:original,  :huge]

def transform(:huge, {file, scope}) do
  {:ffmpeg, Task.async(fn(input, output) ->  "-i #{input} -c:a copy -s 1920x1080 -f mp4 #{output}" end), :mp4}
end

def s3_object_headers(version, {file, scope}) do
  [timeout: 3_000_00, content_type: Plug.MIME.path(file.file_name)]
end
end

1 个答案:

答案 0 :(得分:0)

来自Arc的自述文件(Complex Transformations部分):

  

但是,转换可以完全在Arc之外完成。对于细粒度转换,你应该在$PATH(例如bash脚本)中创建一个可执行包装器,它接受这些正确的参数,运行转换,然后将文件移动到正确的位置。位置**。

也就是说,如果你想让转换完全异步运行,只需在某处创建一个bash脚本并调用它(假设它的名字是myffmpeg):

def transform(:huge, {file, scope}) do
  {:myffmpeg,
     fn ->
       "-i #{input} -c:a copy -s 1920x1080 -f mp4 #{output}"
     end,
   :mp4}
end

脚本应该生成 ffmpeg传递参数并将结果移动到Arc想要的文件夹。