Skip to content

Commit

Permalink
Merge pull request #5546 from avalonmediasystem/wav_tmpfile
Browse files Browse the repository at this point in the history
Store http sources as tempfiles on disk to avoid issue with ffmpeg blocking
  • Loading branch information
cjcolvar authored Jan 5, 2024
2 parents e5e206f + cd6590d commit e0760bc
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
18 changes: 15 additions & 3 deletions app/services/waveform_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,27 @@ def get_normalized_peaks(uri)
factor = max_peak.zero? ? 1 : res / max_peak.to_f
peaks.map { |peak| peak.collect { |num| (num * factor).to_i } }
ensure
Process.wait(wave_io.pid) if wave_io&.pid
if wave_io.is_a? Tempfile
wave_io.close
wave_io.unlink
else
Process.wait(wave_io.pid) if wave_io&.pid
end
end

def get_wave_io(uri)
headers = "-headers $'Referer: #{Rails.application.routes.url_helpers.root_url}\r\n'" if uri.starts_with? "http"
normalized_uri = uri.starts_with?("file") ? Addressable::URI.unencode(uri) : uri
timeout = 60000000 # Must be in microseconds. Current value = 1 minute.
cmd = "#{Settings.ffmpeg.path} #{headers} -rw_timeout #{timeout} -i '#{normalized_uri}' -f wav -ar 44100 - 2> /dev/null"
IO.popen(cmd)
tmpfile = Tempfile.new if uri.starts_with?("http")
cmd = "#{Settings.ffmpeg.path} #{headers} -rw_timeout #{timeout} -i '#{normalized_uri}' -f wav -ar 44100 #{tmpfile&.path || "-"} 2> /dev/null"
Rails.logger.debug("Getting wav file for waveform generation using ffmpeg command: #{cmd}")
if tmpfile
Kernel.system(cmd)
tmpfile
else
IO.popen(cmd)
end
end

def gather_peaks(wav_file)
Expand Down
11 changes: 8 additions & 3 deletions spec/services/waveform_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,16 @@

context "http file" do
let(:uri) { "http://domain/to/video.mp4" }
let(:cmd) {"#{Settings.ffmpeg.path} -headers $'Referer: http://test.host/\r\n' -rw_timeout 60000000 -i '#{uri}' -f wav -ar 44100 - 2> /dev/null"}
let(:cmd) {"#{Settings.ffmpeg.path} -headers $'Referer: http://test.host/\r\n' -rw_timeout 60000000 -i '#{uri}' -f wav -ar 44100 /tmp"}

before do
allow(Kernel).to receive(:system).and_return(nil)
end

it "should call ffmpeg with headers" do
service.send(:get_wave_io, uri)
expect(IO).to have_received(:popen).with(cmd)
io = service.send(:get_wave_io, uri)
expect(Kernel).to have_received(:system).with(start_with(cmd))
expect(io).to be_a Tempfile
end
end

Expand Down

0 comments on commit e0760bc

Please sign in to comment.