我一直试图让某个Google API工作两天。已经尝试了三个不同的项目 - 一个在Perl(很早就死了),一个在Python中(在最后一个障碍时崩溃和烧毁),最后一个在Ruby中。当从命令行调用作为标准命令时,Ruby实际上工作,即:
speech2text somefile.wav
如果你打开irb
并输入项目网站上的示例代码,它甚至可以工作:
require 'speech'
audio = Speech::AudioToText.new("i-like-pickles.wav")
puts audio.to_text.inspect
但是,使用ruby -rubygems somescript.rb
执行时,带有上述内容的Ruby .rb文件将不起作用。它退出了:
/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
尝试将Java中的命令行二进制文件speech2text
用作运行时进程会导致反馈相同的错误消息。它抱怨的违规行是:
def initialize(file)
self.duration = Duration.new(`ffmpeg -i #{file} 2>&1`.strip.scan(/Duration: (.*),/).first.first)
end
但实际上存在问题的想法似乎不太可能,因为它在irb
或终端上的二进制文件中执行时效果很好。
这里真正的问题是我根本不懂Ruby - 我使用Java工作,而我只需要这个API就能运行。它运行在一些方法的事实告诉我,我可能正确安装它,但除非我可以让.rb脚本工作或让它在外部执行,我看不到如何使用它。我已经把JRuby推荐给了我,但这对我来说可能太复杂了,因为它似乎需要手工安装JRuby的红宝石宝石,我不知道该怎么做(或者至少,我不喜欢我想我知道怎么做!)
对核心错误消息的任何建议都非常感激,但是如果你看到问题的明确回避,请告诉我。
编辑 - 这确实是一个路径问题 - 至少在表面上是这样。 Ruby无法找到所涉及的确切文件,因此,speech2text / ffmpeg失败的结果相当模糊。谢谢!答案 0 :(得分:1)
这闻起来像路径问题。您应该始终指定文件的完整路径,因为其他进程可以在内部将其工作目录更改为其他位置。另一种可能性是更改$PATH
,以便ffmpeg
无法解析为绝对路径。
通常,您应该尝试将路径指定为尽可能绝对。
答案 1 :(得分:0)
你使用反引号可能会掩盖问题:
`ffmpeg -i #{file} 2>&1`.strip.scan(/Duration: (.*),/).first.first
如果您什么也没收到,或者您的搜索结果中没有“持续时间:”,那么您将收到错误消息。
首先,确认您的路径是正确的。任何嵌入的空格都会破坏您的命令,因为ffmpeg
将接收文件名作为多个参数,而不是完整的文件路径。您可以使用任何系统调用或popen
来防止这种情况,或者逃避任何嵌入空格和单/双引号。至少,尝试:
`ffmpeg -i "#{file}" 2>&1`
或
`ffmpeg -i '#{file}' 2>&1`
考虑将您对ffmpeg
的调用分成多个步骤,进行防御性编写,并了解正在发生的事情。这是未经测试的代码,但应该给你一个想法:
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
您希望在继续之前尝试每一步,至少直到您确定自己的流程是防弹的,或者根据需要进行防弹。