Я работаю над субтитрами, и в некоторых видео есть 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, поэтому я добавил исключение, но оно кажется, это не волнует.
Поэтому я пытаюсь поймать эту ошибку и сказать: «Хорошо, в таком случае давайте вместо этого сделаем si=0».
Да. Я предполагаю, что «ошибка», которую дает ffmpeg, не считается какой-то системной ошибкой, а просто считается «строкой», исходящей из вывода ffmpeg?
В стороне: вы должны использовать subprocess.run
и передавать список вместо строки, разделенной пробелом. Нет причин заводить вредные привычки =D
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 - код получает нулевой код возврата - это действительно решит ??
Это вопрос к автору. Скриншот, как обычно, бесполезен, но, если бы мне пришлось угадывать, «Процесс завершен с кодом возврата 0» относится к скрипту Python, который они выполнили, и не имеет ничего общего с подпроцессами.
Изменение вызова для check_call устранило проблему. Большое спасибо. В таком случае есть ли смысл всегда использовать call вместо check_call?
В последних версиях Python вы должны использовать run
поверх любого из них. call
полезен для команд, которые могут быть успешными или нет, и вам все равно, но вы хотите, чтобы они выполнялись, например. ls backup_dir/TODAY.txt
Завершен ли подпроцесс с кодом выхода 0? Это немного странно, если это так - обычно 0 является кодом успеха ??