You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir后台长时间运行任务未完成且偶发崩溃问题求助

实现异步转码的视频上传端点方案

针对你需要实现的异步转码视频上传端点,我整理了一套适配Phoenix框架的实现方案,完全满足你提到的「上传后复制到临时目录、后台启动ffmpeg转码、立即返回200响应」的需求:

核心实现思路

  • 接收上传文件后,生成唯一标识并将文件复制到指定临时目录
  • 启动独立异步进程执行ffmpeg转码操作,不阻塞当前请求处理
  • 立即向客户端返回成功响应,无需等待转码完成

完整控制器代码示例

defmodule MyApp.VideoController do
  use MyApp.Web, :controller
  alias MyApp.Video

  def create(conn, %{"file" => file}) do
    # 生成唯一UUID作为视频的临时标识
    uuid = Video.uuid()
    # 从应用配置读取临时目录,默认使用系统临时目录下的videos文件夹
    temp_dir = Application.get_env(:my_app, :temp_video_storage) || "/tmp/videos"
    
    # 确保临时目录存在(不存在则创建)
    File.mkdir_p!(temp_dir)
    
    # 复制上传的原始文件到临时目录,避免原文件被框架自动清理
    original_temp_path = Path.join(temp_dir, "#{uuid}_original.mp4")
    File.cp!(file.path, original_temp_path)

    # 启动异步任务执行ffmpeg转码
    Task.start(fn ->
      # 定义转码后的输出路径
      transcoded_path = Path.join(temp_dir, "#{uuid}_transcoded.mp4")
      
      # 执行ffmpeg转码命令,可根据需求调整参数(比如分辨率、码率)
      {output, exit_code} = System.cmd("ffmpeg", [
        "-i", original_temp_path,
        "-c:v", "libx264",  # 使用H.264视频编码
        "-crf", "23",       # 视频质量参数(值越小质量越高)
        "-preset", "medium",# 编码速度/压缩比平衡
        "-c:a", "aac",      # 使用AAC音频编码
        "-b:a", "128k",     # 音频码率
        "-y",               # 覆盖已存在的输出文件
        transcoded_path
      ])

      # 转码完成后的后续操作示例
      if exit_code == 0 do
        # 转码成功:可以将文件移动到永久存储、更新数据库中视频的状态
        # Video.update_transcoding_status(uuid, :completed)
        # File.rename(transcoded_path, Path.join(permanent_dir, "#{uuid}.mp4"))
      else
        # 转码失败:记录错误日志、更新状态为失败
        # Logger.error("转码失败,视频ID:#{uuid},错误信息:#{output}")
        # Video.update_transcoding_status(uuid, :failed)
      end
    end)

    # 立即返回200响应,告知客户端上传成功且转码已启动
    conn
    |> put_status(:ok)
    |> json(%{
      message: "视频上传成功,后台转码已启动",
      video_id: uuid
    })
  end
end

关键细节解释

  • 文件复制逻辑:Phoenix会将上传的临时文件存在系统临时目录,且可能在请求结束后清理,所以我们需要主动复制到自定义临时目录,保证转码过程中文件不会丢失。
  • 异步任务启动:使用Task.start/1创建独立进程执行转码,当前控制器进程不会等待转码完成,能快速响应客户端。如果需要更可靠的任务管理(比如失败重试、分布式执行),建议使用Oban这类专业任务队列。
  • ffmpeg参数配置:示例中的参数是通用的H.264/AAC转码配置,你可以根据需求调整,比如添加-s 1920x1080指定1080P分辨率,或者更换编码格式。
  • 错误处理:在异步任务中捕获ffmpeg的退出码和输出信息,方便排查转码失败的原因,同时可以更新数据库中视频的状态,让客户端能查询转码进度。

生产环境注意事项

  • 资源限制:ffmpeg转码是CPU密集型操作,生产环境中要限制同时运行的转码任务数量,避免服务器资源耗尽。
  • 临时文件清理:要定期清理临时目录中的过期文件(比如超过7天的未转码完成文件、转码后的临时文件),可以通过定时任务实现。
  • 日志监控:要记录转码任务的执行日志,包括成功和失败的情况,方便运维排查问题。

内容的提问来源于stack exchange,提问作者Kulix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:24:04