Эта проблема может быть легко решена путем использования графа фильтра с несколькими цепочками, что позволяет нам выполнять поиск / загрузку / фильтрацию только один раз и обрабатывать ее несколькими способами. Запрашиваемый / отфильтрованный поток подается как на генератор палитры, так и на фильтр приложения палитры, который использует его вместе с сгенерированной палитрой. Графически:
.--> palettegen [pal]---. input / | [0:v] -> fps -> scale -> split=2 [a][b] V with `-> [b] fifo [b] -> [b] [pal] paletteuse -> out.gif precise seek
что переводится как:
ffmpeg -ss $START -I $IN_URL -t $LENGTH -filter_complex "fps=$FPS,scale=$WIDTH:-1:flags=lanczos,split=2 [a][b]; [a] palettegen [pal]; [b] fifo [b]; [b] [pal] paletteuse" out.gif
Обратите внимание, что для использования одного и того же потока в качестве входных данных для двух отдельных веток конвейера необходимо использовать split
фильтр.
Редактировать :fifo
был добавлен благодарякомментарию @Gyan ; это необходимо, потому чтоpalettegen
нужно дождаться конца потока, прежде чем генерировать палитру, иpaletteuse
не может начать потреблять,[b]
прежде чем иметь палитру, следовательно, если видео достаточно велико, буферов по умолчанию для[b]
будет недостаточно, иffmpeg
начнется отбрасывание кадров. Решение состоит в том, чтобы добавитьfifo
посередине для обработки буферизации произвольного размера (необходимо соблюдать осторожность, чтобы не превышать длину видео, так как буферизация всего потока в памяти может облагаться налогом на доступную оперативную память).
(бесстыдный плагин: эту команду я сейчас использую в своем боте tele2gif_bot tube )
Самое главное, это рассказ о понимании команд, которые вы используете ; вторая команда, приведенная в вопросе, уже использовала сложный фильтр графа, но, когда я слепо скопировал его из Интернета, я не пытался понять синтаксис непрозрачного фильтра графа, поэтому мне не пришло в голову, что я просто немного его подправил было бы лучшим решением.