0

现在大多数 Matroska 视频文件 (.mkv) 都启用了标头压缩。这破坏了与硬件播放器的兼容性,因此我很久以前创建了一批“修复”该问题,方法是使用 mkvtoolnix 重新组装文件而不使用标头压缩。但奇怪的是,即使来源是正确的,该批次也不适用于某些 .mkv。只是打嗝没有规律...

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

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

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

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

代码的重要部分:

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.
4

2 回答 2

3

os.popen is deprecated, and I haven't used it, at least not the last few years, so I don't remember the details. But documentation indicates that you need to call os.wait() to wait for the subprocess to finish.

For subprocess.Popen you need to call wait() on that object to see if it has finished. If you do so before starting the next one, outputs will not be mixed. On the other hand, if you start all at once, you can use any number of processor cores, which would be nice. To not have mixed outputs you then need to create one output for each subprocess, by calling Popen() with a stdout argument pointing to a file you opened for the purpose. You'll get one logfile per conversion that way, which makes sense.

于 2012-04-22T05:08:05.320 回答
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 上运行)

于 2012-04-22T15:14:02.753 回答