2012-03-26 13 views
0

Ich habe versucht, eine bestimmte Google API für zwei Tage zu arbeiten. Drei verschiedene Projekte wurden ausprobiert - eines in Perl (welches sehr früh starb) eines in Python (abgestürzt und verbrannt an der letzten Hürde) und schließlich eines in Ruby. The Ruby arbeitet man eigentlich, wenn von der Kommandozeile als Standard-Befehl aufgerufen, das heißt:Ruby Gem funktioniert auf Kommandozeile und irb - schlägt fehl, wenn es als Ruby-Skript oder über Java-Prozess ausgeführt wird

speech2text somefile.wav 

Es funktioniert auch, wenn Sie irb öffnen und in dem Beispielcode auf der Website des Projektes gefunden setzen:

require 'speech' 
audio = Speech::AudioToText.new("i-like-pickles.wav") 
puts audio.to_text.inspect 

Eine Ruby-.rb-Datei mit dem obigen in funktioniert jedoch nicht, wenn sie mit ruby -rubygems somescript.rb ausgeführt wird. Es tritt mit diesem:

/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 

Der Versuch, das Kommandozeilen-Binär-speech2text von Java als Runtime-Prozess führt zu der gleichen Fehlermeldung zurück wird zugeführt zu verwenden. Die Codezeile es beschwert sich über ist:

def initialize(file) 
    self.duration = Duration.new(`ffmpeg -i #{file} 2>&1`.strip.scan(/Duration: (.*),/).first.first) 
end 

Aber die Idee, ein Problem tatsächlich ist, da mir unwahrscheinlich scheint gegeben, dass es perfekt funktioniert, wenn entweder irb oder über den binären auf einem Terminal ausgeführt.

Das eigentliche Problem hier ist, dass ich Ruby überhaupt nicht kenne - ich arbeite in Java, und ich brauche einfach diese API zu funktionieren. Die Tatsache, dass es in einigen Methoden ausgeführt wird, sagt mir, dass ich es wahrscheinlich richtig installiert habe, aber wenn ich kein .rb-Skript zum Funktionieren bringen oder es extern ausführen lassen kann, kann ich nicht sehen, wie es zu benutzen ist. Ich habe JRuby für mich empfohlen, aber das könnte zu kompliziert für mich sein, da es eine manuelle Installation des Rubin-Edelsteins für JRuby erfordert, von dem ich nicht weiß, wie ich es machen soll (oder zumindest nicht Ich denke, ich weiß, wie es geht!)

Jeder Hinweis auf die Kernfehlermeldung sehr geschätzt, aber wenn Sie eine klare Umgehung des Problems sehen lassen Sie mich wissen.

EDIT - Es war in der Tat ein Pfadproblem - zumindest auf den ersten Blick. Ruby hatte Probleme, die genauen betroffenen Dateien zu finden, und read2text/ffmpeg versagte dadurch eher im Dunkeln. Vielen Dank!

Antwort

1

Das riecht wie ein Pfadproblem. Sie sollten immer den vollständigen Pfad zur Datei angeben, da andere Prozesse ihr Arbeitsverzeichnis intern in andere Speicherorte ändern können. Eine andere Möglichkeit wäre ein geänderter $PATH, so dass ffmpeg nicht auf einen absoluten Pfad aufgelöst werden kann.

Im Allgemeinen sollten Sie versuchen, Ihre Pfade so genau wie möglich zu spezifizieren.

+0

Welche besondere Sache wird falsch behandelt? Ist es das Juwel rede2text? Der Rubin selbst installiert? Oder die Sachen, die Speech2text selbst benutzt (wie ffmpeg, wie du sagst)? Es tut mir leid, dass ich das so explizit darlege, dass ich nur wenig Ahnung davon habe, wie Ruby funktioniert und ich bin zu ausgebrannt, um damit zu spielen! – mtrc

+0

Auch - danke, dass Sie sich die Zeit genommen haben, zu lesen und zu antworten. – mtrc

+0

Zwei Dinge: 'i-like-pickles.wav' und die' ffmpeg'-Binärdatei. Sie sollten zuerst versuchen, einen absoluten Pfad zu Ihrer Audiodatei zu verwenden. –

0

Ihre Nutzung von Backticks kann das Problem sein Maskierung:

`ffmpeg -i #{file} 2>&1`.strip.scan(/Duration: (.*),/).first.first 

Wenn Sie nichts zurückbekommen, oder Ihre Ergebnisse enthalten keine „Dauer:“ von etwas gefolgt, werden Sie den Fehler erhalten Sie sahen.

Zuerst bestätigen Sie, dass Ihr Pfad korrekt ist. Alle eingebetteten Leerzeichen unterbrechen den Befehl, da ffmpeg den Dateinamen als mehrere Parameter und nicht als vollständigen Dateipfad erhält. Sie können einen der Systemaufrufe oder popen verwenden, um davor zu schützen oder alle eingebetteten Leerzeichen und einfache/doppelte Anführungszeichen zu umgehen.Zumindest versuchen:

`ffmpeg -i "#{file}" 2>&1` 

oder

`ffmpeg -i '#{file}' 2>&1` 

Betrachten Sie Ihren Anruf ffmpeg in mehreren Schritten zu brechen, defensiv zu schreiben, und etwas Einblick in das bekommen, was los ist. Dies ist ungetestet Code aber sollten Sie die Idee geben:

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 

Sie wollen jeden Schritt, um zu versuchen, bevor Sie fortfahren, zumindest, bis Sie sicher, dass Ihr Prozess ist kugelsicher oder als kugelsicher wie Sie benötigen.

+0

Ein Teil des Problems ist, dass dies alles aus Ruby Code von jemand anderem ist! Ich hatte also nur eine vage Vorstellung davon, was diese Linie tat. Dein Beitrag hat es sehr deutlich gemacht, also bin ich ein bisschen sicherer darin, es jetzt zu bearbeiten. – mtrc

+0

Die Verwendung von Backticks, um etwas innerhalb einer Subshell auszuführen, ist in Sprachen sehr verbreitet und ist mit vielen Problemen behaftet, die nicht sofort sichtbar sind. –

Verwandte Themen