让popen与mkvtoolnix一起工作?

时间:2012-04-21 20:59:17

标签: python python-3.x popen mkv

现在大多数Matroska视频文件(.mkv)都启用了标头压缩功能。这打破了与硬件播放器的兼容性,因此我很久以前就通过使用mkvtoolnix重新组装文件而不使用标头压缩来创建批处理。 但奇怪的是,即使源是正确的,批处理对某些.mkv也不起作用。打嗝中没有任何模式...

因此我今天开始编写一个小的Python 3.2脚本,其唯一目的是遍历CWD中的.mkv文件,并使用它们作为参数来调用mkvtoolnix-.exe使用参数。我尝试在我准备好的命令上同时使用os.popen()和os.system(),虽然system()似乎误解了命令,但在不应该删除的情况下删除双引号,即使在转义时,popen似乎至少工作了位。

这就是我的问题。现在执行脚本,它会为文件夹中的每个.mkv文件创建一个.mkv_fix文件,这很好,但是它的大小只是原始文件的一小部分而且无法播放。对我来说,似乎popen称.exe很好,但几乎立即终止它,只剩下一个未完成的文件。

我已将mkvtoolnix windows可执行文件作为来自here的7zip存档,并将它们放在脚本CWD的子目录中。

我还应该注意,从批处理调用时,可执行文件会生成控制台输出,而.py脚本不是这种情况。

代码的重要部分:

for file in glob.iglob('*.mkv'):
    if file.count('_fix') == 0:
        print(file)
        convertCMD = '"{0}\mkvtoolnix\mkvmerge.exe" -o "{1}_fix" --engage keep_bitstream_ar_info -A -S --compression -1:none "{1}" -D -S --compression -1:none "{1}" -A -D "{1}"'.format(os.getcwd(),file)
        os.popen(convertCMD)
        print('Converted '+file)

感谢任何形式的帮助。

其他信息:

通常的mkvtoolnix输出:

mkvmerge v5.5.0 ('Healer') built on Apr  6 2012 21:43:24
'F:\$PRECONVERT\MKVFILENAME': Using the demultiplexer for the format 'Matroska'.
'F:\$PRECONVERT\MKVFILENAME': Using the demultiplexer for the format 'Matroska'.
'F:\$PRECONVERT\MKVFILENAME': Using the demultiplexer for the format 'Matroska'.
'F:\$PRECONVERT\MKVFILENAME' track 0: Using the output module for the format 'MPEG-4'.
'F:\$PRECONVERT\MKVFILENAME' track 1: Using the output module for the format 'Vorbis'.
'F:\$PRECONVERT\MKVFILENAME' track 2: Using the output module for the format 'Vorbis'.
'F:\$PRECONVERT\MKVFILENAME' track 3: Using the output module for the format 'text subtitles'.
'F:\$PRECONVERT\MKVFILENAME' track 4: Using the output module for the format 'text subtitles'.
The file 'F:\$PRECONVERT\MKVFILENAME.mkv_fix' has been opened for writing.
Progress: 0%
Progress: 16%
Progress: 39%
Progress: 56%
Progress: 78%
Progress: 96%
Progress: 100%
The cue entries (the index) are being written...
Muxing took 3 seconds.

2 个答案:

答案 0 :(得分:3)

os.popen已被弃用,我没有使用它,至少在最近几年没有使用过,所以我不记得细节了。但是文档表明你需要调用os.wait()来等待子进程完成。

对于subprocess.Popen,您需要在该对象上调用wait()以查看它是否已完成。如果在开始下一个之前这样做,输出将不会混合。另一方面,如果你一次启动,你可以使用任意数量的处理器内核,这将是不错的。要没有混合输出,则需要为每个子进程创建一个输出,方法是使用stdout参数调用Popen(),该参数指向为此目的打开的文件。每次转换都会得到一个日志文件,这是有道理的。

答案 1 :(得分:1)

我写了一个脚本,我每天使用它来将一些.srt字幕复制到一个mkv文件。
这是相关的代码:

import subprocess

mkvmerge_args = [
    mkvmerge_path,
    '-o',
    dest_file_path,
    original_file,
    #other arguments...
    ]

returncode = subprocess.call(mkvmerge_args)

(在我的Ubuntu Server机器上完美运行,它也适用于Windows)

相关问题