Как поймать исключение FFMPEG с помощью подпроцесса?

Я работаю над субтитрами, и в некоторых видео есть 1 дорожка субтитров, в других - 2 дорожки субтитров. Для тех, у кого 2, я использую 2-й (индекс = 1). Я пытаюсь автоматизировать это с помощью python.

Для файлов с двумя дорожками субтитров я использую:

-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, поэтому я добавил исключение, но оно кажется, это не волнует.

Как поймать исключение FFMPEG с помощью подпроцесса?

Поэтому я пытаюсь поймать эту ошибку и сказать: «Хорошо, в таком случае давайте вместо этого сделаем si=0».

Завершен ли подпроцесс с кодом выхода 0? Это немного странно, если это так - обычно 0 является кодом успеха ??

Mr R 14.05.2022 01:05

Да. Я предполагаю, что «ошибка», которую дает ffmpeg, не считается какой-то системной ошибкой, а просто считается «строкой», исходящей из вывода ffmpeg?

Faindirnomainzein 14.05.2022 01:10

В стороне: вы должны использовать subprocess.run и передавать список вместо строки, разделенной пробелом. Нет причин заводить вредные привычки =D

Cireo 14.05.2022 01:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

subprocess.call возвращает код возврата, он никогда не возникает.

Вероятно, вам нужен check_call, который вызовет 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.

Привет @Cireo - код получает нулевой код возврата - это действительно решит ??

Mr R 14.05.2022 01:13

Это вопрос к автору. Скриншот, как обычно, бесполезен, но, если бы мне пришлось угадывать, «Процесс завершен с кодом возврата 0» относится к скрипту Python, который они выполнили, и не имеет ничего общего с подпроцессами.

Cireo 14.05.2022 01:19

Изменение вызова для check_call устранило проблему. Большое спасибо. В таком случае есть ли смысл всегда использовать call вместо check_call?

Faindirnomainzein 14.05.2022 01:19

В последних версиях Python вы должны использовать run поверх любого из них. call полезен для команд, которые могут быть успешными или нет, и вам все равно, но вы хотите, чтобы они выполнялись, например. ls backup_dir/TODAY.txt

Cireo 14.05.2022 01:24

Другие вопросы по теме