diff --git a/app/services/waveform_service.rb b/app/services/waveform_service.rb index 219c309de2..99c8dce39a 100644 --- a/app/services/waveform_service.rb +++ b/app/services/waveform_service.rb @@ -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) diff --git a/spec/services/waveform_service_spec.rb b/spec/services/waveform_service_spec.rb index 09ec6a1a5f..90a5e21887 100644 --- a/spec/services/waveform_service_spec.rb +++ b/spec/services/waveform_service_spec.rb @@ -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