Кстати, насчёт 60 fps - небольшое отступление. Есть распространённое заблуждение, что для видео нужно 25-30 кадров в секунду, а 60 нужны только, если будешь потом вдвое замедлять. Это пример так называемого bullshit'а. 25-30 кадров это минимальный frame rate, позволяющий видеть видео как "плавное", но глаз способен различать куда больше, и он офигенно наслаждается этим. Погуглите 60 fps видео, напр., вот это: https://www.youtube.com/watch?v=rql_F8H3h9E, или даже специальные сравнения 60 и 30: https://www.youtube.com/watch?v=IrK5cDU9AIA . В общем, если камера может делать 60, то необходимо это использовать, это просто ругой уровень качества.
Кстати, есть разница между 60p и 60i. i-это ненастоящие кадры в секунду, а интерполированные. Кадры чередуются, в одном идёт одна половина изображения (скажем, чётные горизонтальные сканлинии), а в следующем, скажем, нечётные. Эта буква "p" важна.
Ещё момент: для 60 fps при таком же "ощущаемом" качестве нужен более высокий битрейт. Я экспериментировал, и вывел для себя, что примерно 9-12 MBit/sec даёт приемлемое качество для 1080p60 (1920x1080 @ 60p), а 3 MBit/sec - это минимальное качество, которое уже выглядит плохо, но всё ещё сохраняются какие-то прелести высокой частоты кадров. Я для себя выбрал такую стратегию:
*) в 3 MBit/sec можно кодировать бросовые видео, когда плевать, получит ли зритель удовольствие от просмотра (например, информативные туториалы),
*) в 12 MBit/sec кодировать всё остальное, когда хочется хорошего качества,
*) но: в 9 MBit/sec кодировать, если хочется хорошего качества, но уж очень жалко места на диске. Как, скажем, пример с полуторочасовым исходником. Разница между 9 MBit/sec и 12 MBit/sec приводит к разнице между 6GB и 8GB в конечном файле.
Как кодировать? Я не разбираюсь в теме, но один мой друг посоветовал Sony Vegas (я не буду показывать пальцем, но, наверное, ты понял, что я о тебе ;)), и пробовал использовать его.
С ним такая проблема: он начинает глючить, когда работы слишком много. Downsample, чтобы уменьшить разрешение он не может делать вообще (виснет, падает с ошибками), но даже простое кодирование ему не под силу, в случае больших файлов. Он говорит, что работа займёт 18 часов, где-то на 5 часу вдруг перестают двигаться проценты прогресса (и потом этот процесс никогда не заканчивается), потом перезапускаешь, он работает 10 часов, и грязно виснет, и т.п. В общем, накопилось достаточно фрустрации, чтобы поискать достойную альтернативу.
Достойной альтернативой оказался опенсоурсный ffmpeg, который можно собрать самому, а можно скачать готовую сборку. Утилита для командной строки. Она может кодировать, может также делать какие-то простые преобразования. Я рассмотрю мой пример с 1.5 часовым видео, которое я склеивал из 6 кусочков.
ffmpeg -i C0001.MP4 -i C0002.MP4 -i C0003.MP4 -i C0004.MP4 -i C0005.MP4 -i C0006.MP4 -filter_complex concat=n=6:v=1:a=1 -c:v libx264 -crf 20 -c:a aac -b:a 192k Result.mp4
Параметр качества - это
-crf 20
. По умолчанию, кажется, 22. Чем ниже число, тем выше качество. 20 даёт как раз примерно 9-12 MBit/sec на 1080p60, то, что мне нужно. Считается, что ниже 17-18 для человеческого глаза разница в качестве заметна не будет, что подтверждается моими тестами. Уменьшение или увеличение числа на 6 приводит к изменению битрейта примерно вдвое. Но использование такого числа хорошо тем, что оно определяет качество, т.е. не нужно будет пересчитывать, какой же нужен битрейт, если у вас другой размер видео или другая частота кадров.Кодирование заняло 5 часов. Отлично!
Но я решил пойти немножко дальше... я заметил, что он всё равно кушал 100% CPU, значит, он не использовал чип моей видеокарты (GPU), а использовать GPU должно быть эффективнее.
Мой настольный компьютер имеет такие железки:
*) NVIDIA GeForce GTX 645. Это бюджетная маленькая карточка для системных блоков с низкой мощностью, ей нужно до 130W, поэтому она подходит для системных блоков до 450W... если у вас SSD, и нет вращающихся хардов, то я бы и на 350W не побоялся её поставить; я покупал вариант от Dell'а (вроде такого) - он хорош тем, что ей не нужно дополнительное питание и ей хватает одного слота. С такими ограничениями это лучшая видеокарта из тех, что я нашёл, но она таки слабая и дешёвая по сравнению с крутыми геймерскими. У жены стоит GTX 960, и это уже совсем другой уровень.
*) Intel Core i7-2600 @ 3.40 GHz
Для того, чтобы
ffmpeg
работал с GPU, нужны три вещи:*) Видеокарта, которая поддерживает CUDA или другие программные интерфейсы, для которых есть поддержка в
ffmpeg
. NVIDIA поддерживает CUDA.*) Раздобыть бинарник
ffmpeg
, откомпилированный с флагом --enable-nvenc
(для NVIDIA). Для линуксов это делается тривиально через configure, и ты собираешь свой вариант. Для винды - компилировать из исходников это гемор, поэтому пришлось поискать готовый бинарник. Он нашёлся вот здесь: https://github.com/illuspas/ffmpeg-hw-win32 (скачиваем репозиторий как ZIP-файл и копируем бинарники из x86_64/bin, там есть ffmpeg.exe)*) Проинсталлировать NVidia CUDA - официальные драйвера для NVidia, поддерживающие программный интерфейс. Это не то же самое, что обычные драйвера для видеокарты. Гуглим "nvidia cuda drivers", идём сюда: https://developer.nvidia.com/cuda-downloads, скачиваем, ставим.
Вот команда, которой я сделал всё то же самое через GPU:
ffmpeg -i C0001.MP4 -i C0002.MP4 -i C0003.MP4 -i C0004.MP4 -i C0005.MP4 -i C0006.MP4 -filter_complex concat=n=6:v=1:a=1 -c:v nvenc_h264 -b:v 9500k -minrate 5000k -maxrate 18000k -preset llhq -c:a aac -b:a 192k Result.mp4
Мне пришлось вручную прописывать битрейт (
-b:v 9500k -minrate 5000k -maxrate 18000k
), потому что параметр -crf
для этого кодека не поддерживается, а по умолчанию получается 3.5 MBit/sec, мне слишком мало.Но... результат - это кодирование в реальном времени. 1.5 часа видео = 1.5 часа занимает кодирование.
Кроме того, процессор почти не загружен, вентилятор не шумит, можно параллельно использовать компьютер без неудобств. Да и памяти куда меньше жрёт. Лепота!
Резюмируя:
1. Sony Vegas - 18 часов, 100% CPU, 2GB RAM (working set), глючит и подвисает, нужно рестартовать.
2.
ffmpeg, libx264
- 5 часов, 100% CPU, 1GB RAM - всё пучком.3.
ffmpeg nvenc_h264
- 1.5 часа (~= realtime, encoding FPS=61), 15% CPU, 370MB RAM.