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

如何在Rails应用中构建含FFmpeg操作的表单?求实现示例

How to Build a Rails Form for FFmpeg Video Processing

First off, yes—you absolutely can create a Rails form that lets authorized users trigger FFmpeg-based video edits like adding reverb to audio or overlaying audio tracks. Let’s walk through this with practical, actionable examples, since documentation can be sparse for this specific use case.

Step 1: Set Up Dependencies

First, make sure FFmpeg is installed on your server/local machine (verify with ffmpeg -v). Then add the streamio-ffmpeg gem to your Gemfile—it’s a Ruby wrapper that simplifies calling FFmpeg commands:

# Gemfile
gem 'streamio-ffmpeg'

Run bundle install to install it. We’ll assume you’re using Active Storage for handling user-uploaded videos (Rails’ built-in file system, but you can adapt this to CarrierWave or Paperclip too).

Step 2: Create a Video Processing Form

We’ll build a form with radio buttons for different FFmpeg operations. Let’s assume you have a Video model with an active_storage_attached :file attachment.

First, add columns to track processing state and selected action:

rails generate migration AddProcessingFieldsToVideos processing_status:string processing_option:string
rails db:migrate

Now build the form in your view (e.g., app/views/videos/edit.html.erb):

<% if current_user.admin? || current_user == @video.user %>
  <%= form_with model: @video do |form| %>
    <h3>Select Video Processing Action</h3>
    
    <%= form.radio_button :processing_option, "add_reverb" %>
    <%= form.label :processing_option_add_reverb, "Add Reverb to Audio" %>
    
    <%= form.radio_button :processing_option, "overlay_audio" %>
    <%= form.label :processing_option_overlay_audio, "Overlay Background Audio" %>
    
    <%= form.submit "Start Processing", class: "btn btn-primary" %>
  <% end %>
<% end %>

Replace the permission check with your actual logic (e.g., admin access or video ownership).

Step 3: Handle Form Submission in the Controller

Video processing is slow, so we’ll use Active Job to run it in the background. First, generate a job:

rails generate job VideoProcessingJob

Update the VideosController to trigger the job on form submission:

# app/controllers/videos_controller.rb
def update
  @video = Video.find(params[:id])
  # Add permission check here if not using the view check
  # redirect_to @video, alert: "No permission" unless current_user.authorized?

  if @video.update(video_params)
    @video.update(processing_status: "processing")
    VideoProcessingJob.perform_later(@video)
    redirect_to @video, notice: "Video processing started—we’ll notify you when it’s done!"
  else
    render :edit
  end
end

private

def video_params
  params.require(:video).permit(:processing_option)
end

Step 4: Implement FFmpeg Logic in the Job

Add the actual FFmpeg commands to the job—this is where you define how each edit works:

# app/jobs/video_processing_job.rb
class VideoProcessingJob < ApplicationJob
  queue_as :default

  def perform(video)
    input_path = video.file.service.path_for(video.file.key)
    output_path = "#{Rails.root}/tmp/processed_#{video.id}.mp4"

    begin
      case video.processing_option
      when "add_reverb"
        # FFmpeg command to add reverb (adjust parameters for your desired effect)
        ffmpeg_command = "ffmpeg -i #{input_path} -filter_complex \"afftdn=nf=-20:tn=-20,aecho=0.8:0.9:1000:0.3\" #{output_path}"
        system(ffmpeg_command)

      when "overlay_audio"
        # Use a pre-stored background audio file (or let users upload their own)
        background_audio_path = "#{Rails.root}/app/assets/audio/background.mp3"
        ffmpeg_command = "ffmpeg -i #{input_path} -i #{background_audio_path} -filter_complex \"[1:a]volume=0.3[a1];[0:a][a1]amix=inputs=2:duration=shortest\" -c:v copy #{output_path}"
        system(ffmpeg_command)
      end

      # Replace original video with processed version
      video.file.attach(io: File.open(output_path), filename: "processed_#{video.file.filename}", content_type: "video/mp4")
      video.update(processing_status: "completed")
    rescue StandardError => e
      video.update(processing_status: "failed", error_message: e.message)
    ensure
      # Clean up temporary file
      File.delete(output_path) if File.exist?(output_path)
    end
  end
end

Tweak the FFmpeg filter parameters (like aecho or volume) to get your desired effect—FFmpeg has a huge library of filters to explore.

Step 5: Show Processing Status to Users

Add status feedback in your video show view:

# app/views/videos/show.html.erb
<% case @video.processing_status %>
  <% when "processing" %>
    <p class="text-info">Video is being processed—please wait.</p>
  <% when "completed" %>
    <p class="text-success">Video processing done!</p>
    <%= video_tag @video.file %>
  <% when "failed" %>
    <p class="text-danger">Processing failed: <%= @video.error_message %></p>
<% end %>

That’s the core setup! You can expand this with more options (trimming, subtitles, etc.) by adding more radio buttons and corresponding FFmpeg commands in the job.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:23:13