В течение некоторого времени я использовал эту пару команд для преобразования фрагмента видео в анимированный GIF, и ffmpeg
рассчитал для него наилучшую палитру:
ffmpeg -ss $START -i $IN_FILE -t $LENGTH -vf "fps=$FPS,scale=$WIDTH:-1:flags=lanczos,palettegen" palette.png
ffmpeg -ss $START -i $IN_FILE -i palette.png -t $LENGTH -filter_complex "fps=$FPS,scale=$WIDTH:-1:flags=lanczos [x]; [x] [1:v] paletteuse" output.gif
Это очень хорошо работает для локальных файлов, но если я начну использовать удаленные URL-адреса для $IN_FILE
, он загрузит необходимую часть дважды - один раз для генерации палитры, один раз для фактического преобразования.
Предварительная загрузка полного файла вообще не подлежит обсуждению - часто меня интересует очень небольшая последовательность в середине более длинного видео.
Я попытался загрузить только небольшую часть, используя -ss
и -t
и сохранив ее - без перекодирования - во временный файл:
ffmpeg -ss $START -i $IN_URL -t $LENGTH -vc copy -ac none temp.mkv
В этом случае я избегаю потери пропускной способности (загружается только соответствующая часть файла и только один раз), но поиск уже не точен, так как -ss
при вводе имеет только гранулярность ключевых кадров для поиска при выполнении потока копия
При теоретическом преобразовании в gif можно было бы выполнить дополнительный точный поиск и исправить это, но, похоже, нет способа получить исходную временную метку начала временного файла, сгенерированного выше, поэтому это невозможно рассчитать, где я должен -ss
при перекодировании в GIF. Я пытался играть с -copy_ts
, но ничего хорошего не получилось.
Тривиальное решение состоит в том, чтобы повторно закодировать на этом первом шаге (возможно, применяя масштабирование / повторную выборку в процессе, чтобы не делать это дважды позже), но я бы хотел избежать потери стоимости / качества одной дополнительной бесполезной кодировки.
Итак: как я могу выполнить преобразование видео с наилучшей палитрой в gif небольшой части потенциально большого сетевого файла, эффективно извлекая его (= загрузить один раз, только соответствующую часть), с точным поиском и без дополнительного перекодирования?