Reputation: 1345
I've been trying to get a certain Google API to work for two days now. Three different projects have been tried - one in Perl (which died very early on) one in Python (crashed and burnt at the last hurdle) and finally one in Ruby. The Ruby one actually works when called from the commandline as a standard command, i.e.:
speech2text somefile.wav
It even works if you open up irb
and put in the sample code found on the project site:
require 'speech'
audio = Speech::AudioToText.new("i-like-pickles.wav")
puts audio.to_text.inspect
However, a Ruby .rb file with the above in will not work when executed with ruby -rubygems somescript.rb
. It exits with this:
/Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_inspector.rb:50:in `initialize': undefined method `first' for nil:NilClass (NoMethodError)
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_splitter.rb:77:in `new'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_splitter.rb:77:in `initialize'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_to_text.rb:15:in `new'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_to_text.rb:15:in `to_text'
from script/test_s2t.rb:6
Attempting to use the commandline binary speech2text
from Java as a runtime process results in the same error message being fed back. The offending line it complains about is:
def initialize(file)
self.duration = Duration.new(`ffmpeg -i #{file} 2>&1`.strip.scan(/Duration: (.*),/).first.first)
end
But the idea of there actually being a problem in there seems unlikely to me, given that it works perfectly when executed in either irb
or via the binary on a terminal.
The real problem here is that I don't know Ruby at all - I work in Java, and I simply need this API to function. The fact that it runs in some methods tells me I probably installed it correctly, but unless I can get a .rb script to work or get it to execute externally, I can't see how to use it. I've had JRuby recommended to me, but that might be too complicated for me, as it seems it would require a manual installation of the ruby gem for JRuby, which I don't know how to do (or at least, I don't think I know how to do it!)
Any advice on the core error message much appreciated, but if you see a clear sidestep to the problem do let me know.
EDIT - It was, indeed, a path problem - at least on the face of it. Ruby was having trouble locating the exact files involved, and speech2text/ffmpeg was failing rather obscurely as a result. Thanks!
Upvotes: 0
Views: 826
Reputation: 160551
Your use of backticks can be masking the problem:
`ffmpeg -i #{file} 2>&1`.strip.scan(/Duration: (.*),/).first.first
If you get nothing back, or your results don't contain "Duration: " followed by something, you will get the error you saw.
First, confirm that your path is correct. Any embedded spaces will break your command because ffmpeg
will receive the file name as multiple parameters, not a full file path. You can use any of the system calls or popen
to protect against that, or escape any embedded spaces and single/double quotes. At a minimum, try:
`ffmpeg -i "#{file}" 2>&1`
or
`ffmpeg -i '#{file}' 2>&1`
Consider breaking your call to ffmpeg
into multiple steps, to write defensively, and get some visibility into what is going on. This is untested code but should give you the idea:
ffmpeg_results = `ffmpeg -i #{ file } 2>&1`
if (!ffmpeg_results.strip.empty?)
duration = ffmpeg_results.strip[/Duration: (.*),/, 1]
if (!duration.strip.empty? && duration.to_i > 0)
...
end
else
puts "ffmpeg_results are empty"
end
You want to try each step, before continuing, at least until you are sure your process is bulletproof, or as bulletproof as you need.
Upvotes: 0
Reputation: 55758
This smells like a path issue. You should always specify the full path to the file as other processes can change their working directory to other locations internally. Another possibility would be a changed $PATH
so that ffmpeg
can not be resolved to an absolute path.
Generally, you should try to specify your paths as absolute as possible.
Upvotes: 1