Вопрос или проблема
Я хочу сложить два видеозаписи выступления вертикально с помощью FFmpeg. Одно показывает презентацию (слайды), а другое — выступающего. Поскольку я хочу сделать это для нескольких выступлений, мне хотелось бы сделать это более универсальным способом и как можно эффективнее. Чаще всего видео имеет разные разрешения и соотношения сторон.
Мой текущий рабочий процесс выглядит так:
- Масштабировать видео с более низким разрешением, чтобы оно соответствовало разрешению другого видео:
ffmpeg -i video1.mp4 -s 1920x1080 -c:a copy video1_upscaled.mp4
- Совместить два видео:
ffmpeg -i video1_scaled.mp4 -i video2.mp4 -filter_complex vstack=inputs=2 combined.mp4
Длительность видео составляет от одного до двух часов, и выполнение команд занимает некоторое время. Есть ли способ экономии времени?
Скорее ли будет, если обрамить меньшее видео черными полосами вместо того, чтобы масштабировать его до размера другого? Можно ли совместить видео более эффективно? Поможет ли существенно объединить эти два шага в один?
Некоторая информация, которая может быть полезной:
- Всегда точно два видео, которые нужно сложить вертикально, одно над другим.
- Качество видео не имеет критического значения, как правило, разрешение видео с более низким разрешением будет вполне приемлемым.
- Место на диске не является проблемой.
- Разрешение и соотношение сторон видео известны (используйте любые для вашего примера).
- Оба видео имеют одинаковый аудиотрек.
- Оба видео имеют одинаковую длительность.
Вот четыре способа сделать то, что вы описали:
Метод А – в основном ваш метод
ffmpeg -y -i small.mp4 -s 1920x1080 -c:a copy upscaled.mp4
ffmpeg -y -i upscaled.mp4 -i big.mp4 -filter_complex vstack=inputs=2 A.mp4
Метод B – ваш метод, но выполненный как одна цепочка
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] scale=1920:1080 [a]; [1:v][a] vstack=inputs=2" B.mp4
Метод C – Обрамление (что, как я предполагаю, вы имеете в виду под черными полосами)
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] pad=1920:1080:0:0 [a]; [1:v][a] vstack=inputs=2" C.mp4
Метод D – Обрамление и наложение
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] pad=1920:1560:0:1080 [a]; [a][1:v] overlay=x=0:y=0" D.mp4
Метод Время (с)
A 29.3567267
B 19.932263
C 14.8910977
D 13.7423037
Примечания:
- A и B имеют схожие результаты.
- C и D имеют схожие результаты.
- C и D не изменяют размер меньшего видео.
- Если у вас разные SAR, C и D будут выглядеть странно.
- Вы также можете использовать overlay_cuda, если у вас есть CUDA-карта и вы готовы подправить фильтры.
- Я запускал это в Windows и сравнивал, используя PowerShell (см. ниже)
function VersionA {
ffmpeg -y -i small.mp4 -s 1920x1080 -c:a copy upscaled.mp4
ffmpeg -y -i upscaled.mp4 -i big.mp4 -filter_complex vstack=inputs=2 combinedA.mp4
}
function VersionB {
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] scale=1920:1080 [a]; [1:v][a] vstack=inputs=2" combinedB.mp4
}
function VersionC {
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] pad=1920:1080:0:0 [a]; [1:v][a] vstack=inputs=2" combinedC.mp4
}
function VersionD {
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] pad=1920:1560:0:1080 [a]; [a][1:v] overlay=x=0:y=0" combinedD.mp4
}
Measure-Command {VersionA | Out-Default}
Measure-Command {VersionB | Out-Default}
Measure-Command {VersionC | Out-Default}
Measure-Command {VersionD | Out-Default}
Извините, если я неверно понял вопрос о черных полосах.
Ответ или решение
Для задачи по совместному отображению двух видео с помощью FFmpeg, рассмотрим наиболее эффективные методы. Учитывая, что одно из видео — это презентация (слайды), а другое — спикер, и что оба видео могут иметь различные разрешения и соотношения сторон, мы можем выбрать подход, учитывающий ваши требования.
Метод A — Ваш текущий метод
ffmpeg -i small.mp4 -s 1920x1080 -c:a copy upscaled.mp4
ffmpeg -i upscaled.mp4 -i big.mp4 -filter_complex vstack=inputs=2 combinedA.mp4
Данный метод включает этап увеличения разрешения меньшего видео, затем объединение этих двух видео. Хотя он работает, он может занять много времени.
Метод B — Оптимизированный метод
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] scale=1920:1080 [a]; [1:v][a] vstack=inputs=2" combinedB.mp4
В этом подходе оба шага объединены в одном процессе. Он тоже эффективен, но требует масштабирования меньшего видео, что может замедлить обработку.
Метод C — Паддинг
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] pad=1920:1080:0:0 [a]; [1:v][a] vstack=inputs=2" combinedC.mp4
Этот метод добавляет черные полосы (или "паддинг") вокруг меньшего видео, чтобы оно соответствовало разрешению большего. Этот подход обычно быстрее, так как не влечет за собой масштабирование.
Метод D — Паддинг и наложение
ffmpeg -y -i small.mp4 -i big.mp4 -filter_complex "[0] pad=1920:1560:0:1080 [a]; [a][1:v] overlay=x=0:y=0" combinedD.mp4
Этот метод также использует паддинг, но по сути накладывает одно видео на другое. Это эффективный способ и дополнительно позволяет манипулировать положением меньшего видео.
Сравнение методов
Сравнение выполнения показало, что методы C и D проходят быстрее, чем методы A и B, особенно если учитывать, что в C и D отсутствует этап масштабирования:
Метод | Время (с) |
---|---|
A | 29.36 |
B | 19.93 |
C | 14.89 |
D | 13.74 |
Рекомендации
- Лучший выбор: Метод C будет наиболее эффективным, если панорама (aspect ratio) меньшего видео значительно меньше чем большего.
- Проблемы SAR (соотношение сторон): Если у вас разные SAR, использование паддинга может привести к неожиданным результатам на выходе.
- Использование CUDA: Если есть возможность, возможно использование аппаратного ускорения с помощью
overlay_cuda
, если ваша видеокарта поддерживает это.
Заключение
Выбор метода зависит от ваших предпочтений. Однако, если вы ищете максимальную эффективность и хотите избегать ненужного масштабирования, рекомендуется использовать Метод C с добавлением паддинга. Это сэкономит вам время на обработку и упростит рабочий процесс.