О нас Руководства Проекты Контакты
Админка
пожалуйста подождите

FFmpeg — это «швейцарский нож» для обработки медиа, способный выполнять транскодирование, стриминг, фильтрацию и манипуляции практически с любым аудио-/видео-форматом. В этом руководстве рассматриваются практические паттерны использования FFmpeg с точки зрения senior-разработчика.

Зачем нужен FFmpeg

FFmpeg лежит в основе большинства видеоплатформ:

  1. Универсальная поддержка форматов: работает практически с любыми кодеками и контейнерами
  2. Мощные фильтры: изменение размера, кадрирование, наложение, цветокоррекция и многое другое
  3. Поддержка стриминга: вывод RTMP, HLS, DASH
  4. Поддержка субтитров: встраивание, извлечение и рендеринг субтитров
  5. Пакетная обработка: можно скриптовать любой media workflow

Установка

# Ubuntu/Debian
sudo apt install ffmpeg
# CentOS/RHEL
sudo dnf install ffmpeg
# macOS
brew install ffmpeg
# Проверка установки
ffmpeg -version

Базовые понятия

Структура команды FFmpeg

ffmpeg [global_options] [input_options] -i input [output_options] output

Контейнер vs кодек

  • Контейнер: формат файла (MP4, MKV, AVI)
  • Video Codec: сжатие видео (H.264, H.265, VP9)
  • Audio Codec: сжатие аудио (AAC, MP3, Opus)

Проверка информации о файле:

ffprobe -v error -show_format -show_streams input.mp4

Типовые задачи транскодирования

Конвертация между форматами

# MKV в MP4 (перекодирование)
ffmpeg -i input.mkv -c:v libx264 -c:a aac output.mp4
# MKV в MP4 (копирование stream без перекодирования)
ffmpeg -i input.mkv -c copy output.mp4
# AVI в WebM
ffmpeg -i input.avi -c:v libvpx-vp9 -c:a libopus output.webm

Изменение качества видео

# Constant Rate Factor (CRF) — меньше = лучшее качество
# H.264: диапазон 18–28 считается хорошим, 23 — значение по умолчанию
ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
# H.265 (HEVC) — лучшее сжатие
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
# Целевой bitrate
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M output.mp4
# Кодирование в два прохода (лучшее качество при целевом размере)
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -f null /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 output.mp4

Изменение размера видео

# Масштабирование до заданного разрешения
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4
# Масштабирование с сохранением соотношения сторон
ffmpeg -i input.mp4 -vf "scale=1280:-1" output.mp4 # Высота автоматически
ffmpeg -i input.mp4 -vf "scale=-1:720" output.mp4 # Ширина автоматически
# Масштабирование, чтобы вписаться в размеры (при необходимости — padding)
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4

Работа с субтитрами

Конвертация субтитров YouTube в SRT

Формат VTT от YouTube в SRT:

ffmpeg -i subtitles.vtt subtitles.srt

Встраивание субтитров (Soft Subs)

Субтитры как отдельный stream (можно включать/выключать):

# Добавить SRT как stream субтитров
ffmpeg -i video.mp4 -i subtitles.srt -c copy -c:s mov_text output.mp4
# Добавить субтитры VTT
ffmpeg -i video.mp4 -i subtitles.vtt -c copy -c:s webvtt output.mkv
# Несколько дорожек субтитров
ffmpeg -i video.mp4 -i english.srt -i spanish.srt \
-c copy -c:s mov_text \
-metadata:s:s:0 language=eng \
-metadata:s:s:1 language=spa \
output.mp4

Прожиг субтитров в видео (Hard Subs)

Субтитры отрисовываются поверх видео (навсегда):

