在IronPython中重现PIPE功能

1 投票
1 回答
1169 浏览
提问于 2025-04-16 13:02

我希望能有聪明人帮我解决这个问题...

我正在使用sox工具来合并和重新取样一组WAV文件,然后把输出直接传给NeroAACEnc进行AAC格式的编码。

最开始我是在一个脚本中运行这个过程,内容包括:

sox.exe d:\audio\1.wav d:\audio\2.wav d:\audio\3.wav -c 1 -r 22050 -t wav - | neroAacEnc.exe -q 0.5 -if - -of test.m4a

这个方法按预期工作。命令行中的'-'表示“管道/重定向输入/输出(stdin/stdout)”——所以Sox把数据输出到标准输出,NeroAACEnc从标准输入读取,|符号把它们连接在一起。

后来我把整个解决方案迁移到了Python,等效的命令变成了:

from subprocess import call, Popen, PIPE
runwav = Popen(['sox.exe', 'd:\audio\1.wav', 'd:\audio\2.wav', 'd:\audio\3.wav', '-c', '1', '-r', '22050', '-t', 'wav', '-'], shell=False, stdout=PIPE)
runm4b = call(['neroAacEnc.exe', '-q', '0.5', '-if', '-', '-of', 'test.m4a'], shell=False, stdin=runwav.stdout)

这个方法也完美运行,和之前一样。虽然稍微复杂了一点,但没关系 :)

现在我需要把它移到IronPython上,而Subprocess模块不可用(部分实现没有Popen/PIPE支持——而且似乎添加一个自定义库没必要,因为可能有本地的替代方案)。更新 其实这个部分模块是支持Popen和PIPE的,我看错了。可以从这个模块中提取出适用于.net/IronPython的具体内容(见下面的更新)

我在这里要提一下,我选择IronPython而不是C#,因为我现在对Python比较熟悉——不过以后可能会再转到C#原生,所以我用IronPython来慢慢适应 :) 我没有C#或.net的经验。

到目前为止,我有以下等效的代码,设置了这两个进程:

from System.Diagnostics import Process
wav = Process()
wav.StartInfo.UseShellExecute = False
wav.StartInfo.RedirectStandardOutput = True
wav.StartInfo.FileName = 'sox.exe'
wav.StartInfo.Arguments = 'd:\audio\1.wav d:\audio\2.wav d:\audio\3.wav -c 1 -r 22050 -t wav -'       
wav.Start()

m4b = Process()
m4b.StartInfo.UseShellExecute = False
m4b.StartInfo.RedirectStandardInput = True
m4b.StartInfo.FileName = 'neroAacEnc.exe'
m4b.StartInfo.Arguments = '-q 0.5 -if - -of test.m4a'
m4b.Start()

我知道这两个进程已经启动(我在任务管理器中看到了Nero和Sox),但我搞不清楚(真是费劲)怎么把这两个输出/输入流连接起来,就像之前的两个解决方案那样。我搜索了很久,所以我想问问!

如果有人知道:

  1. 怎么把这两个流连接起来,达到和Python和命令行版本一样的效果;或者
  2. 有没有更好的方法来实现我想做的事情。

附言:如果能给个基于上述内容的代码示例就太好了 :) 或者一个类似过程的具体代码示例,我可以轻松转换。

[更新]

经过考虑,我决定把我的特定场景处理成两个独立的进程;先把合并后的WAV输出到一个文件,然后再用这个文件作为转换的输入。

不过,使用可用的subprocess模块,实际上是可以实现我想要的,具体可以在这里找到。

1 个回答

1

Windows系统有一种叫做命名管道的东西,你可以在像IronPython这样的.NET应用程序中使用它。把VB.NET的例子像这个转换过来通常很简单。你经常可以找到一些管理库来处理这些事情,比如http://www.codeproject.com/KB/threads/dotnetnamedpipespart1.aspx

这里还有一个项目,可以用来创建一个包裹在管道API周围的工具。http://omegacoder.com/?p=101

撰写回答