Ruby Gem работает в командной строке, а irb - не работает при запуске в качестве скрипта ruby ​​или через Java-процесс - PullRequest
0 голосов
/ 26 марта 2012

Я уже два дня пытаюсь заставить работать определенный API Google. Были опробованы три различных проекта - один в Perl (который умер очень рано), один в Python (разбился и сгорел при последнем препятствии) и, наконец, один в Ruby. Ruby one на самом деле работает, когда вызывается из командной строки как стандартная команда, т. Е .:

speech2text somefile.wav

Это даже работает, если вы откроете irb и вставите образец кода, найденный на сайте проекта:

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

Однако файл Ruby .rb с указанным выше параметром не будет работать при выполнении с ruby -rubygems somescript.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

Попытка использовать двоичный файл командной строки speech2text из Java в качестве процесса выполнения приводит к тому, что возвращается то же сообщение об ошибке. Оскорбительная строка, на которую он жалуется:

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

Но идея о том, что там действительно есть проблема, мне кажется маловероятной, учитывая, что она прекрасно работает, когда выполняется либо в irb, либо через двоичный файл на терминале.

Настоящая проблема здесь в том, что я вообще не знаю Ruby - я работаю на Java, и мне просто нужен этот API для работы. Тот факт, что он запускается в некоторых методах, говорит мне, что я, вероятно, установил его правильно, но если я не могу заставить работать скрипт .rb или заставить его работать внешне, я не могу понять, как его использовать. Мне порекомендовали JRuby, но это может быть слишком сложно для меня, так как кажется, что это потребует ручной установки гема ruby ​​для JRuby, что я не знаю, как это сделать (или, по крайней мере, я не не думаю, что знаю, как это сделать!)

Любые советы по поводу сообщения об ошибке ядра приветствуются, но если вы видите явный шаг в сторону проблемы, дайте мне знать.

РЕДАКТИРОВАТЬ - Это была действительно проблема пути - по крайней мере, на первый взгляд. У Руби были проблемы с поиском нужных файлов, и в результате речь22xt / ffmpeg не получалась довольно неясной. Спасибо!

Ответы [ 2 ]

1 голос
/ 26 марта 2012

Это пахнет как проблема пути.Вы должны всегда указывать полный путь к файлу, так как другие процессы могут внутренне изменить свой рабочий каталог.Другой возможностью было бы изменение $PATH, так что ffmpeg не может быть преобразован в абсолютный путь.

Как правило, вы должны попытаться указать ваши пути как можно более абсолютными.

0 голосов
/ 26 марта 2012

Использование обратных кавычек может маскировать проблему:

`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  

Вы хотите попробовать каждый шаг, прежде чем продолжить, по крайней мере, пока не убедитесь, что ваш процесс является пуленепробиваемым или настолько пуленепробиваемым, насколько вам нужно.

...