私はパイプ、IO.popen
特にRubyで作業してきましたが、理解できない問題に遭遇しました。flac
プロセスからプロセスへのバイナリデータをファイルに書き込もうとしてlame
います。私が使用しているコード構造は以下のとおりです。
# file paths
file = Pathname.new('example.flac').realpath
dest = Pathname.new('example.mp3')
# execute the process and return the IO object
wav = IO.popen("flac --decode --stdout \"#{file}\"", 'rb')
lame = IO.popen("lame -V0 --vbr-new - -", 'r+b')
# write output from wav to the lame IO object
lame << wav.read
# close pipe for writing (should indicate to the
# process that input for stdin is finished).
lame.close_write
# open up destiniation file and write from lame stdout
dest.open('wb'){|out|
out << lame.read
}
# close all pipes
wav.close
lame.close
しかし、うまくいきません。の実行後flac
、スクリプトはハングし、lame
アイドル状態のままになります (プロセッサはまったく使用されません)。エラーや例外は発生しません。
Windows 7 で cygwin ruby パッケージ ( 1.9.3p429 (2013-05-15) [i386-cygwin] ) を使用して cygwin を使用しています。
私は何か間違ったことをしているに違いありません。どんな助けも大歓迎です。ありがとう!
エクストラ #1
オーディオファイルをトランスコードlame
するためにプラットフォームに依存しない(もちろんルビーのサポートは限定されています)を作成しようとしているため、プロセスからバイナリデータをパイプインおよびパイプアウトしたいと考えています.Windowsバイナリはlame
Windowsのパス名のみをサポートし、cygwinの.
編集#1
IO.popen
Windows でプロセスをブロックすることに関する既知の問題があり、これが当てはまる可能性があるいくつかの場所を読みました (URL を保存しなかったので、ブラウザーの履歴で検索してみます) 。
RubyOpen3.popen3
やを含む他のライブラリをいじってみOpen4
ましたが、上記のコード構造と非常によく似たコード構造に従っているため、lame
プロセスは依然としてハングし、応答しません。
編集#2
Windowsの制限と、ファイルから標準入力へのストリーミングデータの使用をどのように妨げるかについて説明しているこの記事を見つけました。cmd.exe
これをテストするために、コードを次のようにリファクタリングしましたが、lame
結局のところ、stdin 書き込みでフリーズします。その行を削除(コメントアウト)すると、lame
プロセスが実行されます(「サポートされていないオーディオ形式」の警告が表示されます)。おそらく、この記事で述べたことで、ここで私の問題を説明できるかもしれません。
# file paths
file = Pathname.new('example.flac').realpath
dest = Pathname.new('example.mp3')
# some local variables
read_wav = nil
read_lame = nil
# the flac process, which exits succesfully
IO.popen("flac --decode --stdout \"#{file}\"", 'rb'){|wav|
until wav.eof do
read_wav = wav.read
end
}
# the lame process, which fails
IO.popen("lame -V0 --vbr-new --verbose - -", 'r+b'){|lame|
lame << read_wav # if I comment out this, the process exits, instead of hanging
lame.close_write
until lame.eof do
read_lame << lame.read
end
}
編集#3
(最初の回答で)パイプの実装は信頼できないと述べたこのスタックオーバーフローを見つけました。cygwin
これはおそらく、実際には Windows に関連するものではなく (少なくとも直接的には)、cygwin とそのエミュレーションに関連している可能性があります。代わりに、 icyの回答に基づいて、次のコードを使用することを選択しました。
flac = "flac --decode --stdout \"#{file}\""
lame = "lame -V0 --vbr-new --verbose - \"#{dest}\""
system(flac + ' | ' + lame)