У меня есть большой набор jpg, которые я хочу преобразовать в видео без потерь (или, по крайней мере, очень близко к без потерь, если время кодирования не намного выше, чем в противном случае).
Наивно я думал, что должен быть какой-то кодек, который может хранить каждый отдельный кадр jpg как есть (без повторного сжатия) и, возможно, добиться хорошего сжатия, заменив некоторые кадры просто информацией о дельте от предыдущего кадра. В моем случае есть много последовательностей кадров, которые идентичны друг другу или имеют между собой небольшую разницу.
Есть ли какой-нибудь кодек и подходящие настройки для ffmpeg, которые могут это сделать?
Вы можете просто мультиплексировать изображения JPG, чтобы сделать видео:
ffmpeg -framerate 30 -i input%03d.jpg -codec copy output.mkv
Обратите внимание, что если вы опустите , то к вводу будет применено -framerate
значение по умолчанию .-framerate 25
Вы можете использовать jpegtran
оптимизацию без потерь для каждого кадра, что может обеспечить значительную экономию размера файла:
mkdir outputdir
for f in *.jpg; do jpegtran -optimize -copy none -perfect -v "$f" > "outputdir/$f"; done
Теперь мультиплексируйте ffmpeg
, как показано выше.
Мультиплексор framehash можно использовать для сравнения уникального хэша каждого кадра, чтобы убедиться, что результат действительно без потерь:
$ ffmpeg -i input%03d.jpg -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0, 0, 0, 1, 460800, 29bcc2db3726c7dfec1826c5740f603f
0, 1, 1, 1, 460800, b5fdc23d93cbd043dc2b9290dc8378f0
0, 2, 2, 1, 460800, ee0709942f24b458fd2380d134dcb59d
...
$ ffmpeg -i output.mkv -map 0:v -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0, 0, 0, 1, 460800, 29bcc2db3726c7dfec1826c5740f603f
0, 1, 1, 1, 460800, b5fdc23d93cbd043dc2b9290dc8378f0
0, 2, 2, 1, 460800, ee0709942f24b458fd2380d134dcb59d
...
В приведенных выше примерах каждый связанный кадр для ввода и вывода использует один и тот же хэш, что гарантирует идентичность кадров и отсутствие потерь на выходе.
framemd5
должны достичь две команды, помимо простого перечисления хэшей? как мне получить дополнительное сжатие, когда таким образом идентифицируются идентичные кадры?Это приведет к выводу видео H.264 без потерь, в котором кадры будут использовать информацию из других кадров.
ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4
Объяснение вариантов:
-f image2
- указывает ffmpeg выбрать группу изображений-r 30
- говорит ffmpeg кодировать со скоростью 30 кадров (или изображений) в секунду (измените это на желаемую частоту кадров)-i %09d.jpg
- говорит ffmpeg использовать изображения от 000000000.jpg до 999999999.jpg в качестве входных данных. Измените 9
in %09d.jpg
на количество нулей в именах вашей последовательности изображений. Если ваши имена файлов, например, img0001.jpg, то это будет выражено как img%04d.jpg-vcodec libx264
- сообщает ffmpeg о необходимости вывода в файл, совместимый с H.264.-profile:v high444
- указывает libx264 использовать профиль High 4:4:4 Predictive Lossless, что позволяет кодировать без потерь-refs 16
- указывает libx264 хранить 16 изображений в буфере, чтобы на них могли ссылаться другие изображения в видео.-crf 0
- говорит libx264 выполнять кодирование без потерь-preset ultrafast
- сообщает libx264, что скорость кодирования важнее размера выходного файла.a.mp4
- указывает ffmpeg сохранять вывод в файле MP4 с именем a.mp4. Измените это на имя файла и формат, который вы хотите использовать.-f image2
здесь лишнее. Демультиплексор файла изображения должен использовать -framerate
вместо -r
. libx264 автоматически выберет подходящий -profile
для без потерь, и -preset
будет работать с файлами -refs
.-refs 5
в MOST, если вы не знаете, что в вашем контенте есть идентичные изображения, разделенные несколькими другими, это может привести к тому, что x264 потеряет ссылку до того, как доберется до дубликата. Выше ultrafast
, чем в режиме без потерь, мало что отличается, за исключением ~ 10% -ного прироста CABAC по сравнению с CAVLC (из-за высокой стоимости процессора при битрейтах, необходимых для без потерь). Серьезно, на каком-то лайв-экшене 720x480p60 (вывод с деинтерлейсом) superfast
было 28 ГБ, slower
было 27 ГБ. Если время кодирования не имеет значения, а время декодирования имеет значение, избегайте CABAC. Может даже -tune fastdecode
. Умеренное количество ссылок не помешает.-preset placebo
добавить несколько дополнительных долей процента.-vcodec libx265 -x265-params lossless=1
является эквивалентным вариантом. (Но по моему опыту (= запись презентаций слайд-шоу в Powerpoint), это не обязательно лучше, и это намного медленнее, чем h264). Оставайтесь с нами для AOMedia в следующем году AV1 / IETF NETVC1 / Xiph's Daala / что бы это ни было переименовано к тому времени ... в режиме без потерьВы можете создать avi
анимацию в виде серии png
изображений ( png
без потерь, поэтому jpeg => png
преобразование не должно ухудшать ваши изображения):
если ваши изображения названыimg_0001.jpg
ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec png video.avi
где «25» — частота кадров, которую вы хотите получить в результирующем видео. -start_number
не нужен, если он равен 1, но полезен, если ваш первый номер видео не равен 1.
Если вы хотите кодировать в mjpeg
командной строке высочайшего качества:
ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec mjpeg -qscale 1 video.avi
И прелесть в том, что вы можете преобразовать видео обратно в серию изображений:
ffmpeg -i video.avi "img_series_%04d.png"
ffmpeg -i video.avi "img_series_%04d.jpg"
и т.д...
Чтобы расширить ответ LordNeckbeard, да, просто мультиплексируйте данные JPEG в видеопоток MJPEG. Это будет наименьшее представление точной последовательности выходных изображений, даже несмотря на то, что MJPEG — ужасно неэффективный кодек по сегодняшним меркам. (без временной избыточности и даже без внутреннего предсказания.
Вы можете сделать MJPEG-видео с переменной частотой кадров, чтобы использовать дубликаты изображений во входных данных.
ffmpeg -framerate 30 -i input%03d.jpg -vf mpdecimate -codec copy output.mkv # doesn't work.
Хм, это не сработает, так как mpdecimate не будет работать со сжатыми данными, и мы не можем позволить ffmpeg декодировать, а затем повторно преобразовать данные изображения в jpeg без потерь и затрат ЦП.
Может быть, если вы заменили дубликаты исходных файлов jpg пустыми файлами с этим порядковым номером или что-то в этом роде?
Поскольку этот вопрос даже не новый, я не собираюсь тратить время на то, чтобы выяснить, как это сделать, если кто-то не ответит, чтобы спросить, как это сделать. Но поскольку MJPEG может помещаться в контейнер mkv, я уверен, что можно иметь файл, который не дублирует данные jpeg для повторяющихся кадров, а вместо этого просто не имеет выходного кадра для декодирования, пока последовательность дубликатов не будет над.
О, вот идея:
ffmpeg -framerate blah -input blah -vf mpdecimate -f mkvtimestamp_v2 mpdecimate.timestamps
Затем удалите (или отодвиньте в сторону) все jpeg для кадров, которые mpdecimate хочет удалить (возможно, у него есть какие-то параметры ведения журнала? Или -vf showinfo, и проанализируйте его, и переместите или жестко свяжите только те кадры, которые отображаются в его выводе, оставив позади упавшие JPEG-файлы?). мультиплексируйте это в MJPEG.mkv, затем сделайте что-нибудь с mkvmerge, чтобы заменить временные метки кадров в нем временными метками из mpdecimate.timestamps
.
Если бы вы использовали xcoding, а не просто мультиплексировали данные jpeg в MJPEG, это было бы НАМНОГО проще, поскольку вы просто использовали бы мою первую команду с mpdecimate и любым кодеком, кроме copy
, и это просто сработало бы (tm).
Я ничего из этого не пробовал, так как это был старый вопрос. Также причина, по которой я не заполнил пробелы в том, как на самом деле фильтровать ваш каталог jpeg на основе вывода mpdecimate или как на самом деле использовать поток меток времени.
Друг Джорджа
Друг Джорджа
Питер Кордес