Существует ли общий метод или какая-то стратегия для перезапуска неудачного задания перекодирования с того места, на котором оно было остановлено в момент сбоя (или остановки по какой-либо причине)?
Например, если у меня есть 2-часовое задание по перекодированию, и оно терпит неудачу/вылетает через 1 час и 59 минут, есть ли способ, которым я могу просто выполнить эту работу в последние минуты и использовать прогресс, который у меня уже был, предполагая, что частично перекодированный файл до сих пор доступен?
Прямой вариант возобновления кодирования недоступен.
А что касается ручного перезапуска кодирования, то это тоже невозможно. Две причины:
1) при перекодировании в типичный контейнер, такой как MP4, индекс записывается после завершения кодирования. В частичном файле такого индекса не будет, если процесс неожиданно завершился, и поэтому существующий файл не может быть проанализирован.
2) Если вы не можете точно определить последний неповрежденный кадр, закодированный в частичном файле, ваше соединение не будет бесшовным.
Тем не менее, есть утомительный способ сделать это. Метод основан на использовании segment
мультиплексора. Вы кодируете в формат MPEG-TS, но сегментируете вывод по мере его создания. В случае сбоя задания вы проверяете несколько атрибутов и возобновляете кодирование на основе этих данных. Наконец, вы соединяете все сегменты вместе.
Шаг 1 : Кодировать и сегментировать
Для достижения наилучших результатов аудио и видео должны быть сделаны отдельно. На самом деле звук можно сделать без сегментации, так как он кодируется намного быстрее.
ffmpeg -i in.mp4 -c:a aac -vn job-audio.mp4
И для видео
ffmpeg -copyts -start_at_zero -ss 0 -i in.mp4 -c:v libx264 -an
-f segment -segment_time 0.01 -segment_time_delta 1
-muxpreload 0 -muxdelay 0 -mpegts_copyts 1
-segment_start_number 0 -segment_list files.ffcat
job-video%d.ts
Каждый вышеприведенный сегмент будет содержать одну GOP, поэтому никакие кадры в сегменте не зависят от кадров в других сегментах для воспроизведения.
Шаг 2 Определите точку возобновления
Предположим, задание завершается ошибкой при создании сегмента №5.
Во-первых, вы бежите
ffprobe "in.mp4" -show_entries stream=codec_type,start_time,duration -of compact
Это произведет показание, подобное этому
stream|codec_type=audio|start_time=0.000000|duration=356.309333
stream|codec_type=video|start_time=0.040000|duration=356.360000
Обратите внимание на время начала видеопотока.
Теперь запустите его для первого и последнего (неполного) сегмента.
ffprobe "job-video0.ts" -show_entries stream=codec_type,start_time,duration -of compact
stream|codec_type=video|start_time=0.080000|duration=10.000000
Вы видите положительное смещение 0,04 относительно видеопотока MP4. Назовем это начальным значением смещения
Теперь, для последнего потока
ffprobe "job-video5.ts" -show_entries stream=codec_type,start_time,duration -of compact
stream|codec_type=video|start_time=20.080000|duration=4.320000
Шаг 3. Возобновление кодирования
Итак, теперь вы бежите
ffmpeg -copyts -start_at_zero -ss {start_time of last segment - initial offset} -i in.mp4 -c:v libx264 -an
-f segment -segment_time 0.01 -segment_time_delta 1
-muxpreload 0 -muxdelay 0 -mpegts_copyts 1 -initial_offset {initial offset}
-segment_start_number {index number of last segment} -segment_list files-resume.ffcat
job-video%d.ts
Шаг 4. Соедините сегменты
У вас будет несколько .ffcat
файлов - от первого запуска и всех возобновленных запусков. Скопируйте записи из всех вторичных прогонов и добавьте их в первый файл. Избегайте дублирования.
Бег
ffmpeg -f concat -i files.ffcat -i job-audio.mp4 -c copy full.mp4
Если вы знаете конкретную часть файла, которую блокирует задание кодирования, вы можете использовать параметры и ffmpeg
для обхода точки блокировки. Подробнее об этих параметрах можно прочитать в документации к инструменту .--ss
-t
тонил7126
Гьян