# Прожечь субтитры SRT
ffmpeg -i video.mp4 -vf "subtitles=subtitles.srt" output.mp4
# Настроить стиль субтитров
ffmpeg -i video.mp4 -vf "subtitles=subtitles.srt:force_style='FontSize=24,PrimaryColour=&H00FFFF&'" output.mp4
# Прожечь субтитры ASS/SSA (с сохранением оформления)
ffmpeg -i video.mp4 -vf "ass=subtitles.ass" output.mp4

Извлечение субтитров

# Извлечь первый stream субтитров
ffmpeg -i video.mkv -map 0:s:0 subtitles.srt
# Извлечь все stream субтитров
ffmpeg -i video.mkv -map 0:s subtitles_%d.srt

Обработка аудио

Извлечение аудио

# Извлечь в MP3
ffmpeg -i video.mp4 -vn -c:a libmp3lame -q:a 2 audio.mp3
# Извлечь в исходном формате
ffmpeg -i video.mp4 -vn -c:a copy audio.aac

Изменение аудио

# Изменить audio codec
ffmpeg -i input.mp4 -c:v copy -c:a aac output.mp4
# Отрегулировать громкость
ffmpeg -i input.mp4 -filter:a "volume=1.5" output.mp4
# Нормализовать аудио
ffmpeg -i input.mp4 -filter:a loudnorm output.mp4
# Удалить аудио
ffmpeg -i input.mp4 -an output.mp4

Замена аудиодорожки

ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 output.mp4

Нарезка и склейка

Нарезка видео на сегменты

# Вырезать с 00:01:00 на 30 секунд
ffmpeg -i input.mp4 -ss 00:01:00 -t 30 -c copy output.mp4
# Вырезать с 00:01:00 до 00:02:30
ffmpeg -i input.mp4 -ss 00:01:00 -to 00:02:30 -c copy output.mp4
# Быстрый seek (для больших файлов ставьте -ss перед -i)
ffmpeg -ss 00:01:00 -i input.mp4 -t 30 -c copy output.mp4

Конкатенация видео

Создайте список файлов videos.txt:

file 'video1.mp4'
file 'video2.mp4'
file 'video3.mp4'

Склейте файлы:

# Тот же codec (без перекодирования)
ffmpeg -f concat -safe 0 -i videos.txt -c copy output.mp4
# Разные codec (перекодирование)
ffmpeg -f concat -safe 0 -i videos.txt -c:v libx264 -c:a aac output.mp4

Видео-фильтры

Примеры распространённых фильтров

# Кадрировать видео (ширина:высота:x:y)
ffmpeg -i input.mp4 -vf "crop=640:480:100:50" output.mp4
# Повернуть видео
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4 # 90° по часовой стрелке
ffmpeg -i input.mp4 -vf "transpose=2" output.mp4 # 90° против часовой стрелки
ffmpeg -i input.mp4 -vf "hflip" output.mp4 # Отразить по горизонтали
ffmpeg -i input.mp4 -vf "vflip" output.mp4 # Отразить по вертикали
# Ускорить/замедлить
ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" -af "atempo=2.0" output.mp4 # Скорость 2x
ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" -af "atempo=0.5" output.mp4 # Скорость 0.5x
# Добавить fade in/out
ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=2,fade=t=out:st=58:d=2" output.mp4

Добавление водяного знака/наложения

# Водяной знак-изображение в углу
ffmpeg -i video.mp4 -i watermark.png \
-filter_complex "overlay=W-w-10:H-h-10" \
output.mp4
# Текстовое наложение
ffmpeg -i video.mp4 \
-vf "drawtext=text='Copyright 2024':fontsize=24:fontcolor=white:x=10:y=H-th-10" \
output.mp4
# Timestamp
ffmpeg -i video.mp4 \
-vf "drawtext=text='%{pts\:hms}':fontsize=24:fontcolor=white:x=10:y=10" \
output.mp4

Создание превью и GIF

Извлечение превью

