How to catch a FFMPEG exception with subprocess?

I’m doing some work on subtitles and some videos have 1 subtitle track, others have 2 subtitle tracks. For those that have 2, I use the 2nd one (index = 1). I’m trying to automate it with python.

For files with with 2 subtitle tracks, I use:

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

and for those with 1 subtitle track, I use:

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

I’m using this code:

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 ...')

But it doesn’t seem to care about the exception and just ends the loop whenever it meets a file with 1 subtitle and gives me the error anyway.

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!

As you can see in the error message above, it says: "Error initializing filter …. si=1" because it should be si=0 in the case of that specific file, which is why I added the exception, but it doesn’t seem to care about it.

enter image description here

So I’m trying to catch that error and say "ok, in that case, let’s do si=0 instead".

>Solution :

subprocess.call returns the returncode, it never raises.

You probably want check_call, which will raise a subprocess.CalledProcessError on non-zero returncodes.

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.

Leave a Reply