Обработка видео в несколько этапов, используя Python
стоит задача:
- Есть видео mp4, вес 500Мб, кодек h264, скаченное с телеграмм
- Надо это видео разрезать на две части, первая часть 2 секунды, вторая остаток
- Наложить на 5 кадр первой части видео текст и потом соединить первую и вторую части
- Все это должно сделаться на Питоне максимум за 1:30-2:00 минуты
Что получилось у меня:
- Видео разрезал
- Текст на первую часть наложил
- Соединяю и получаю не корректную длину видео
Что я заметил:
- Когда я разрезаю видео на две части и соединяю их обратно - все соединяется отлично, без косяков и т.п
- Как только я наложил текст на первую часть видео и пытаюсь соединить со второй частью - получаю не корректную длину итогового видео.
- Программа меня так же предупреждает о том, что dps < tps. Я проверил метаданные времени первой части видео с наложенным текстом и получил что dps иногда имеет значение меньше, чем tps, я проверил первую часть видео без текста, там все идет идеально, как надо. Видимо в этом причина не корректной длины итогового видео.
Прикладываю свой код:
# Команда для сохранения отрезанной части
command_save_cut_part = [
"ffmpeg",
"-ss",
"00:00:00", # Начальное время отрезанной части
"-i",
"record.mp4",
"-t",
"00:00:10", # Продолжительность отрезанной части
"-c:v",
"copy",
"-c:a",
"copy",
f"1.mp4"
]
# Выполнение команды для сохранения отрезанной части
subprocess.run(command_save_cut_part)
# Команда для сохранения оставшейся части видео
command_save_remaining_part = [
"ffmpeg",
"-ss",
"00:00:10", # Начальное время оставшейся части (после отрезанной части)
"-i",
"record.mp4",
"-c:v",
"copy",
"-c:a",
"copy",
f"{video_dir}/2.mp4"
]
# Выполнение команды для сохранения оставшейся части
subprocess.run(command_save_remaining_part)
# Пути к файлам
video_path = f"1.mp4"
frame_path = f"frame.png"
frame_with_text_path = f"frame_with_text.png"
# Параметры текста
text = str(123456789)
x_position = 5
y_position = 5
font_size = 8
font_color = "white" # Цвет текста белый
# Команда для извлечения пятого кадра
command_extract_frame = [
"ffmpeg",
"-i",
video_path,
"-vf",
"select=gte(n\,4)",
"-vframes",
"1",
frame_path
]
# Выполнение команды для извлечения кадра
subprocess.run(command_extract_frame)
# Команда для наложения текста на кадр
command_overlay_text = [
"ffmpeg",
"-i",
frame_path,
"-vf",
f"drawtext=text='{text}':x={x_position}:y={y_position}:fontsize={font_size}:fontcolor={font_color}",
frame_with_text_path
]
# Выполнение команды для наложения текста
subprocess.run(command_overlay_text)
# Команда для замены пятого кадра на кадр с текстом
command_replace_frame = [
"ffmpeg",
"-i",
video_path,
"-i",
frame_with_text_path,
"-filter_complex",
"[0:v][1:v]overlay=0:0:enable='eq(n,4)'",
"-codec:a",
"copy",
f"1_2.mp4"
]
# Выполнение команды для замены кадра в видео
subprocess.run(command_replace_frame)
# Удаление временных файлов
os.remove(frame_path)
os.remove(frame_with_text_path)
video_out_path = f'здесь мой путь'
success_file_path = os.path.join(os.path.dirname(video_out_path), "list.txt")
with open(success_file_path, 'w') as file:
file.write(f"file '1_2.mp4'\n"
f"file '2.mp4'\n")
output_video_path = f"total.mp4"
# Коррекция команды для объединения видео
command = [
'ffmpeg',
'-f', 'concat',
'-safe', '0',
'-i', 'list.txt',
'-c', 'copy',
'output_2.mp4'
]
# Выполнение команды для объединения видео
subprocess.run(command)
Может кто сталкивался с такой задачей и есть другие, быстрые варианты? Или может я делаю что-то не так?