【问题标题】:Reproduce PIPE functionality in IronPython在 IronPython 中重现 PIPE 功能
【发布时间】: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)但我无法弄清楚(对于我的一生)是如何将两个输出/输入流串在一起,如与前两个解决方案。找了又找,所以想问问!

如果有人知道:

  1. 如何以与 Python 和命令行版本相同的最终结果连接两个流;或
  2. 实现我想要做的事情的更好方法。

附:基于上述内容的代码示例会很棒:) 或者我可以轻松翻译的类似过程的特定代码示例。

[更新]

经过考虑,我决定将我的特定场景作为两个单独的过程来处理;将合并的 WAV 输出到文件,然后使用该文件作为转换的输入。

但是,使用可用的子流程模块here,可以实现我想要的。

【问题讨论】:

  • IronPython,从 2.7 开始,包含一个完整的子流程实现。

标签: python ironpython stdout stdin pipe


【解决方案1】:

Windows 具有命名管道,您可以在 IronPython 等 .NET 应用程序中使用它们。翻译 VB.NET 示例like this one 通常很简单。你经常可以找到类似这样的托管库,例如http://www.codeproject.com/KB/threads/dotnetnamedpipespart1.aspx

这是另一个在管道 api 周围创建包装器的项目。 http://omegacoder.com/?p=101

【讨论】:

  • 嗨,迈克尔,感谢您的回复。我知道我有 wav.StandardOutput 和 m4b.StandardInput 可用,但无论我尝试什么组合,我都无法获得有效;例如我希望它类似于 m4b.StandardInput.BaseStream = wav.StandardOutput.BaseStream - 但这会引发异常。
  • 如果您阅读了上面的 VB.NET 示例,您不会期望像赋值语句这样简单的东西可以工作。进程间通信很复杂。您可以将复杂性隐藏在类/模块中,但首先您需要了解所有内容并使其发挥作用。
  • 我确实阅读了这篇文章,谢谢你的链接。然而,复杂性让我相信一个在命令行和 Python 中都很简单的过程,在 .net 中必须有类似的解决方案。也许我错了,但我已经阅读了很多引用 Process 类中可用的 StandardOutput 和 StandardInput 方法的文章。当我找到解决方案时,我会继续搜索并更新我的帖子(无论多么复杂!)。再次感谢。
猜你喜欢
  • 2022-11-02
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 2014-07-15
  • 2019-07-01
  • 2010-10-16
  • 1970-01-01
  • 2014-02-13
相关资源
最近更新 更多