Я написал прогу на пайтон для преобразования изобр...
बनाया गया: 28 जून 2026
का उपयोग करके उत्तर दिया गया GPT-5.5 Thinking द्वारा Chat01
बनाया गया: 28 जून 2026
का उपयोग करके उत्तर दिया गया GPT-5.5 Thinking द्वारा Chat01
Я написал прогу на пайтон для преобразования изображений и аудио в видео. на моем сервере используется видеокарта от нвидиа RTX4060. также я использую ffmpeg 8.1. Посмотри мой код и предложи что можно улучшить (может кодек), основная задача увеличить скорость создания видео
ffmpeg_image = (
FFmpeg()
.option('y')
.option('loop', '1') # зацикливаем изображение
.input(img_path)
.input(aud_path)
.output(segment_path, {
'c:v': 'h264_nvenc', # используем NVIDIA encoder вместо CPU
'c:a': 'aac',
'vf': 'scale=1280:720,fps=24',
't': str(duration),
'shortest': None,
'preset': 'p1', # preset для NVENC (p1-p7, p4 - баланс качества и скорости)
'rc': 'vbr', # режим контроля битрейта
'cq': '28', # качество сжатия (аналог crf для CPU)
})
)
Главный вывод: для статичной картинки + аудио быстрее всего не “подкрутить NVENC”, а перестать делать 24 одинаковых кадра в секунду. Сейчас строка:
python'vf': 'scale=1280:720,fps=24',
может быть главным тормозом: scale — CPU-фильтр, а fps=24 заставляет генерировать много одинаковых кадров.
Если тебе не принципиально, чтобы файл был именно 24 fps, ставь 1 fps. Для видео “картинка + звук” это нормально: картинка просто висит на экране, звук играет.
Пример:
pythonffmpeg_image = ( FFmpeg() .option('y') .option('hide_banner') .option('loglevel', 'error') .input(img_path, {'loop': '1', 'framerate': '1'}) .input(aud_path) .output(segment_path, { 'map': ['0:v:0', '1:a:0'], 'c:v': 'h264_nvenc', 'preset': 'p1', 'rc': 'constqp', 'qp': '30', 'r': '1', 'pix_fmt': 'yuv420p', 'c:a': 'aac', 'b:a': '128k', 't': str(duration), 'shortest': None, 'vf': 'scale=1280:720', }) )
Что изменилось:
python.input(img_path, {'loop': '1', 'framerate': '1'})
и
python'r': '1'
Вместо 24 кадров в секунду будет 1 кадр в секунду. Для 5-минутного ролика это примерно 300 кадров вместо 7200. Ускорение может быть очень заметным.
Тогда хотя бы задай входной framerate для картинки как 1, а уже потом делай fps=24:
python.input(img_path, {'loop': '1', 'framerate': '1'})
и фильтр:
python'vf': 'scale=1280:720,fps=24'
Это лучше, чем пускать looped image с дефолтной частотой. Но всё равно медленнее, чем 1 fps, потому что NVENC будет кодировать 24 кадра в секунду.
vbr + cq на constqp, если главная цель — скоростьСейчас у тебя:
python'rc': 'vbr', 'cq': '28',
Для максимальной скорости проще использовать:
python'rc': 'constqp', 'qp': '30',
Например:
python'rc': 'constqp', 'qp': '30',
qp можно подбирать:
text26–28 — лучше качество, больше размер 30–32 — быстрее/меньше размер, качество чуть хуже 34+ — заметнее сжатие
Для статичной картинки qp=30 или 32 обычно вполне нормально.
Если входной аудиофайл уже AAC и тебе подходит контейнер MP4, лучше:
python'c:a': 'copy'
Вместо:
python'c:a': 'aac'
Копирование потока убирает декодирование и повторное кодирование аудио; FFmpeg прямо описывает, что при codec copy нет операций decoding-filtering-encoding, пакеты просто переносятся в выходной файл. (FFmpeg)
Вариант:
python'c:a': 'copy',
Но если аудио бывает MP3/WAV/OGG/Opus и тебе нужен стабильный MP4, оставляй:
python'c:a': 'aac', 'b:a': '128k',
NVIDIA рекомендует для GPU-пайплайна держать кадры в GPU-памяти и использовать scale_cuda или scale_npp; в их примерах для FFmpeg используются -hwaccel cuda -hwaccel_output_format cuda, а для масштабирования — scale_cuda или scale_npp. (NVIDIA Docs)
Но у тебя вход — одна картинка, а не видео. Поэтому часто быстрее будет:
1280x720 картинку без scale.Самый практичный вариант: кэшировать подготовленные изображения.
Например:
textoriginal.jpg -> prepared_1280x720.jpg
И потом в FFmpeg уже не делать:
python'vf': 'scale=1280:720'
Это может дать больше пользы, чем перенос scale на GPU.
Проверь, есть ли у тебя scale_cuda или scale_npp:
bashffmpeg -filters | grep scale_cuda ffmpeg -filters | grep scale_npp
Если есть scale_cuda, можно попробовать:
python'vf': 'format=nv12,hwupload_cuda,scale_cuda=1280:720'
Если есть scale_npp:
python'vf': 'format=nv12,hwupload_cuda,scale_npp=1280:720'
Но для твоего кейса я бы сначала тестировал 1 fps и предварительный resize картинок.
Для скорости и совместимости оставляй:
python'c:v': 'h264_nvenc'
RTX 4060 относится к RTX 40 Series/Ada, а у Ada есть NVENC с AV1-кодированием; NVIDIA пишет, что карты Ada имеют NVENC с AV1 и что AV1 эффективнее H.264 по сжатию. (NVIDIA) Но для твоей задачи av1_nvenc я бы не ставил первым вариантом: он может дать меньший размер файла, но совместимость хуже, а скорость создания не обязательно будет выше.
То есть:
textнужна максимальная совместимость и скорость → h264_nvenc нужен меньший размер и современная платформа → av1_nvenc можно тестировать
Я бы начал вот с такого варианта:
pythonffmpeg_image = ( FFmpeg() .option('y') .option('hide_banner') .option('loglevel', 'error') .input(img_path, { 'loop': '1', 'framerate': '1', }) .input(aud_path) .output(segment_path, { 'map': ['0:v:0', '1:a:0'], 'c:v': 'h264_nvenc', 'preset': 'p1', 'rc': 'constqp', 'qp': '30', 'r': '1', 'pix_fmt': 'yuv420p', 'c:a': 'aac', 'b:a': '128k', 'vf': 'scale=1280:720', 't': str(duration), 'shortest': None, }) )
Если аудио уже AAC:
python'c:a': 'copy'
Самая быстрая схема:
text1. Один раз подготовить картинку 1280x720 2. Сохранить в кэш 3. Для видео использовать уже готовую картинку 4. Не использовать scale в основном ffmpeg-вызове
Тогда основной код:
pythonffmpeg_image = ( FFmpeg() .option('y') .option('hide_banner') .option('loglevel', 'error') .input(prepared_img_path, { 'loop': '1', 'framerate': '1', }) .input(aud_path) .output(segment_path, { 'map': ['0:v:0', '1:a:0'], 'c:v': 'h264_nvenc', 'preset': 'p1', 'rc': 'constqp', 'qp': '30', 'r': '1', 'pix_fmt': 'yuv420p', 'c:a': 'aac', 'b:a': '128k', 't': str(duration), 'shortest': None, }) )
Вот это, скорее всего, будет быстрее твоего текущего варианта.
Запусти FFmpeg с benchmark:
bashffmpeg -benchmark ...
Сравни 3 варианта:
textA. текущий: scale=1280:720,fps=24 B. framerate=1 + r=1 C. заранее resized image + r=1
Я бы ожидал такой порядок скорости:
textсамый быстрый: prepared image + 1 fps средний: framerate=1 + scale + 1 fps медленный: scale + fps=24
Главное: preset: p1 у тебя уже правильный для скорости. Больше всего ускорит не другой preset, а отказ от 24 fps и повторного масштабирования одинаковых кадров.