# Один кадр в заданный момент времени
ffmpeg -i video.mp4 -ss 00:00:10 -vframes 1 thumbnail.jpg
# Несколько превью (каждые 10 секунд)
ffmpeg -i video.mp4 -vf "fps=1/10" thumbnail_%04d.jpg
# Сетка превью/sprite
ffmpeg -i video.mp4 -vf "fps=1/5,scale=160:-1,tile=5x5" sprite.jpg

Создание GIF

# Базовый GIF (большой файл)
ffmpeg -i video.mp4 -t 5 output.gif
# Оптимизированный GIF с palette
ffmpeg -i video.mp4 -t 5 -vf "fps=15,scale=480:-1:flags=lanczos,palettegen" palette.png
ffmpeg -i video.mp4 -i palette.png -t 5 -filter_complex "fps=15,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif

Стриминг

Генерация HLS для адаптивного стриминга

ffmpeg -i input.mp4 \
-c:v libx264 -c:a aac \
-hls_time 10 \
-hls_list_size 0 \
-hls_segment_filename "segment_%03d.ts" \
playlist.m3u8

HLS с несколькими уровнями качества

ffmpeg -i input.mp4 \
-filter_complex "[0:v]split=3[v1][v2][v3]; \
[v1]scale=1920:1080[v1out]; \
[v2]scale=1280:720[v2out]; \
[v3]scale=854:480[v3out]" \
-map "[v1out]" -map 0:a -c:v:0 libx264 -b:v:0 5M -c:a aac -b:a:0 192k \
-hls_time 10 -hls_playlist_type vod 1080p.m3u8 \
-map "[v2out]" -map 0:a -c:v:1 libx264 -b:v:1 2.5M -c:a aac -b:a:1 128k \
-hls_time 10 -hls_playlist_type vod 720p.m3u8 \
-map "[v3out]" -map 0:a -c:v:2 libx264 -b:v:2 1M -c:a aac -b:a:2 96k \
-hls_time 10 -hls_playlist_type vod 480p.m3u8

Пакетная обработка с помощью скриптов

Пример Bash-скрипта

##!/bin/bash
INPUT_DIR="./raw"
OUTPUT_DIR="./processed"
mkdir -p "$OUTPUT_DIR"
for file in "$INPUT_DIR"/*.mp4; do
filename=$(basename "$file" .mp4)
echo "Processing: $filename"
ffmpeg -i "$file" \
-c:v libx264 -crf 23 \
-c:a aac -b:a 128k \
-vf "scale=1280:-1" \
"$OUTPUT_DIR/${filename}_720p.mp4"
done
echo "Done!"

Интеграция с Node.js

const { spawn } = require('child_process');
function transcodeVideo(input, output, options = {}) {
return new Promise((resolve, reject) => {
const args = [
'-i', input,
'-c:v', 'libx264',
'-crf', options.crf || '23',
'-c:a', 'aac',
'-y', // Перезаписать выходной файл
output
];
const ffmpeg = spawn('ffmpeg', args);
ffmpeg.stderr.on('data', (data) => {
console.log(`FFmpeg: ${data}`);
});
ffmpeg.on('close', (code) => {
if (code === 0) {
resolve(output);
} else {
reject(new Error(`FFmpeg exited with code ${code}`));
}
});
});
}
// Использование
transcodeVideo('input.mp4', 'output.mp4', { crf: '28' })
.then(output => console.log('Created:', output))
.catch(err => console.error('Error:', err));

Ключевые выводы

  1. По возможности используйте -c copy: избегайте перекодирования ради скорости
  2. CRF для контроля качества: меньшие значения = более высокое качество
  3. Два прохода для целевого размера: лучшее качество при заданном bitrate
  4. Palette для GIF: критически важно для хорошего качества
  5. -ss перед -i: более быстрый seek в больших файлах
  6. Тестируйте на коротких клипах: прототипируйте фильтры до полного рендера

Возможности FFmpeg чрезвычайно обширны — этих паттернов достаточно для большинства типовых задач, но документация раскрывает ещё множество функций для специализированных workflow.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
Зетка Интерактив