Как стать автором
Обновить

Комментарии 84

Очень удобная штука! Используем в своем проекте для обработки более полутора тысяч видео.

И все всегда забывают указывать правильное цветовое пространство, чтобы плеерам не приходилось его угадывать. Поэтому совет: если лень разбираться с этим, то просто вставляйте эти опции в параметры кодирования видео, в большинстве случаев сойдёт:


-color_primaries:v bt709 -color_trc:v bt709 -colorspace:v bt709

А смысл? В 99% при разрешении видео SD и ниже - bt470, всё что выше - b709. Тут, правда, есть подводный камень - если делаешь апскейл SD-HD или даунскейл HD-SD, то лучше прописать преобразование в явном виде. А в остальных случаях особо и не надо.

Я как питонист воспитан, что явное лучше неявного, подводных камней будет поменьше)


Плюс в такой формулировке возникает вопрос, что такое SD, а что такое HD. Слегка увеличенное видео 722x578 — это уже HD или ещё SD? Или наоборот, слегка обрезанное видео 1278x718 — это уже SD или ещё HD? А если «кинематографичное» соотношение сторон 1280x536? А если кому-то приспичило сделать неквадратный пиксель 640x536? У всех ли плееров одинаковый алгоритм «угадывания»? А у браузеров? https://habr.com/ru/company/vdsina/blog/560224/


Я не хочу задаваться подобными вопросами, поэтому для удобства сделал себе в консоли переменную $BT709, которую теперь пихаю почти в любую команду ffmpeg: цветовое пространство в моих файлах указано, а если у кого-то видео отобразится некорректно, то это уже не мои проблемы)

Обычно считается по ширине - всё, что до 720 - SD, 721 и более - HD.

Проблема в том, что для этого надо учитывать входное цветовое пространство. То есть можно, конечно, по умолчанию ставить видеофильтр приведения к 709, но это, скорее костыль.

Посмотрел статью, на которую дана ссылка, и стал понимать. Дело в том, что я в основном имею дело с профессиональными программами работы с видео. И у них алгоритм именно такой - если цветовое пространство прописано в файле - работать в нём. Не прописано - смотрим по разрешению файла.

Если же данный алгоритм не гарантирован - то, конечно, лучше прописывать цветовое пространство в явном виде.

Немного напоминает ранние компьютерные видеоплейера, программисты которых в принципе не понимали - что такое чересстрочная развертка и как пиксель может быть неквадратным

ITU-R BT.470 же закончился, когда Москва отключила аналоговый ТВ, и то там был SECAM, а значит https://en.wikipedia.org/wiki/YDbDr

Вы вообще не понимаете, что несете.

Primaries между SD и HD разные (причем в SD может быть два типа, а вообще могут быть любые) -- это надо тоже проконтролировать отдельно от матрицы.

Это баг, что это надо указывать постоянно.

вы про map_metadata?

Может быть, я не знаю, как называется. Точка, где было снято видео.

Да, но не во всех случаях, это баг, новые метаданные не создаются.

Ряд видеокодеков поддерживают режим сжатия без потерь

помню игрался с тем как хранить видео, HuffYUV отжирает просто непомерно места и довольно паршиво сжимается силами ФС, зато практически моментально обрабатывается серверами youtube (после многочасового ожидания выгрузки на эти самые сервера конечно).

Я не так давно открыл для себя безпотерьный кодек utvideo. Сжатие гораздо лучше, чем HuffYUV, а скорость приблизительно такая же. ffmpeg в него умеет. А лучше всех из известных жмёт ffv1, правда он медленный, и как мне кажется, однопоточный

Математический lossless поддерживается в ffmpeg для AV1 (и даже AVIF), VP9, AVC, HEVC. Слышали про такие? Причем hevc и avc lossless даже с nvenc на Nvidia Turing.

А еще есть MJPEG 2000 lossless. И даже JPEG lossless и JPEG-LS и даже JPEG XL.

Одна команда в консоли заменяет десять минут редактирования в Premiere Pro!

Ага. и 2 суток курения мануалов, чтоб эту команду составить...


Кстати, еще прекрасный мультимедиа комбайн/фреймворк - это GStreamer. Тоже позволяет творить мультимедиа магию в консоли, и может быть встроен в ваши приложения.

Gstreamer ещё, кстати, используется в nvidia deepstream SDK. Т.е. при работе с jetson альтернатив, к сожалению, мало.

Если не указаны дополнительные параметры, то всё кодируется с настройками по умолчанию для MP3.

Не очень понял. А как вытащить аудиодорожку без перекодирования? Возможно ли это в принципе? Она же как-то уже закодирована, правильно? Во-первых, это по идее должно быть быстрее, а во-вторых, хочется без потери качества (а все эти кодирования туда-сюда по-любому могут что-то там портить).

Да, -c:a copy — только вот в mpg-файлах будет скорее всего не mp3, а что-то другое, а значит или придётся заранее узнавать кодек и выбирать правильный контейнер для него, или всё-таки перекодировать

ffmpeg -i позволяет тут же на месте узнать кодек

Вы хотели сказать ffprobe?!

Результат один и тот же. Разве что ffmpeg сетует, что нет выходного файла.

с хорошей вероятностью там будет AAC, и контейнер .m4a

а вообще, сам же ffmpeg расскажет, что там и чем пожато.

И скорее всего m4a контейнер неправильный и это скорее всего mp4. Для m4a надо отдельно команду.

Курите avidemux. Прекрасная программа-оболочка для ваших целей.

Я обнаружил, что chatGPT заменяет все подобные статьи и документацию по ffmpeg. Примерно понимая что ffmpeg может, просто спрашиваешь у чатгпт как это сделать, получаешь готовую команду, и делаешь.

можно прям так

Да. Точно.

Еще для быстрого редактирования без перекодирования удобен Avidemux, только нужно удалять контент между ключевыми кадрами

С перекодированием - тоже. С деинтерлейсингом, субтиррами, поворотами и прочими наворотами. Там возможностей - море.

мы оцифровали старую VHS-кассету в программе HandBrake

Это как? HandBrake для перекодирования видеофайлов, а не для видеозахвата.

У меня не получилось закодировать в H.265 с настройками максимального качества и уменьшением разрешения в одной команде

Эээээ. Что???

А вообще - статья мне напомнила классический рисунок "как нарисовать сову".

Не могу не посоветовать открытый Avidemux для этих же целей.

Няшненько и ванильненько, самое главное не упоминать про интерлейс, правильные пропорции кадра и frame accuracy, что-бы не спугнуть маленьких "я-ж погромистов".

Одна команда в консоли заменяет десять минут редактирования в Premiere Pro!

Эээ :) только всё наоборот: десять минут редактирования в Premiere Pro заменяет день курения мануалов для формирования "одной команды"

Вкурив команду, в последующем ее вызов будет занимать секунду. А 10 минут редактирования это всегда 10 минут редактирования...

И h265 через hls тоже:

ffmpeg -fflags nobuffer
-rtsp_transport tcp -stimeout 1000000
-i "rstp://ip/stream.265"
-vsync 0 -copyts -vcodec copy
-movflags frag_keyframe+empty_moov
-c:a aac -method POST -f hls
"https://a.upload.youtube.com/http_upload_hls?cid=YOUR_KEY&copy=0&file=index.m3u8"

И даже в HDR.

Эффекты это, конечно, хорошо, но ещё поддержку HEIF/HEIC

Видео-версия статьи за 6 минут:


Фразы вида "Программа - швейцарский нож в такой-то области..." уже изрядно надоели, как будто нельзя найти другую аналогию или мем.

Это самая главная библиотека в мире после GMP/GCC/Clang. А это компилятор.

Не спорю, но фраза "швейцарский нож" на Хабре и в статьях к опенсорсным программам уже приелась. Возможно только мне.

glibc: "Ну да, ну да. Пошла я нахер".

