О чем статья
В этой статье я расскажу вам о том, как можно вырезать фрагмент из видео, склеить видео из фрагментов (частей), извлечь звук из видеозаписи и всё это делается буквально одной строчкой кода. Для этого мы будем использовать "программу" FFmpeg. И да - всё это очень просто и бесплатно. Ссылки на программу и рабочий пример будут в конце статьи.
Почему такая длинная статья и зачем всё это надо
Статья длинная потому что все объяснено очень подробно. Можно читать быстро и "между строк". Можно даже и не читать, а просто скачать пример и если возникнут вопросы смотреть статью.
Зачем это надо. Я показал основные операции с видео - это уже полезная информация.
Я показал операции в "цикле". Мы разрезаем видеофайл на фрагменты, разбиваем фрагмент покадрово, вырезаем звук. А потом всё обратно собираем. И вуаля - исходное видео.
Зачем мы это делаем? Дело в том, что теперь мы можем работать с изображениями. И некоторые нейросети это тоже могут. Итого после разбивки видео на кадры мы можем их изменить, обработать нейросетью, а потом заново собрать и получить интересный результат. И в следующей статье я это покажу. Итого: полезная и подробная информация о работе с FFmpeg и интересное применение данной программы.
Сразу к делу
Сначала я хотел написать вводную часть с кратким пояснением, что такое FFmpeg, преимущества данной программы и недостатки. Но кому это надо, когда есть Википедия? Поэтому скажу кратко и по существу - FFmpeg это программа, которая позволяет делать с видео почти что угодно. Программа не имеет графического интерфейса - работа идет из командной строки. Но намного удобнее создать cmd файлы, что мы и будем делать.
Итого наш краткий план действий.
1) Скачать FFmpeg.
2) Создать cmd файл с 1-2 строчками кода.
3) Запустить cmd файл и получить результат. Всё.
А можно ничего и не делать. Ведь я уже всё сделал за вас. Качаем мой архив "Пример", распаковываем (ссылка есть внизу статьи). Там всё уже есть. И FFmpeg и cmd файлы. А статью читаем в качестве пояснения. Для новичка так будет проще. Обратите внимание, мой пример работает для Windows x64.
Скачиваем FFmpeg
Первое, что нам нужно - это скачать FFmpeg. Ссылка есть в конце статьи (а можно и загуглить). Идем на официальный сайт, выбираем (если вдруг не выбралось автоматически) версию (Version - для начала можно любую), архитектуру (скорее всего у вас Windows x64), выбираем компоновку (Linking - Static) и нажимаем Download Build.
В результате мы скачаем zip архив. Разархивируем его. В нем будут 3 файла. ffmpeg.exe, ffplay.exe, ffprobe.exe. В нашем случае нам нужен только файл ffmpeg.exe.
Нам нужен только один файл ffmpeg.exe. Именно он и будет вырезать, склеивать и производить любые другие операции с видео.
Создаем cmd файлы
cmd файл - это обычный текстовый файл, сохраненный с расширением cmd. То есть вам нужно открыть блокнот, написать команду и сохранить этот файл с расширением cmd.
Но для начала, давайте создадим папку, в которой мы будем работать. Создайте папку с любым именем, например Test. И скопируйте туда файл ffmpeg.exe. Скопируйте в эту папку и ваше видео (то с которым мы хотим работать). В моем примере имя видео original_video.mp4.
Команда 1. Получить информацию о видеофайле
Давайте создадим в этой папке файл с именем 1_get_video_information.cmd в котором напишем следующее:
ffmpeg -i original_video.mp4
@pause
Это наша первая команда которая покажет нам информацию о видеофайле. Эта команда довольно простая. Мы обращаемся к ffmpeg (файл ffmpeg.exe) с параметром -i (infotmation) и указываем ему наш видеофайл original_video.mp4. В конце мы вызываем команду @pause. @pause - пауза - это приостановка программы. Она не позволяет окну закрыться, чтобы мы увидели результат работы программы и возможные ошибки.
Сохраним этот файл и запустим его. Мы увидим на экране следующее.
Мы получили основную информацию о нашем видеофайле. Обратите внимание, в моем видеофайле, аудио в формате aac, а частота кадров 60 fps. Далее эта информация мне пригодится.
Команда 2. Скопировать фрагмент из видео в отдельный видеофайл
Аналогично, создадим в нашей папке файл с именем 2_copy_video.cmd в котором напишем следующее (команду echo Y...cut_1.mp4 пишем в одну строку):
echo Y | ffmpeg -ss 00:00:06 -to 00:00:10 -i original_video.mp4 -c copy cut_1.mp4
@pause
Кратко о команде. Команда копирует ("вырезает") часть видео из файла original_video.mp4 в файл cut_1.mp4 (этот файл будет создан). Копирование идет с 6 секунды ( 00:00:06 ) по 10 секунду (00:00:10). При копировании будет использован тот же кодек, что и в оригинале видео (-c copy ), так что потерь качества не будет.
echo Y - это автоответ да. Если файл cut_1.mp4 уже существует, то ffmpeg спросит нас перезаписать ли этот файл. И мы должны будем написать в окне командной строки Y или N. Да или нет. Чтобы не писать руками, мы напишем код в файле. То есть всегда перезаписывать файл cut_1.mp4.
Команда 3. Создать png изображения из видеофайла ("раскадровка")
Для начала поясним, почему png, а не jpg или другие форматы. Дело в том, что полученные из видео png изображения будут идентичны видеокадрам. То есть формат png - это по сути формат без искажений, "без сжатия" (сжатие без потерь), в отличии от jpg, gif и других форматов.
Сколько будет изображений из 1 секунды видео? А это уже зависит от fps. Помните, в команде 1 (получение информации о видеофайле) я писал "Кстати, в моем видеофайле частота кадров 60 fps"? Ну вот - из моего видео я получу 60 кадров из 1 секунды.
Как вы понимаете, если 1 секунда мне даст 60 кадров/файлов (не говоря уже о минуте), то мне желательно создать отдельную папку для моих кадров. И я её создам. В нашей папке Test я создам папку cut_1_video. Далее я создам файл 3_create_png_from_video.cmd в котором пропишу следующее:
ffmpeg -i cut_1.mp4 cut_1_video\%%06d.png
@pause
О команде - я указываю ffmpeg файл cut_1.mp4. Из него и будут создаваться кадры-изображения. А далее я указываю папку, вид имени и тип файла.
Папку cut_1_video мы только что создали. Вид имени файла %%06d.png означает, что имя файла будет состоять из 6 цифр, с нулями впереди. Например 000001.png, 000002.png...000010.png...123456.png.
Итого в папке cut_1_video мы получим png кадры с последовательной нумерацией. Такую нумерацию (особенно 6 цифр) поддерживают многие программы.
А теперь, немного математики. Первая команда мне сообщила что в одной секунде у меня 60 кадров. Вторая команда вырезала 4 секунды из видео. А сейчас мы создали из этого видео кадры. Итого 4*60=240 кадров.
Всё точно - 240 файлов в папке. И общий размер около 1 ГБ. И это не удивительно, ведь мало того, что мое видео содержит 60 кадров (обычно 24 или 30) в секунду, так ещё и с разрешением 1920x1080. Это буквально как 240 обоев на рабочий стол, причем высочайшего качества.
Чуть больше 4 МБ на 1 картинку. Ну а 240 как раз и будет гигабайт. готовьте место на вашем диске )
Команда 4. Создать из png изображений видео
Обратная задача. Мы только что создали изображения из видео. А сейчас будем создавать видео из этих изображений. Зачем это надо? Ну,
например, мы можем отредактировать изображения какой нибудь программой (или нейросетью) и далее "собрать" видео уже из измененных изображений. Вариантов много.
Создадим файл 4_create_video_from_png.cmd в котором пропишем следующее:
echo Y | ffmpeg -framerate 60 -i cut_1_video\%%06d.png -vcodec libx264 cut_1_output_from_images.mp4
@pause
Итак, так как мы создаем видео из картинок, то у ffmpeg есть только информация о картинках. Программа не знает ни частоту кадров, ни кодек, да и звука в картинках нет. Поэтому, для полноценного видео, мы всё это должны указать.
-framerate 60 - это количество кадров в секунду, в оригинальном видео. Их количество я узнал первой командой. И в моем "видео из кадров" у меня будет 60 кадров в секунду. (Впрочем я могу и указать 30, 10, 1 кадр в секунду и получить замедленное видео. Или 120 и получить ускоренное.)
cut_1_video\%%06d.png папка с изображениями.
-vcodec libx264 - кодек. Я решил использовать этот кодек. Он весьма неплох. Вы же можете использовать другой кодек.
cut_1_output_from_images.mp4 имя и формат создаваемого видеофайла.
Команда 5. Скопировать звук из видео в отдельный аудиофайл.
Создадим файл 5_copy_sound_from_video.cmd в котором пропишем следующее:
echo Y | ffmpeg -i cut_1.mp4 -c:a copy cut_1_sound.aac
@pause
Я копирую звук из видео cut_1.mp4 в файл cut_1_sound.aac. Обратите внимание на расширение aac. Почему не mp3? Потому что первая команда мне это показала (ранее писал - Кстати, в моем видеофайле, аудио в формате aac ). Если у вас там будет mp3, то вы должны писать cut_1_sound.mp3.
Команда 6. Добавить звук из видео в отдельный видеофайл.
Создадим файл 6_add_sound_to_video в котором пропишем следующее:
echo Y | ffmpeg -i cut_1_sound.aac -i cut_1_output_from_images.mp4 cut_1_result.mp4
@pause
Я объединяю звук из файла cut_1_sound.aac с видео из файла cut_1_output_from_images.mp4 и создаю файл со звуком cut_1_result.mp4.
Команда 7. Объединить видео.
У нас уже есть видео cut_1.mp4, созданное из оригинала с 6 по 10 секунду. Я создам (командой 2 )ещё один видеофайл cut_0.mp4. Туда я скопирую видео с 0 по 5 секунду.
Итого у нас есть 2 файла - cut_0.mp4 и cut_1.mp4. Нам их надо объединить. Для этого мы сначала создадим файл join_video_filelist.txt. Это обычный текстовый файл. Его имя может быть любое. В этом файле мы напишем следующее
file 'cut_0.mp4'
file 'cut_1.mp4'
Теперь этот файл содержит имена видеофайлов для объединения и их последовательность. То есть сначала cut_0.mp4, потом cut_1.mp4.
Создадим файл 7_join_video.cmd в котором пропишем следующее:
echo Y | ffmpeg -f concat -i join_video_filelist.txt -vcodec libx264 join_video.mp4
@pause
Это команда берет информацию из файла join_video_filelist.txt (а там указаны имена файлов и последовательность объединения) и объединяет их в файл join_video.mp4. Как вы могли заметить, мы снова используем кодек libx264, хотя могли бы этого и не делать, а использовать оригинальный кодек (-c copy ). Ниже я объясню, зачем мы это сделали.
И вот мы получили видео join_video.mp4 по качеству практически не уступающее оригиналу.
Пояснения
Поговорим о результате. Посмотрим оригинальный файл original_video.mp4 и наш результат join_video.mp4. Качество видео практически не изменилось. Теоретически изменилось, мы же конвертировали видео, но "на глаз" это абсолютно незаметно. А вот со звуком всё не так хорошо. Слышите небольшой щелчок на месте объединения видео?
Скажу прямо - с видео работать не просто. Кодеки, ключевые кадры, аудиодорожки, различные форматы. Помните, выше мы объединяли видео и одновременно конвертировали его (libx264), а не использовали оригинальный кодек (-c copy )? Дело в том, что при разделении видео и его сборке ffmpeg режет видео поблочно, по ключевым кадрам.
Аналогично и со звуком. Но вот размеры блоков могут не совпадать. Итого при объединении мы получаем искажения звука или несовпадение его с видео. Вот такие вот тонкости.
Одно из решений - конвертация видео, что мы и сделали. Оно частично устраняет эту проблему (остался небольшой щелчок). Но для качественного результата, всё равно придется использовать дополнительные программы, например Sony Vegas Pro, что уже выходит за рамки этой статьи.
Ссылки