У Twitch есть пост об этом. Они объясняют, что решили использовать собственную программу по нескольким причинам; одна из них заключалась в том, что ffmpeg не позволяет запускать разные экземпляры x264 в разных потоках, а вместо этого посвящает все указанные потоки одному кадру в одном выводе, прежде чем переходить к следующему выводу.
Если вы не делаете потоковую передачу в реальном времени, у вас больше роскоши. «Правильный» способ - это, вероятно, кодировать в одном разрешении только с размером GOP, указанным с -g, а затем кодировать другие разрешения, заставляя ключевые кадры в тех же местах.
Если вы хотите это сделать, вы можете использовать ffprobe, чтобы получить время ключевого кадра, а затем использовать сценарий оболочки или реальный язык программирования, чтобы преобразовать это в команду ffmpeg.
Но для большей части контента очень мало различий между наличием одного ключевого кадра каждые 5 секунд и двух ключевых кадров каждые 5 секунд (один принудительный, а другой из сцены). Это примерно средний размер I-кадра по сравнению с размером P-кадров и B-кадров. Если вы используете x264 с типичными настройками (единственная причина, по которой я думаю, что вы должны что-то сделать, чтобы повлиять на них, это если вы установите -qmin, как плохой способ запретить x264 использовать битрейт для простого контента; это ограничивает все типы кадров одним и тем же значением Я думаю) и получу такой результат, как средний размер I-кадра 46 кБ, P-кадр 24 кБ, B-кадр 17 кБ (в два раза меньше P-кадров), а затем дополнительный I-кадр каждую секунду со скоростью 30 кадров в секунду только 3% увеличение размера файла. Разница между h264 и h263 может состоять из 3% снижений, но одно не очень важно.
Для других типов контента размеры фреймов будут другими. Чтобы быть справедливым, речь идет о временной сложности, а не пространственной сложности, поэтому это не просто легкий контент против жесткого контента. Но, как правило, сайты потокового видео имеют ограничение по битрейту, а контент с относительно большими I-кадрами - это простой контент, который будет кодироваться с высоким качеством независимо от того, сколько дополнительных ключевых кадров добавлено. Это расточительно, но эти отходы обычно не будут замечены. Наиболее бесполезным случаем, вероятно, является видео, представляющее собой статичное изображение, сопровождающее песню, где каждый ключевой кадр точно такой же.
Одна вещь, в которой я не уверен, это то, как принудительные ключевые кадры взаимодействуют с ограничителем скорости, установленным с -maxrate и -bufsize. Я думаю, что даже у YouTube недавно были проблемы с правильной настройкой параметров буфера для обеспечения постоянного качества. Если вы просто используете настройки среднего битрейта, как это видно на некоторых сайтах (поскольку вы можете проверить параметры x264 в заголовке / атоме mov с помощью шестнадцатеричного редактора), тогда модель буфера не является проблемой, но если вы При работе с пользовательским контентом средняя скорость передачи битов побуждает пользователей добавлять черный экран в конце своего видео.
Параметр -g в Ffmpeg или любой другой используемый вами параметр кодировщика сопоставляется с параметром, специфичным для кодировщика. Таким образом, ключ -x264-params = GOPSIZE эквивалентен ключу -g GOPSIZE.
Одна из проблем, связанных с использованием обнаружения сцен, заключается в том, что вы предпочитаете ключевые кадры рядом с конкретными номерами по любой причине. Если вы определяете ключевые кадры каждые 5 секунд и используете обнаружение сцены, и происходит изменение сцены на 4,5, то это должно быть обнаружено, но тогда следующий ключевой кадр будет на 9,5. Если время будет увеличиваться, как это, вы можете получить ключевые кадры в 42,5, 47,5, 52,5 и т. Д. Вместо 40, 45, 50, 55. И наоборот, если в 5,5 произойдет изменение сцены, то будет ключевой кадр на 5 и 5,5 будет слишком рано для другого. Ffmpeg не позволяет вам указать «создайте ключевой кадр здесь, если в течение следующих 30 кадров не произойдет смена сцены». Однако тот, кто понимает C, может добавить эту опцию.
Для видео с переменной частотой кадров, когда вы не транслируете в прямом эфире, как Twitch, вы должны иметь возможность использовать изменения сцены без постоянного преобразования в постоянную частоту кадров. Если вы используете фильтр 'select' в ffmpeg и используете константу 'scene' в выражении, то вывод отладки (-v debug или несколько раз нажмите '+' во время кодирования) показывает номер изменения сцены. Вероятно, это отличается от числа, используемого x264, и не так полезно, но все же может быть полезным.
Процедура, вероятно, будет состоять в том, чтобы сделать тестовое видео, которое предназначено только для изменений ключевого кадра, но, возможно, может быть использовано для данных контроля скорости при использовании 2-проходного. (Не уверен, что сгенерированные данные вообще полезны для разных разрешений и настроек; данные дерева макроблоков не будут.) Преобразуйте их в видео с постоянной частотой кадров, но посмотрите эту ошибку о заикании вывода при уменьшении частоты кадров вдвое, если вы когда-нибудь решите использовать фильтр fps для других целей. Запустите его через x264 с нужным ключевым кадром и настройками GOP.
Затем просто используйте это время ключевого кадра с исходным видео с переменной частотой кадров.
Если вы допускаете совершенно сумасшедший пользовательский контент с 20-секундным промежутком между кадрами, то для кодирования с переменной частотой кадров вы можете разделить вывод, использовать фильтр fps, каким-то образом использовать фильтр выбора (возможно, создать действительно длинное выражение, которое имеет каждый ключевой кадр) ... или, возможно, вы можете использовать тестовое видео в качестве входных данных и либо декодировать только ключевые кадры, если эта опция ffmpeg работает, либо использовать фильтр выбора для выбора ключевых кадров. Затем масштабируйте его до нужного размера (для этого есть даже фильтр scale2ref) и наложите на него оригинальное видео. Затем используйте фильтр чередования, чтобы объединить эти обязательные ключевые кадры с исходным видео. Если это приводит к двум кадрам, которые находятся на расстоянии 0,001 секунды друг от друга, что не мешает фильтру чередования, то решите эту проблему самостоятельно с помощью другого фильтра выбора. Работа с ограничениями кадрового буфера для фильтра чередования может быть главной проблемой здесь. Все это может работать: использовать какой-то фильтр для буферизации более плотного потока (fifo filter?); обращайтесь к входному файлу несколько раз, чтобы он декодировался более одного раза, и кадры не нужно сохранять; использовать фильтр streamselect, который я никогда не делал, точно в моменты ключевых кадров; улучшить фильтр чередования, изменив его поведение по умолчанию или добавив опцию для вывода самого старого кадра в буфер вместо удаления кадра. что я никогда не делал, точно в моменты ключевых кадров; улучшить фильтр чередования, изменив его поведение по умолчанию или добавив опцию для вывода самого старого кадра в буфер вместо удаления кадра. что я никогда не делал, точно в моменты ключевых кадров; улучшить фильтр чередования, изменив его поведение по умолчанию или добавив опцию для вывода самого старого кадра в буфер вместо удаления кадра.