Мы генерируем множество миниатюрных GIF-файлов, качество которых не так важно, как время, необходимое для их создания. Генерация высококачественных GIF-файлов с помощью ffmpeg очень хорошо освещена, но мне не сильно удастся выяснить, как генерировать низкокачественные как можно быстрее.
Вычисление палитры занимает большую часть времени выполнения с помощью следующей команды (взятой из ответа по многоцепочечному фильтру здесь: Как эффективно создать лучший палитра GIF из видео прямо из Интернета ):
ffmpeg -y -threads 8 -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter_complex "fps=24,scale=150:-1:flags=fast_bilinear,split=2 [a][b]; [a] palettegen [pal] fifo [b]; [b] [pal] paletteuse" output.gif
Время выполнения этой команды с 1000 кадрами составляет около 72 секунд. Примерно через 67 секунд проходит палитра, а затем она проходит через фактическое создание GIF в течение 5 секунд. Я хотел бы максимально сократить время выполнения и желать пожертвовать большим качеством изображения ради скорости.
[b]
этикетка. В любом случае, использование быстрой палитры примерно на 200⨉ медленнее, если судить по быстрому тесту. Не использовать его вообще не вариант для вас?ffmpeg -y -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter:v "scale=150:-1:flags=fast_bilinear" output.gif
Две проблемы с этим: 1) он сэкономил только 13 секунд (59 секунд вместо 72), и 2) я не уверен на 100%, что эта команда полностью исключает вычисления палитры (только то, что вычисление палитры, которое я указывал ранее, не включено ).ffmpeg -i <input> <scale> <output.gif>
,Ответы:
Ваше использование
palettegen
/paletteuse
фильтры замедляют выполнение команды. Простой способ получить менее качественный GIF:С дополнительным масштабированием:
Вы также можете удалить кадры в выходном GIF-файле, то есть сэмплировать кадры, чтобы не все из них были обработаны. Например. иметь только 1 FPS выход, используя
fps
фильтр:источник
fps
фильтр названfps
так что это эквивалентно. Если ваш источник 120fps, вам нужно указать-framerate 120 -i "frames…"
потому что по умолчанию для ввода 24.Мне было поручено сократить количество времени, необходимое для создания анимированного GIF-файла, как можно ближе к 30 кадрам в длину при ширине 150 пикселей. Большинство сгенерированных нами последовательностей имеют размер менее 1000 кадров. У нас была последовательность кадров 15000, и наши узлы рендеринга принимали 17 минут чтобы создать этот ~ 30-кадр GIF, который неприемлемо медленный.
Мы использовали ffmpeg в качестве демультиплексора и добавили imagemagick. После нескольких часов экспериментов я пришел к следующим выводам:
Количество входных кадров, которые вы просите обработать ffmpeg: Вдали самый впечатляющий вклад с точки зрения скорости исполнения. Если использовать опцию concat demuxer для пропуска входных кадров, это даст наибольшую разницу в производительности. Взяв каждый 5-й кадр, я смог сократить общее время вычислений до 1 минута 45 секунд с высококачественным масштабированием Ланцоша и вычислением палитры для каждого кадра. Создание нашего 30-кадрового предварительного просмотра теперь занимает менее 1 секунды ,
Алгоритм масштабирования был следующим по значимости фактором, влияющим на производительность (но далекая секунда). Использование fast_bilinear вместо lanczos сэкономило 150 секунд вычислительного времени на всех 15 000 кадров.
Наименее влиятельной переменной были вычисления палитры, и это варьировалось в зависимости от алгоритма масштабирования. Более 15 000 кадров с использованием lanczos, мы сэкономили около 17 секунд времени выполнения, если исключили вычисления палитры. Используя fast_bilinear, мы сэкономили около 75 секунд времени выполнения.
Поскольку алгоритм масштабирования и вычисления палитры были незначительны, мы в итоге сохранили их с высочайшим качеством. Мы сократили время вычислений с 17 минут до 1 секунды, в основном, указав ffmpeg пропускать чтение входных файлов.
КЛЮЧЕВОЙ TAKEAWAY: ПРОХОДНЫЕ КАДРЫ И ПРОХОДНЫЕ КАДРЫ
Причина, по которой наш процесс занял так много времени, заключается в том, что удаление кадров не помогает времени выполнения при использовании демультиплексора image2. Если вы гадите с
-r
флаг иfps
Фильтр, вы будете влиять на количество кадров, которые появляются в конечном GIF, но ffmpeg, кажется, все еще что-то делает со всеми 15 000 входных кадров.Единственный способ пропустить входные кадры ffmpeg - использовать
concat
демультиплексор.Вот как я теперь генерирую высококачественные анимированные GIF-эскизы на своем компьютере разработчика менее чем за 1 секунду, пропуская входные кадры:
источник