在 IronPython 中重现 PIPE 功能
我希望有一些天才可以帮助我解决这个问题...
我正在使用 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 通过管道传输到 stdout,而 NeroAACEnc 从 stdin 读取,即 |将他们结合在一起。
然后我将整个解决方案迁移到 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()
我知道这 2 个进程启动(我可以在任务管理器中看到 Nero 和 Sox),但我无法弄清楚(对于我的一生)是如何将两个输出/输入流串在一起,就像前两个解决方案一样。我查了又查,所以我想问一下!
如果有人知道:
- 如何加入两个流,其最终结果与 Python 和命令行版本相同;或
- 实现我想做的事情的更好方法。
PS 基于上述的代码示例将非常棒:)或者我可以轻松翻译的类似过程的特定代码示例。
[更新]
经过考虑,我决定将我的特定场景作为两个单独的进程来处理;将合并的 WAV 输出到文件,然后使用该文件作为转换的输入。
但是,使用可用的子进程模块 这里。
I am hoping some genious out there can help me out with this...
I am using sox to merge and resample a group of WAV files, and pipe the output directly to the input of NeroAACEnc for encoding to AAC format.
I originally ran the process in a script, which included:
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
This worked as expected. The '-' in the comand line translates as 'Pipe/redirect input/output (stdin/stdout)' - So Sox pipes to stdout, and NeroAACEnc reads from stdin, the | joins them together.
I then migrated the whole solution to Python, and the equivalent command became:
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)
This also worked like a charm, exactly as expected. Slightly more convoluted, but hey :)
Well now I have to move it to IronPython, and the Subprocess module isn't available (the partial implementation that is, doesn't have Popen/PIPE support - plus it seems silly to add a custom library when there is probably a native alternative). UPDATE The partial module DOES support Popen and PIPE, I mis-read it. It is possible to extract the specifics for the .net/IronPython solution from this module (see update below)
I should mention here, that I opted for IronPython over C#, because I am comfortable with Python now - however, there is a chance of moving it again later to C# native, and I am using IronPython to ease myself into it :) I have no C# or .net experience.
So far I have the following equivalent, that sets up the 2 processes:
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()
I know that these 2 processes start (I can see Nero and Sox in the task manager) but what I can't figure out (for the life of me) is how to string the two output/input streams together, as with the previous two solutions. I have searched and searched, so I thought I'd ask!
If anyone knows either:
- How to join the two streams with the same net result as the Python and Commandline versions; or
- A better way to acheive what I am trying to do.
P.S. A code sample based off the above would be awesome :) or a specific code example of a similar process that I can easily translate.
[UPDATE]
After consideration, I resolved to handle my particular scenario as two seperate processes; outputting the merged WAVs to a file, then using that file as the input for the conversion.
However, it is possible to acheive what I wanted, using the subprocess module available here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Windows 具有命名管道,您可以从 IronPython 等 .NET 应用程序中使用它们。翻译 VB.NET 示例通常很简单像这样。您经常可以找到此类内容的托管库,例如 http://www.codeproject。 com/KB/threads/dotnetnamedpipespart1.aspx
这是另一个围绕管道 api 创建包装器的项目。 http://omegacoder.com/?p=101
Windows has named pipes and you can use them from .NET applications like IronPython. It is usually straightforward to translate VB.NET examples like this one. You can often find managed libraries for things like this, for instance http://www.codeproject.com/KB/threads/dotnetnamedpipespart1.aspx
Here is another project to create a wrapper around the pipe api. http://omegacoder.com/?p=101