如何使用子进程捕获 FFMPEG 异常?

How to catch a FFMPEG exception with subprocess?

我正在做一些字幕方面的工作,一些视频有 1 个字幕轨道,其他视频有 2 个字幕轨道。对于那些有 2 个的,我使用第二个(索引 = 1)。我正在尝试使用 python.

使其自动化

对于有 2 个字幕轨道的文件,我使用:

-vf "subtitles='file.mkv':si=1

对于有 1 个字幕轨道的,我使用:

-vf "subtitles='file.mkv':si=0

我正在使用此代码:

for mkv in all_mkvs:
    try:
      subprocess.call(f'ffmpeg -i ... -vf "subtitles='file.mkv':si=1 ...')
    except:
      subprocess.call(f'ffmpeg -i ... -vf "subtitles='file.mkv':si=0 ...')

但它似乎并不关心异常,只要遇到带有 1 个字幕的文件就结束循环,并且无论如何都会给我错误。

Press [q] to stop, [?] for help
[Parsed_subtitles_0 @ 0000011af4912880] Shaper: FriBidi 1.0.10 (SIMPLE) HarfBuzz-ng 2.7.2 (COMPLEX)
[Parsed_subtitles_0 @ 0000011af4912880] Unable to locate subtitle stream in ./test/349.mkv
[AVFilterGraph @ 0000011af623d880] Error initializing filter 'subtitles' with args './test/349.mkv:si=1'
Error reinitializing filters!
Failed to inject frame into filter network: Operation not permitted
Error while processing the decoded data for stream #0:3
Conversion failed!

正如您在上面的错误消息中看到的那样,它说:“初始化过滤器时出错.... si=1”,因为对于该特定文件,它应该是 si=0,这就是我添加的原因例外,但它似乎并不关心它。

所以我试图捕获该错误并说“好的,在这种情况下,让我们改为 si=0”。

subprocess.call returns 返回码,它永远不会引发。

您可能需要 check_call,这将在 non-zero 返回码上引发 subprocess.CalledProcessError

https://docs.python.org/3/library/subprocess.html

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

Run the command described by args. Wait for command to complete, then return the returncode attribute.

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

Run command with arguments. Wait for command to complete. If the return code was zero then return, otherwise raise CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute. If check_call() was unable to start the process it will propagate the exception that was raised.