Ну да, есть же Microsoft libm (или в код windows нужно смотреть) https://github.com/amd/win-libm/blob/master/pow.asm#L108

libc++ в llvm есть тоже.

Musl, uClibc.

https://en.wikipedia.org/wiki/Bionic_(software)

А вот у GMP там только GNU MPRF и ARB. И то спорно.

Пересекаемся в разных постах))

glibc не имеет отношения непосредственно к c++. А Musl и uClibc не на столько популярны.

Альтернативы есть. У ffmpeg нет, даже близко. Gstreamer уступает в 10 раз, да и не имеет hdr zscale например. Что там ещё? Avisynth+? Смешно.

Да и в любом случае GMP бесконечная арифметика самая важная библиотека, без неё gcc это тыква.

Закину кирпич, пока не знаю в чей огород.

Когда работал с ffmpeg, была задача видео разных форматов приводить к одному формату, прожигать субтитры, изменять размер видео, склеивать видео из разных форматов, и так далее.

Вобщем, швейцарский нож да, инструмент огонь, но пытаясь собрать в одно целое видео разных форматов это как та картинка про CSS из грифинов. Постоянные артефакты, ограничения, дропы кадров, искажения, и прочее, и прочее, целое море всевозможных косяков с кодированием вылезло. Может быть готовить не умею.

Я к тому, что круто оно круто, но как и любой инструмент который пытается собрать воедино всё и сразу, это не просто взять и использовать, это всё-равно море работы по исследованию совместимостей, отладке, и прочему.

Но ffmpeg огонь в любом случае. Титаническая работа сделана.

Вот что он не любит - это собирать несколько клипов в один. Совершенно не его задача.

А вот чего мне у него действительно не хватает - некоего внутреннего скриптового языка, чтобы можно было внутри него формировать командную строку в зависимости от формата входного файла. Поэтому у меня большинство задач решается либо через bat'ник - запустил ffmpeg, получил параметры входного файла, распарсил выход, сформировал командную строку, запустил ffmpeg на обработку. Либо через самописные программы, делающие примерно то же самое, но когда нужно что-то более наворочанное.

Ну и, конечно, его библиотеки просто великолепны.

Вот что он не любит — это собирать несколько клипов в один. Совершенно не его задача.
Я собирал. Нужно сконвертировать файлы в формат TransportStream (ts), т.е. поток без глобального заголовка, где заголовок есть у каждого фрейма, затем файлы бинарно склеить (copy /b), затем обратно из ts в mp4. Всё это можно делать без перекодирования (-c:a copy -c:v copy).

Да не, можно, конечно. Но далеко не всякий формат поддерживает ts. А уже тем более это не работает в случае " пытаясь собрать в одно целое видео разных форматов", как в исходном комментарии.

Тут уже либо надо конвертить сперва в промежуточный формат и потом уже собирать всё это в кучу. Либо пытаться как-то извратиться через фрейм-сервера. Но этим лично я не занимался, поэтому не могу ничего конкретного сказать.

В исходном комментарии
задача видео разных форматов приводить к одному формату
То есть, вместо -c:v copy надо -c:v libx264 если кодек отличается.
Тут уже либо надо конвертить сперва в промежуточный формат и потом уже собирать всё это в кучу
Вы смешиваете в одну кучу контейнер и кодек. «Промежуточный формат» как контейнер — ничего страшного, это быстрое копирование потока. «Промежуточный формат» как кодек — не нужен, т.к. конвертить надо не в промежуточный, а сразу в окончательный h.264.

Но в целом, замечание справедливое. Если надо смонтировать совсем разные клипы последовательно в один файл, в командной строке это целый квест, когда в GUI-редакторах это банальное мышекликание.

Дайте пожалуйста пример команд чтобы склеить два ролика разных форматов (для человека который ffmpeg никогда не пользовался ) :)

ffmpeg -i clip1.avi clip1.ts
ffmpeg -i clip2.avi clip2.ts
copy /b clip1.ts + clip2.ts clip_result.ts
ffmpeg -i clip_result.ts -c:v copy -c:a copy clip_result.mp4

в первых двух командах не указываю -c:v copy -c:a copy на случай, если аудио/видео в разных кодеках

Ваша 3 команда это плохая идея. Объединять так нельзя. Есть спец. фильтры в ffmpeg

А я сперва жму в одинаковые форматы с одинаковым размером кадра, а потом делаю mkvmerge -o file.mkv file1 + file2 + fileN

Отдельный скриптовый язык не нужен, когда есть биндинги для питона.

А они есть? Всё, что я вижу в своём гугле, это просто обёртки над командной строкой, толку от которых почти нет

https://github.com/kkroening/ffmpeg-python

Толк от них в том, что бы не парсить вывод ffmpeg в первую очередь. А например удобно получить разрешение видео через api, список стримов и т.п.

Скажем вам нужно все что больше fullhd уменьшить вполовину, а все что меньше уменьшить на 80%. На cmd или баше это будет боль.

Это не биндинги, а распарсить ffprobe -print_format json тривиально и без таких библиотек, поэтому я их не использую


Ещё есть проблема, что это подразумевает два отдельных запуска (сперва ffprobe, потом ffmpeg), а между запусками свойства стримов имеют шанс внезапно поменяться — это было для меня проблемой, когда я пытался работать с RTSP-потоками IP-камер

Ну если нужны именно биндинги к либам, то https://pyav.org

Тут конечно личные предпочтения. Но если мне нужно написать пару циклов с несколькими условиями, то я ни при каких обстоятельствах не выберу баш.

Так и есть. Это считается библиотека, а значит очень все хитро. Т.е. предполагается, что ты сам пишешь код, а не пользуешься ffmpeg/ffprobe и уж тем более ffplay.

>Постоянные артефакты, ограничения, дропы кадров, искажения, и прочее, и прочее, целое море всевозможных косяков с кодированием вылезло. Может быть готовить не умею.

Обычно с ffplay/mpv нет проблем. VLC это баг на баге.

Графическая оболочка для работы с графическим же контентом, предпросмотром, и визуальным выбором режимов, когда будет?

В IrfanView же сделали. Один человек, между прочим, работал.

IrfanView - никакая не "оболочка", а полноценная программа с GUI. (Наличие у нее интерфейса командной строки не делает ее консольной программой.)

Мужики, а можно дать примеры команд для hardware-accelerated encoding ? С масштабированием , к примеру, с 3840x2160 до fullhd , желательно тоже аппаратным ?

В официальной документации есть страница trac.ffmpeg.org/wiki/HWAccelIntro

При запуске без параметров видно, с какими опциями скомпилен ваш ffmpeg.exe (например, --enable-nvenc).

В ком. строку добавляется

-c:v h264_nvenc
или
-c:v h264_cuvid
для NVidia

или для AMD
Windows: -c:v h264_amf / hevc_amf
Linux: h264_vaapi / hevc_vaapi

cuvid может быть как декодер (до -i), так и енкодер. А вот nvenc все сложнее. Это только енкодер. Для декодера используется программный h264, но можно добавить ускорение (-hwaccel cuda, имеено cuda, не nvdec, или другие). h264 при этом все равно активно используется.

Кто вдруг не знает, хочу посоветовать конвертер с аппаратным ускорение HEVC(h265) кодека на картах nvidia - nvenc. После попыток обработки большого количества домашнего видео 2.7k в 265 кодек с помощью ffmpeg случайно пришёл к нему. Скорость обработки кратно быстрее длительности ролика( условно, ролик в 1 минуту обрабатывается за 20-25 секунд ) на карте 1060. Если говорит о более низких разрешениях-там вообще полёт. С телефона не удобно, позже дополню ссылкой.

Да, хороший пакет тоже. Но ffmpeg поглощает его потихоньку. Осталось полная HDR манипуляция.

https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new
Вот тут указано, кто во что умеет сжимать. 1030 ни во что не умеет, если что. Потому что GT, а нужно GTX. Я разок так прокололся на покупке.

Драйвера 1030 не раскапывали? Или в ней физически блоков кодирования нет

Как я понял, она железно не умеет.

Мне вот было интересно возможно ли как-то спарить ffmpeg и smooth video project чтобы конвертировать 30 фпс стримы в 60 фпс через командную строку. Я в своё время игрался, не нашёл. Мб кто знает?

Это бесполезно. Без LG C9 и новее аппаратной упловнялки артефактов будет слишком много.

Напоминает ответы на форумах когда попытка разобраться зачем человеку что-то надо заменяет простой ответ в стиле "вот, сделай так, но разочаруешься"
Я транскодил стримы которые я смотрел с 30 фпс и мне было норм, артефактов было не так уж и много - тем более сильно зависит от стилистики контента. Хотелось бы и на отдачу это как-то запихнуть.

Давненько не было тут такого...

Подскажите кто что использует чтобы звук корректно растянуть из 23.976 в 25 кадров? Использовал раньше atempo, но на некоторых исходниках он заметно портит звук. Недавно попробовал rubberband, с ним пришлось долго параметры подбирать чтобы убрать одну проблему, правда в целом звук становится выше и несколько хуже...

Есть ли что-то проф.уровня именно в ffmpeg?

Даже не подозревал, что есть такая проблема.
Ведь звуковая дорожка идёт со своими параметрами (AAC, 192Kbps, 44.1KHz, 16-bit, stereo, например) и формально никак не связана с частотой кадров видео.

Для начала поймите 23.976 это на самом деле 24/1.001 и да это играет огромное значение.

Вот есть такое. https://toolstud.io/video/framerate.php?inputfps=23.976&compare=network&duration=60&duration_unit=seconds&outputfps=25

Это вы хорошо заметили... вот только я про это очень хорошо в курсе.

И если я меняю частоту видео, то я использую setpts + atempo, причем мои значения отличаются от тех, что по вашей ссылке (проверял что чуть лучше результат именно из-за того что нет ошибки округления т.к. 23.976 != 24/1001).

Как они хотят:
ffmpeg -i [input] -r 25 -filter:v "setpts=0.959*PTS" -y [output]
Как я пишу:
ffmpeg -i [input] -r 25 -filter:v"setpts=0.959040959*PTS" -y [output]

Почему?
24000/1001 = 23.976023976/25 = 0.959040959 и 25/23.976023976 = 1.042708333

Аналогично и по звуку

Предлагается:
ffmpeg -i [input] -filter:a "atempo=1.0427" -vn [output]
Я же делаю иначе:
ffmpeg -i [input] -filter:a "atempo=1.042708333" -vn [output]

Но сути это не меняет, звук-то портится. Поэтому и ищу вариант получше.

Пробовал (после тестов на слух) вариант с rubberband, искажения стали другими:
rubberband=tempo=1.042708333:pitch=1.042708333:pitchq=quality:smoothing=on:channels=apart:phase=independent:detector=percussive:transients=crisp

Вариант с тупым -r 25 не катит, т.к. видео заметно дергается...

Т.е. я не совсем не в теме, хотя это не мой профиль. И если у вас есть иные советы - напишите, думаю что не только мне будет полезно. Спасибо!

Считаю также важным отразить в примерах, что в зависимости от задачи стоит применять различные пресеты. Видеофайл, сжатый в H.264 с пресетом slower, будет примерно в 10 раз легче при таком же качестве, чем сжатый с пресетом ultrafast, но при этом процесс сжатия может быть до 10 раз медленнее. Также для новичков будет полезно знать, что пресеты veryslow и placebo в большинстве случаев не рекомендуются: экономия битрейта (в сравнении со slower) от них незначительная, обработка крайне медленная, могут быть проблемы при воспроизведении в некоторых плеерах.

Для сборки/разборки видео использую xvid4psp - удобная оболочка для ffmpeg.

Конечно он поддерживает не только xvid и psp. Есть сборки под win, macOS, Ubuntu/Mint

Зарегистрируйтесь на Хабре, чтобы оставить комментарий