gpt4 book ai didi

ffmpeg - Elixir 长时间运行的后台任务无法完成,有时会崩溃

转载 作者:行者123 更新时间:2023-12-02 13:34:31 26 4
gpt4 key购买 nike

作为一点背景知识,我有一个负责视频上传的端点。我想要做的是将视频文件从请求复制到临时位置,并启动异步任务(ffmpeg shell 进程)以在后台对该视频进行转码,以便我的端点可以及时返回 200,并且响应不会等待 ffmpeg 完成对该视频的转码。

这是我的 Controller 代码。

def create(conn, %{"file" => file ... })
uuid = Video.uuid()
tmp_path = Application.get_env(:myapp, :video_tmp_path) <> "/" <> uuid
:ok = File.cp(file.path, tmp_path)
VideoService.process(tmp_path, final_path)

VideoService 的内部如下所示。

defmodule MyApp.Services do
defmodule VideoService do
def process(tmp_path, final_path) do
Task.start_link fn ->
System.cmd("ffmpeg", ["-i", tmp_path, final_path, "-hide_banner"])
File.rm(tmp_path)
end
end
end
end

我在这里遇到的问题是,无论如何,System.cmd("ffmpeg") 调用之后的任何内容都不会在 VideoService 中执行,有时System.cmd 调用甚至不会启动 ffmpeg 进程。我在这里做错了什么吗?我需要的是一种方法来从 Controller /服务在后台旋转这个 ffmpeg shell 进程,并在视频上传时响应 200。提前感谢您的帮助。我是 Elixir/OTP 的新手,所以我确信我在做一些愚蠢的事情。

我也随机看到以下错误

erl_child_setup:失败,第 240 行出现错误 32

最佳答案

感谢 mudasobwa 和 Dogbert 帮助回答这个问题。我关注了this guide按照他们的建议,让一个独立的主管在我的 Phoenix 堆栈中启动并运行。其要点是向 lib/myapp.ex 添加一行来创建这样的 Supervisor

supervisor(Task.Supervisor, [[name: MyApp.TaskSupervisor]])

然后,当您想要以该主管作为父级运行任务时,您可以运行

Task.Supervisor.start_child(MyApp.TaskSupervisor, fn -> do_stuff() end)

就我而言,do_stuff 涉及生成 ffmpeg 进程并进行一些文件清理。这里的基本思想是,您以 Supervisor 作为父级来完成这项工作,这样即使请求退出并且该进程终止,您的 Supervisor 仍然存在并且运行良好,因为当您的应用程序启动时它始终处于运行状态。

关于ffmpeg - Elixir 长时间运行的后台任务无法完成,有时会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49525248/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com