Как сделать … в ffmpeg

Чем хорош ffmpeg? С ним удобно решать однотипные задачи по обработке звука и видео, когда файлов много, а действия повторяются часто. Составляем нужную команду один раз, отлаживаем, проверяем, полируем. Потом сохраняем в какой‐нибудь bat‐файл или во что‐то более современное и вызываем по необходимости.

Даже YouTube использует ffmpeg. Разве это не аргумент?

Скачайте ffmpeg здесь (для Win7 здесь ), извлеките из архива ffmpeg.exe, понадобится только он. Проще всего кинуть его в c:\windows, где система его найдёт. Но можно заморочиться, разместить как положено где‐нибудь в Program Files и прописать путь к нему в переменной PATH. А теперь команды:

  • Перепаковать видео в другой контейнер (avi, mp4, mkv) без изменений и без потери качества.

    ffmpeg -i "Запись.AVI" -c:a copy -c:v copy "Запись.mp4"
  • Нормализовать звук в ролике без перекодирования видео (усиление звука до нормального уровня, если он слишком тихий).

    ffmpeg -i "Запись.avi" -c:a aac -b 320k -filter:a loudnorm -c:v copy "Запись.mp4"
  • Повернуть вертикально снятое видео без перекодирования (изменить метаданные).

    ffmpeg -i "VID_20180512_210030.mp4" -c copy -metadata:s:v:0 rotate=0 "снимай нормально.mp4"
  • Заменить звуковую дорожку, видео остаётся без изменений. Если не указывать аудиокодек -c:a aac -b:a 320k, ffmpeg сам выберет подходящий контейнеру. Для mp4 это будет aac с битрейтом около 130 кб/с.

    ffmpeg -i video.mp4 -i new_audio.wav -c:v copy -c:a aac -b:a 320k -map 0:v:0 -map 1:a:0 результат.mp4
  • Сжать видео, варианты:

    • Обычный h264/aac с упором на качество. Фильмы с рутрекера идут в этом формате. Замените fast на veryslow, чтобы сжать эффективнее. Увеличьте ‑crf до 23–28, если хотите снизить вес файла за счёт понижения качества. Faststart и movflags позволяют начать смотреть видео до того, как оно загрузилось полностью.

      ffmpeg -i "video-101733.webm" -c:a aac -b 320k -c:v libx264 -preset fast -profile:v high -crf 18 -pix_fmt yuv420p -movflags +faststart 1.mp4
    • Задействуя Intel QSV, аппаратное ускорение. Даёт колоссальный прирост в скорости, но качество ощутимо хуже. Доступен на процессорах Intel начиная с Core i3 Ivy Bridge (2012 год). Более новые поддерживают также h265, но он пока мало распространён и не везде откроется. Кстати говоря, ffmpeg – не лучшее решение для кодирования с QSV, из‐за своей универсальности он в несколько раз проигрывает по скорости более узконаправленной QSVEnc, которая настоятельно рекомендуется. Чтобы аппаратное ускорение Intel работало, монитор должен быть подключен ко встроенной видеокарте Intel. Для управления качеством варьируйте битрейт ‑b:v.

      ffmpeg -hwaccel qsv -i "videoplayback.mp4" -c:a aac -b 320k -c:v h264_qsv -preset:v veryslow -b:v 1700K -level 41 -profile:v high -look_ahead 1 "videoplayback+.mp4"

      У этого кодека много неочевидных настроек, некоторые нужно выставлять с оглядкой на возможности процессора. Например, look_ahead для Haswell и Broadwell. Полный список:

      ffmpeg -? encoder=h264_qsv
    • Сжать для whatsapp в 320p, максимально, чтобы пролезло в жёсткие ограничения по размеру и воспроизвелось на самом захудалом картошка‐фоне

      ffmpeg -i 1.mp4 -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p -b:v 500K -filter:v scale=-1:320 2.mp4

      то же, с аппаратным ускорением:

      ffmpeg -hwaccel qsv -i 1.mp4 -c:v h264_qsv -preset:v veryslow -b:v 400K -level 41 -profile:v high -look_ahead 1 -filter:v scale=-1:320 2.mp4
  • Создать видео из статичной картинки. Идеально для многочасовых аудиокниг или лекций. Предпологая, что звуковая дорожка содержит в основном речь, возьмём кодек opus 64 кбит/с, он классный и звучит лучше mp3/128 (круче только xhe‐aac, но это пока диковинка). С такими настройками часовой ролик уместится в 30 Мб и отрендерится за минуту. Вся видеордорожка займёт столько же места, сколько одна исходная картинка. Супербыстро и суперкруто:

    ffmpeg -r 0.3 -i обложка.jpg -i звук.mp3 -shortest -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2,tpad=stop_mode=clone:stop_duration=3600100" -c:a libopus -b:a 64K -c:v libx264 -pix_fmt yuv420p -max_interleave_delta 0 -preset faster -x264-params "rc-lookahead=1:keyint=123456:min-keyint=123:ref=0:subme=0:no-scenecut=1:bframes=1:qp=20" Готово.mp4

    Мы снизили частоту кадров почти до минимального значения, которое поддерживают все плееры – 0,2 fps или один кадр раз в пять секунд. Это не влияет на размер видеодорожки, но ускоряет обработку до космических скоростей. Кроме того, вместо стандартного ‑loop, зацикливающего картинку, применён более быстрый фильтр похожего действия, который дублирует последний кадр. Ещё один фильтр pad делает размер картинки чётным, другую кодек не съест.

  • Чередующиеся картинки, более продвинутый вариант статичного видео. Видеодорожка получится чуть объёмнее, но терпимо. Сделайте текстовый файлик типа плейлиста, такого вида:

    file 'C:\картинки\1.jpg'
    duration 100
    file 'C:\картинки\2.jpg'
    duration 100
    file 'C:\картинки\3.jpg'
    duration 100
    file 'C:\картинки\4.jpg'
    duration 100
    file 'C:\картинки\4.jpg'

    Duration – это желаемая длительность каждой картинки в секундах. Последняя строчка без длительности нужна техническим причинам. Кавычки только одинарные! Команда будет похожая:

    ffmpeg -safe 0 -stream_loop -1 -f concat -i картинки.txt -i звук.wav -shortest -c:a libopus -b:a 64k -c:v libx264 -pix_fmt yuv420p -max_interleave_delta 0 -preset faster -x264-params "rc-lookahead=1:keyint=123456:min-keyint=123:ref=0:subme=0:no-scenecut=1:bframes=1:qp=26" -r 0.3 Готово.mp4
  • Склеить несколько роликов в один. Если есть список файлов, которые надо объединить, делайте так:

    ffmpeg -hwaccel qsv -y -f concat -safe 0 -i files.txt -c:a copy -c:v h264_qsv -preset:v veryslow -b:v 3500K -level 41  -profile:v high -g 125 -look_ahead 1 out.mp4

    Сам список files.txt должен выглядеть так (кавычки обязательно одинарные):

    file '.\video1.mov'
    file '.\video2.mov'
    file '.\video3.mov'
    ...
  • Склеить несколько аудио. Можем сделать это без перекодирования и потери качества, поскольку формат mp3 допускает вольное обращение с собой: файлы можно резать и клеить как настоящую плёнку при условии совпадения числа каналов и битрейта.

    ffmpeg -f concat -safe 0 -i files.txt -c:a copy -vn Объединённое.mp3
  • Склеить все файлы Mp3 в папке, не используя никаких списков. Для этого создайте bat‐файл следующего содержания:

    cd /D "%~dp0"
    for %%f in (*.mp3) do (
    echo file '%%f' >> list.txt
    )
    ffmpeg -f concat -safe 0 -i list.txt -c copy -vn Gotovo.mp3
    del list.txt
    pause

    Поместите его в папку с mp3 и запустите. Для склеивания видео адаптировать код будет несложно.

  • Разделить запись на несколько или вырезать фрагмент без перекодирования. Попробуем разрезать наш любимый mp3:

    ffmpeg -i Кассета.mp3 -c copy -ss 00:00 -to 00:55:18 Сторона_А.mp3
    ffmpeg -i Кассета.mp3 -c copy -ss 00:55:18 -to 01:45:00 Сторона_Б.mp3

    Учитывайте, что разрез пройдёт не в точно указанном месте, а на ближайшем стыке двух фреймов, поскольку мы работаем без пересжатия, и минимальная переносимая единица – это один фрейм. С mp3 всё будет хорошо, там фреймы крохотные, сотые доли секунды. А вот видео можно разбить обычно только по ключевым кадрам, это секунд десять, не меньше.

    Случается, некоторые вредные плееры врут относительно времени воспроизведения. Я столкнулся с тем, что LightAlloy в середине двухчасовой записи «уплыл» почти на восемь секунд, а вот MPC‐HC был точен, хотя оба играли через ffdshow.

  • Создать анимацию из картинок. Файлы должны иметь порядковые номера без пропусков: img_001.jpg, img_002.jpg и т.д. Здесь framerate – кадры в секунду, stream_loop – сколько кадров держится каждая картинка, %03d – три цифры (digits). Если в именах отсутствуют ведущие нули (img_0.jpg, img_1.jpg … img_999.jpg), следует писать просто %3d. Работает только с картинками, склеить так видеофайлы нельзя.

    ffmpeg -f image2 -framerate 15 -stream_loop 3 -i "img_%03d.jpg" -c:v libx264 -b:v 3000k out.mp4
  • Пакетное перекодирование всех файлов, найденных по маске. Запускать в командной строке, не забыв сначала командой «cd» сменить рабочую директорию на ту, в которой лежат файлы. Запускать в bat‐файле тоже можно, если заэкранировать символ процента ещё одним: %% вместо %.

    FOR %G IN (*.MTS) DO ffmpeg -i "%G" -an -c:v copy "%~nG.mp4"
  • Вытащить звук из ролика без пересжатия:

    ffmpeg -i "The Phantom of the Opera (piano cover).mp4" -acodec copy -vn "The Phantom of the Opera (piano cover).aac"

    или в пакетном режиме:

    FOR %G IN (*.MP4) DO ffmpeg -i "%G" -vn -c:a copy "%~nG.aac"
  • Микс Dolby 5.1 в стерео с сохраненеим правильного баланса каналов. Внимание! Мобильные телефоны не воспроизводят дорожки Dolby Digital AC3 из‐за лицензионных ограничений. Используйте aac, ogg или mp3.

    ffmpeg -i "file.mp4" -vn -c:a ac3 -b:a 360K -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" "out.ac3"

    с преобразованием в сырой wav:

    ffmpeg -i "file.mp4" -vn -c:a pcm_s16le -ar 48000 -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" "out.wav"
  • Вытащить только центральный канал из 5.1:

    ffmpeg -i "file.mp4" -vn -c:a ac3 -b:a 360K -af "pan=1c|c0 = FC" "out.ac3"
  • Стерео в моно:

    ffmpeg -i "file.mp4" -vn -c:a ac3 -b:a 360K -af "pan=1c|c0=.5*c0+.5*c1" "out.ac3"
  • Преобразовать в несжатый WAV (частота дискретизации 44100, 48000 и т.д.)

    ffmpeg -i "The Phantom of the Opera Theme Song.mp4" -vn -acodec pcm_s16le -ar 44100 Song.wav
  • Преобразовать во FLAC, формат без потери качества:

    ffmpeg -i Голос.wav -vn -acodec flac -ar 44100 Голос.flac
  • Наложить таймкод поверх картинки (вшить). Это не настоящий TCR/SMPTE, но близко. Полезно для всяких закадрово‐дубляжных работ:

    ffmpeg -i Фильм.mp4 -c:a copy -vf "drawtext=fontfile=/Windows/Fonts/cour.ttf:  text='%{pts \:hms}':  x=(w-text_w)/2: y=h-text_h*2: fontsize=(h/10): fontcolor=white: box=1: boxcolor=black@0.7: boxborderw=5" Фильм__.mp4

    Таймкод выводится моноширным шрифтом Courier (cour.ttf), размер которого адаптируется под размер видео (fontsize=(h/10)), по центру экрана внизу (y=h-text_h*2). Если место внизу уже занято субтитрами, можно заменить на y=text_h, и текст уедет вверх.

    Можно не впечатывать таймкод в видео, а выводить его динамически, непосредственно в плеере во время воспроизведения с помощью AviSynth. Про это есть отдельная статья.

  • Запись экрана. С аппаратным ускорением:

    ffmpeg -hwaccel qsv -y -rtbufsize 100M -f gdigrab -framerate 5 -probesize 10M -i desktop -f dshow -i audio="Стерео микшер (Realtek High Def" -c:a aac -b 140k -c:v h264_qsv -preset:v veryfast -b:v 3500K -level 41 -profile:v high -g 125 -look_ahead 1 -crf 25 -pix_fmt yuv420p Запись_встречи.mp4

    и без него:

    ffmpeg -y -rtbufsize 100M -f gdigrab -framerate 5 -probesize 10M -i desktop -f dshow -i audio="Стерео микшер (Realtek High Def" -c:a aac -b 140k -c:v libx264 -preset ultrafast -crf 25 -pix_fmt yuv420p Запись_встречи.mp4

    Название источника аудио (стереомикшера) получим, запросив у ffmpeg список direct show устройств:

    ffmpeg -list_devices true -f dshow -i dummy
  • Спидпэйнт из записи экрана. Удаляем повторяющиеся похожие кадры фильтром mpdecimate и ускоряем в 2 раза (0.5 значит, что половина кадров выбрасывается).

    ffmpeg -i ice_video_20200601-101733.webm -vf mpdecimate,setpts=0.5*N/FRAME_RATE/TB  -c:v libx264 -preset faster -profile:v high -tune stillimage -crf 18 -refs 1 -g 1000 -coder 1 -pix_fmt yuv420p -movflags +faststart -an 1.mp4
  • Хромакей в реальном времени. В этом примере видео с вебки накладывается на онлайн‐трансляцию с побережья Италии и выводится на экран. Ничего сложного. Правда, ссылка на Италию недолгоживущая, ищите свежую. И понадобится зелёная стена. Фильтр scale масштабирует кадр с вебки до размера кадра трансляции. В фильтре colorkey первый параметр – это подавляемый цвет (0x00FF00 – зелёный, 0x000000 – чёрный), затем допустимые отклонения (чем больше, тем агрессивнее), затем степень прозрачности перехода от прозрачного к непрозрачному.

    ffmpeg -i "https://hd-auth.skylinewebcams.com/live.m3u8?a=beci4ao7v6g0qt5icj6998suk6" -f dshow -video_size 640x480 -rtbufsize 702000k -i video="VF0520 Live! Cam Sync" -filter_complex "[1:v]scale=1440:1080[scl];[scl]colorkey=0x00FF00:0.8:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" -pix_fmt yuv420p -f sdl "SDL OUT"

    Вариант с заранее скачанным фоном, без масштабирования и с менее агрессивным хромакеем:

    ffmpeg -i "C:\Temp\background.mp4" -f dshow -video_size 640x480 -rtbufsize 702000k -i video="VF0520 Live! Cam Sync" -filter_complex "[1:v]colorkey=0x00FF00:0.4:0.6[ckout];[0:v][ckout]overlay[out]" -map "[out]" -pix_fmt yuv420p -f sdl "SDL OUT"

    Название веб‐камеры получаем тем же способом, что и со стереомикшером выше.

  • Склеить потоковое видео HLS – то самое, которое обычно скачивается только фрагментами, кусочками (chunks)

    ffmpeg -protocol_whitelist "file,http,https,tcp,tls" -i "27-05-14-00.m3u8" -map 0 -c copy result.mp4

    Сам плейлист m3u8 может размещаться на сервере, если это живая трансляция, а может быть и скачан заранее браузером. Выглядит он примерно так:

    #EXTM3U
    #EXT-X-PLAYLIST-TYPE:VOD
    #EXT-X-TARGETDURATION:6
    #EXT-X-VERSION:3
    #EXT-X-MEDIA-SEQUENCE:0
    #EXT-X-PROGRAM-DATE-TIME:2019-02-23T08:19:56Z
    #EXTINF:6.000,
    https://hlsarchive.limehd.tv/f7940e06b7b662bb577dee5694bcec4c017226/tracks-v1a1/dvr-2019/02/23/08/19/56-06000.ts
    #EXTINF:6.000,
    https://hlsarchive.limehd.tv/f7940e06b7b662bb577dee5694bcec4c017226/tracks-v1a1/dvr-2019/02/23/08/20/02-06000.ts
    #EXTINF:6.000,
    https://hlsarchive.limehd.tv/f7940e06b7b662bb577dee5694bcec4c017226/tracks-v1a1/dvr-2019/02/23/08/20/08-06000.ts
    #EXTINF:6.000,
    https://hlsarchive.limehd.tv/f7940e06b7b662bb577dee5694bcec4c017226/tracks-v1a1/dvr-2019/02/23/08/20/14-06000.ts
    #EXTINF:6.000,
    https://hlsarchive.limehd.tv/f7940e06b7b662bb577dee5694bcec4c017226/tracks-v1a1/dvr-2019/02/23/08/20/20-06000.ts
    #EXTINF:6.000,
    https://hlsarchive.limehd.tv/f7940e06b7b662bb577dee5694bcec4c017226/tracks-v1a1/dvr-2019/02/23/08/20/26-06000.ts
    ...

Полезные ссылки: