【发布时间】:2011-03-05 05:29:05
【问题描述】:
我希望那里的一些天才可以帮助我解决这个问题......
我正在使用 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 经验。
到目前为止,我有以下等价物,它设置了 2 个进程:
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)但我无法弄清楚(对于我的一生)是如何将两个输出/输入流串在一起,如与前两个解决方案。找了又找,所以想问问!
如果有人知道:
- 如何以与 Python 和命令行版本相同的最终结果连接两个流;或
- 实现我想要做的事情的更好方法。
附:基于上述内容的代码示例会很棒:) 或者我可以轻松翻译的类似过程的特定代码示例。
[更新]
经过考虑,我决定将我的特定场景作为两个单独的过程来处理;将合并的 WAV 输出到文件,然后使用该文件作为转换的输入。
但是,使用可用的子流程模块here,可以实现我想要的。
【问题讨论】:
-
IronPython,从 2.7 开始,包含一个完整的子流程实现。
标签: python ironpython stdout stdin pipe