Вопрос или проблема
Мне нужно снять много видеозаписей на оперативную память и быстро их объединить. Разрешения видео могут быть разными.
Пока я использую “moviepy” на Python, но это слишком медленно.
Я открыт для идей.
Мое решение на Python:
concatenate_videoclips(clip_list, method="compose").write_videofile(
c_dir + file_n + ".mp4",
verbose=False, logger="bar",
write_logfile=False,
preset="veryfast",
threads=multiprocessing.cpu_count(),
codec="libx264")
Вы можете использовать LEADTOOLS Multimedia SDK для Windows, который имеет классы .NET для обработки видео. (Раскрытие информации: я работаю на поставщика SDK).
Одним из демонстрационных примеров, входящих в SDK, является ConcatSameSize
. Этот демонстрационный пример обрабатывает простой случай объединения 2 или более видеозаписей с диска, при условии что у них похожие свойства, такие как идентичные размеры кадров для всех файлов. Однако инструментарий позволяет легко модифицировать код демонстрации для охвата других случаев следующим образом:
-
Вместо чтения файлов с диска с использованием свойства
ConvertCtrl.SourceFile
и сохранения вывода на диск с использованиемConvertCtrl.TargetFile
, входные и выходные видео могут находиться в памяти, используя свойстваConvertCtrl.SourceStream
иConvertCtrl.TargetStream
. -
Если вам нужно работать с видеозаписями, имеющими различные размеры (разрешения кадров), вы можете использовать фильтр обработки изменения размера LEAD Video Resize для выполнения изменения размера во время объединения.
-
Если у вас есть видео с разными частотами кадров, вы можете унифицировать их частоты с помощью фильтра управления частотой кадров LEAD Video Frame Rate Controller.
Если вы хотите протестировать эти классы и компоненты, вы можете загрузить бесплатную оценочную версию по этой странице. Во время оценки доступна бесплатная поддержка по электронной почте и в чате, если у вас возникнут вопросы по использованию функций или модификации кода демонстрации.
Я бы использовал FFMPEG. Вы можете потратить несколько минут на разработку базового прототипа, а затем часы на его доработку, но для такой базовой задачи, как эта, вероятно, уже есть что-то вроде FFMPEG, что делает работу.
Вы можете сделать это с помощью чего-то подобного:
ffmpeg -threads "$(nproc)" -i ./clips/* -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=$(find ./clips -maxdepth 1 -type f | wc -l):v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" -c:v libx264 -preset ultrafast ./output.mp4
Ответ или решение
Для быстрой конкатенации видео с использованием C# или Python можно рассмотреть несколько подходов. Один из самых эффективных решений основывается на использовании библиотеки FFmpeg, которая позволяет значительно ускорить процесс объединения видео по сравнению с высокоуровневыми библиотеками, такими как MoviePy. Ниже приведены примеры на обоих языках.
Решение на Python с использованием FFmpeg
Если вы исходите из того, что MoviePy слишком медленная, FFmpeg может стать отличной альтернативой. Вот пример, как вы можете использовать FFmpeg через Python:
-
Убедитесь, что FFmpeg установлен на вашем компьютере. Вы можете загрузить его с официального сайта FFmpeg.
-
Установите библиотеку
ffmpeg-python
:pip install ffmpeg-python
-
Используйте следующий код для конкатенации видео:
import ffmpeg
import os
def concatenate_videos(input_folder, output_file):
input_files = sorted([os.path.join(input_folder, f) for f in os.listdir(input_folder) if f.endswith('.mp4')])
# Формируем строку для фильтра
filter_complex = ''
inputs = ''
for i, file in enumerate(input_files):
inputs += f'-i "{file}" '
filter_complex += f'[{i}:v:{0}][{i}:a:{0}]'
n = len(input_files)
filter_complex += f'concat=n={n}:v=1:a=1[outv][outa]'
command = (
ffmpeg
.input('pipe:0', format='concat', **{'threads': os.cpu_count()})
.output(output_file, **{'vcodec': 'libx264', 'preset': 'ultrafast'})
)
command.global_args.update({'filter_complex': filter_complex})
# Выполняем команду
command.run(input=inputs)
# Вызов функции
concatenate_videos('./clips', './output.mp4')
Решение на C# с использованием FFmpeg
Если предпочтительно использовать C#, вы можете воспользоваться библиотекой FFmpeg. Первым делом, убедитесь, что FFmpeg установлен и доступен из вашей среды:
-
Установите FFmpeg.
-
Пример кода для консольного приложения на C#:
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
string inputFolder = @"./clips";
string outputFile = "./output.mp4";
var process = new Process();
process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments = $"-threads {Environment.ProcessorCount} -i \"{inputFolder}/%d.mp4\" " +
$"-filter_complex \"concat=n=[количество_ваших_видео]:v=1:a=1[outv][outa]\" " +
"-map \"[outv]\" -map \"[outa]\" -c:v libx264 -preset ultrafast " +
$"\"{outputFile}\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
}
}
Замечания
-
Поддержка различных разрешений: Если ваши видео имеют разные разрешения или частоты кадров, вам может понадобиться выполнить предварительную обработку, используя фильтры изменения размера и контроля частоты кадров, которые предоставляет FFmpeg.
-
Оптимизация производительности: Использование параметра
-preset ultrafast
значительно ускорит процесс кодирования, однако качество выпускаемого видео может пострадать. Вы можете поэкспериментировать с другими пресетами для достижения наилучшего соотношения качества и скорости. -
Потоковое выполнение: В обоих случаях выше, вместо чтения информации из файлов на диске, вы можете использовать потоковую обработку для обработки видеофайлов в памяти.
Следуя данным инструкциям, вы сможете эффективно и быстро объединить видеофайлы с использованием FFmpeg, что станет более производительным решением по сравнению с MoviePy.