FFMPEG: Как объединить видео и изображение (шаблон видео)

#node.js #ffmpeg #video-processing #fluent-ffmpeg

Вопрос:

Цель

У меня есть видео и изображение (шаблон для видео), которые я пытаюсь объединить в одно выходное видео (соотношение сторон 1080w x 1920h — 9:16).

  • Входное видео — 1920×1080
  • Входное изображение — 1080×1920
  • Выходное видео — 1080×1920

Это изображение показывает, чего я пытаюсь достичь. Две оранжевые секции являются входным изображением — это единое .png целое с прозрачной секцией посередине для видео.

Как уже упоминалось в названии, я пытаюсь сделать это с помощью FFMPEG . Более конкретно, я использую пакет npm fluent-ffmpeg.

Текущее Состояние

Я могу читать на обоих входах просто отлично, но у меня есть проблемы с тем, чтобы заставить их хорошо взаимодействовать друг с другом.

Если я заставлю наложение работать, то мое выходное видео будет 1920х1080 вместо 1080×1920.

Если я правильно определяю размеры выходного видео, то видео либо растягивается, либо я получаю ошибки при добавлении наложения.

Код

Вот что у меня есть на данный момент. Я с радостью отвечу на любые вопросы. Заранее благодарю вас за то, что взглянули 🙂

 var ffmpeg = require('fluent-ffmpeg');
var command = ffmpeg();
var timemark = null;

command
  .on('end', onEnd )
  .on('progress', onProgress)
  .on('error', onError)
  .input('./input-video.mp4')
  .input('./template.png')
  .complexFilter([
    {
      filter: 'scale',
      options: { width: 1080, height: 1920 }
    },
    // {
    //   filter: 'overlay',
    //   options: { x: 100, y: 100 }
    // },
  ])
  .outputFps(30)
  .output('./output-video.mp4')
  .run();

/* Misc */

function onProgress(progress){
  if (progress.timemark != timemark) {
    timemark = progress.timemark;
    console.log('Time mark: '   timemark   "...");
  }
}

function onError(err, stdout, stderr) {
  console.log('Cannot process video: '   err.message);
}

function onEnd() {
  console.log('Finished processing');
}
 

Комментарии:

1. Похоже, вам нужно сначала масштабировать входное видео до ширины 1080, прежде чем добавлять изображение в качестве второго ввода. Обычно команда такова: ffmpeg -i input-video.mp4 -vf scale=1080:-1 -i template.png -filter_complex "overlay=100:100" output-video.mp4 поэтому вам придется найти способ установить фильтр видео на 1-м входе, прежде чем выполнять сложный фильтр при использовании Fluent-FFmpeg.

Ответ №1:

Благодаря пользователю Voldrix_Suroku на Reddit я смог это выяснить.

Чтобы не быть DenverCoder9, команда CLI, чтобы заставить это работать,:

ffmpeg -i input-video.mp4 -i template.png -filter_complex "[0:V]scale=1080:-1,pad=0:1920:0:(oh-ih)/2[vid];[vid][1:v]overlay" output-video.mp4

И если вы используете fluent-ffmpeg , как я, полный код ниже:

 var ffmpeg = require('fluent-ffmpeg');
var command = ffmpeg();
var timemark = null;

command
  .on('end', onEnd )
  .on('progress', onProgress)
  .on('error', onError)
  .input('./input-video.mp4')
  .input('./template.png')
  .complexFilter([
    "[0:V]scale=1080:-1,pad=0:1920:0:(oh-ih)/2[vid];[vid][1:v]overlay"
  ])
  .outputFps(30)
  .output('./output-video.mp4')
  .run();

/* Misc */

function onProgress(progress){
  if (progress.timemark != timemark) {
    timemark = progress.timemark;
    console.log('Time mark: '   timemark   "...");
  }
}

function onError(err, stdout, stderr) {
  console.log('Cannot process video: '   err.message);
}

function onEnd() {
  console.log('Finished processing');
}