3

Мы генерируем много миниатюрных 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 секунд. Я хотел бы максимально сократить время выполнения и желать пожертвовать большим качеством изображения ради скорости.

2 ответа2

2

Использование вами фильтров palettegen/paletteuse выполнение команды. Простой способ получить менее качественный GIF:

ffmpeg -f image2 -i "frames.%04d.jpg" output.gif

С дополнительным масштабированием:

ffmpeg -f image2 -i "frames.%04d.jpg" -vf scale=150:-1 output.gif

Вы также можете удалить кадры в выходном GIF-файле, т.е. сэмплировать кадры, чтобы не все из них были обработаны. Например, чтобы иметь только 1 FPS, используя фильтр fps :

ffmpeg -i "frames.%04d.jpg" -vf "fps=fps=1,scale=150:-1" output.gif
1

Мне было поручено сократить количество времени, необходимое для создания анимированного GIF-файла, как можно ближе к 30 кадрам в длину при ширине 150 пикселей. Большинство сгенерированных нами последовательностей имеют размер менее 1000 кадров. У нас было 15000 кадровых кадров, и нашим узлам рендеринга потребовалось 17 минут, чтобы создать этот ~ 30-кадровый GIF, что недопустимо медленно.

Мы использовали ffmpeg в качестве демультиплексора и добавили imagemagick. После нескольких часов экспериментов я пришел к следующим выводам:

  • Количество входных фреймов, которые вы запрашиваете у ffmpeg для обработки, является BY FAR наиболее эффективным входом с точки зрения скорости выполнения. Если использовать опцию 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 секунду, пропуская входные кадры:

# create text file which describes the ~30 input frames we want ffmpeg to process
seq -f "file 'left_frames.%04g.jpg'" 10000 500 25000 > tmp.txt

# generate the animated gif using ffmpeg only
ffmpeg -f concat -i tmp.txt -filter_complex "scale=150:-1:flags=lanczos,split=2 [a][b]; [a] palettegen [pal]; [b] fifo [b]; [b] [pal] paletteuse" output.gif

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .