Comments 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 может быть два типа, а вообще могут быть любые) -- это надо тоже проконтролировать отдельно от матрицы.
Это баг, что это надо указывать постоянно.
Метаданные умеет переносить? Геотэг, например.
Ряд видеокодеков поддерживают режим сжатия без потерь
помню игрался с тем как хранить видео, 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. Тоже позволяет творить мультимедиа магию в консоли, и может быть встроен в ваши приложения.
Если не указаны дополнительные параметры, то всё кодируется с настройками по умолчанию для MP3.
Не очень понял. А как вытащить аудиодорожку без перекодирования? Возможно ли это в принципе? Она же как-то уже закодирована, правильно? Во-первых, это по идее должно быть быстрее, а во-вторых, хочется без потери качества (а все эти кодирования туда-сюда по-любому могут что-то там портить).
Да, -c:a copy
— только вот в mpg-файлах будет скорее всего не mp3, а что-то другое, а значит или придётся заранее узнавать кодек и выбирать правильный контейнер для него, или всё-таки перекодировать
ffmpeg -i позволяет тут же на месте узнать кодек
с хорошей вероятностью там будет AAC, и контейнер .m4a
а вообще, сам же ffmpeg расскажет, что там и чем пожато.
Курите avidemux. Прекрасная программа-оболочка для ваших целей.
Я обнаружил, что chatGPT заменяет все подобные статьи и документацию по ffmpeg. Примерно понимая что ffmpeg может, просто спрашиваешь у чатгпт как это сделать, получаешь готовую команду, и делаешь.
можно прям так
Да. Точно.
Еще для быстрого редактирования без перекодирования удобен Avidemux, только нужно удалять контент между ключевыми кадрами
мы оцифровали старую VHS-кассету в программе HandBrake
Это как? HandBrake для перекодирования видеофайлов, а не для видеозахвата.
У меня не получилось закодировать в H.265 с настройками максимального качества и уменьшением разрешения в одной команде
Эээээ. Что???
А вообще - статья мне напомнила классический рисунок "как нарисовать сову".
Не могу не посоветовать открытый Avidemux для этих же целей.
Няшненько и ванильненько, самое главное не упоминать про интерлейс, правильные пропорции кадра и frame accuracy, что-бы не спугнуть маленьких "я-ж погромистов".
Одна команда в консоли заменяет десять минут редактирования в Premiere Pro!
Эээ :) только всё наоборот: десять минут редактирования в Premiere Pro заменяет день курения мануалов для формирования "одной команды"
А миллисекунды в имена файлов jpg-кадров до сих пор не умеет...
Эффекты это, конечно, хорошо, но ещё поддержку 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, была задача видео разных форматов приводить к одному формату, прожигать субтитры, изменять размер видео, склеивать видео из разных форматов, и так далее.
Вобщем, швейцарский нож да, инструмент огонь, но пытаясь собрать в одно целое видео разных форматов это как та картинка про 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
на случай, если аудио/видео в разных кодекахА я сперва жму в одинаковые форматы с одинаковым размером кадра, а потом делаю 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-камер
Так и есть. Это считается библиотека, а значит очень все хитро. Т.е. предполагается, что ты сам пишешь код, а не пользуешься ffmpeg/ffprobe и уж тем более ffplay.
>Постоянные артефакты, ограничения, дропы кадров, искажения, и прочее, и прочее, целое море всевозможных косяков с кодированием вылезло. Может быть готовить не умею.
Обычно с ffplay/mpv нет проблем. VLC это баг на баге.
Графическая оболочка для работы с графическим же контентом, предпросмотром, и визуальным выбором режимов, когда будет?
В IrfanView же сделали. Один человек, между прочим, работал.
Мужики, а можно дать примеры команд для hardware-accelerated encoding ? С масштабированием , к примеру, с 3840x2160 до fullhd , желательно тоже аппаратным ?
При запуске без параметров видно, с какими опциями скомпилен ваш 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
Кто вдруг не знает, хочу посоветовать конвертер с аппаратным ускорение HEVC(h265) кодека на картах nvidia - nvenc. После попыток обработки большого количества домашнего видео 2.7k в 265 кодек с помощью ffmpeg случайно пришёл к нему. Скорость обработки кратно быстрее длительности ролика( условно, ролик в 1 минуту обрабатывается за 20-25 секунд ) на карте 1060. Если говорит о более низких разрешениях-там вообще полёт. С телефона не удобно, позже дополню ссылкой.
https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new
Вот тут указано, кто во что умеет сжимать. 1030 ни во что не умеет, если что. Потому что GT, а нужно GTX. Я разок так прокололся на покупке.
Мне вот было интересно возможно ли как-то спарить 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
Безграничные возможности FFmpeg на примерах