Команда FFmpeg для кроссфейдинга между 5 видео. Как управлять setpts=PTS-STARTPTS?

Здесь, Новое в FFmpeg . Я использую и тестирую в консоли в FFmpeg .

Я уже закончил с соединением 2 видео с кросс-фейдингом с этим вопросом: я делаю слияние 5 видео с кросс-фейдом. Я только что сделал слияние на 90%, мне просто нужно управлять setpts=PTS-STARTPTS Просто посмотрите на этот PLS.

ffmpeg -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i 
big_buck.mp4 -filter_complex "[0:v]trim=0:4,setpts=PTS-
STARTPTS,fade=out:st=4:d=1:alpha=1[1]; [1:v]trim=1:4,setpts=PTS-
STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1,fade=out:st=4:d=1:alpha=1[2]; 
[2:v]trim=1:4,setpts=PTS-
STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1,fade=out:st=4:d=1:alpha=1[3]; 
[3:v]trim=1:4,setpts=PTS-
STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1,fade=out:st=4:d=1:alpha=1[4]; 
[4:v]trim=1:4,setpts=PTS-STARTPTS,format=yuva420p,fade=in:st=0:d=1:alpha=1[5]; 
[1][2]overlay,format=yuv420p[12]; [12][3]overlay,format=yuv420p[123]; [4]
[5]overlay,format=yuv420p[45]; [123][45]concat=n=2 [v]" -map [v]  result.mp4

**** Обратите внимание, что продолжительность каждого входного видео big_buck.mp4 составляет 5 секунд ****. Теперь посмотрите setpts=PTS-STARTPTS в коде Как управлять этим в каждом видео входе????

Я также вижу в форумах variuos об этом, но я не нашел!!! Спасибо

3 ответа

Решение

Использование

ffmpeg -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i 
big_buck.mp4 -filter_complex \
"[0:v]setpts=PTS-STARTPTS[v1]; \
 [1:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(4/TB)[v2]; 
[2:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(8/TB)[v3]; 
[3:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(12/TB)[v4]; 
[4:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(16/TB)[v5]; 
[v1][v2]overlay[v12]; [v12][v3]overlay[v123]; [v123][v4]overlay[v1234]; [v1234][v5]overlay,format=yuv420p[v]" \
-map [v]  result.mp4

PTS должен быть модифицирован таким образом, чтобы каждый новый клип начинался за 1 секунду до окончания текущей комбинации клипов, то есть 3-й клип должен начать исчезать через 8 секунд, поскольку комбинация первых двух клипов составляет 9 секунд (4 секунды первого клипа + 1 секунда перехода + 4 секунды 2-го клипа).

Вам не нужно исчезать, так как следующий клип исчезает сверху. Concat требуется только если вы хотите вырезать.


С аудио перекрёстками:

ffmpeg -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i big_buck.mp4 -i 
big_buck.mp4 -filter_complex \
"[0:v]setpts=PTS-STARTPTS[v1]; \
 [1:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(4/TB)[v2]; 
[2:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(8/TB)[v3]; 
[3:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(12/TB)[v4]; 
[4:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(16/TB)[v5]; 
[v1][v2]overlay[12]; [12][v3]overlay[123]; [123][v4]overlay[1234]; [1234][v5]overlay,format=yuv420p[v]; \
[1][2]acrossfade=d=1[a12]; [a12][3]acrossfade=d=1[a123]; [a123][4]acrossfade=d=1[a];" \
-map [v] -map [a] result.mp4

На основе user5726027 я создал удобный скрипт Bash. ответаvideo_crossfade.shдля перекрестного затухания любого количества видео разной продолжительности.

      #!/bin/bash

INPUT="$1"
CMD="ffmpeg"
SIZE=$(find . -iname "$INPUT" | wc -l)

if (( SIZE < 2 ))
then
  echo "2 or more videos are required"
  exit 1
fi

VIDEO=""
OUT=""

i="0"
total_duration="0"
for file in $(find . -iname "$INPUT" | sort)
do
  echo $file
  CMD="$CMD -i $file"

  duration=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of csv=p=0 "$file" | cut -d'.' -f1)

  if [[ "$i" == "0" ]]
  then
    VIDEO="[0:v]setpts=PTS-STARTPTS[v0];"
  else
    fade_start=$((total_duration-$i))
    VIDEO="${VIDEO}[${i}:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(${fade_start}/TB)[v${i}];"
    if (( i < SIZE-1 ))
    then
      if (( i == 1 ))
      then
        OUT="${OUT}[v0][v1]overlay[outv1];"
      else
        OUT="${OUT}[outv$((i-1))][v${i}]overlay[outv${i}];"
      fi
    else
      if (( SIZE == 2 ))
      then
        OUT="${OUT}[v0][v1]overlay,format=yuv420p[outv]"
      else
        OUT="${OUT}[outv$((i-1))][v${i}]overlay,format=yuv420p[outv]"
      fi
    fi
  fi

  total_duration=$((total_duration+duration))

  i=$((i+1))
done

CMD="$CMD -filter_complex \"${VIDEO}${OUT}\" -c:v libx264 -map [outv] crossfade.MP4"

echo "$CMD"

bash -c "$CMD"

Пример:

      ./video_crossfade.sh '*.MP4'

Результат:

Сценарий принимает форму всех видео по шаблону подстановочных знаков и использует ffprobeчтобы получить продолжительность видео.

вы можете установить ширину и высоту в слиянии видео FFmpeg 5

      ffmpeg -i 1699476962.mp4 -i 1699860586.mp4 -i 1699752055.mp4 -i 1699860586.mp4 -i 1699752055.mp4 -filter_complex "[0:v]scale=240:320[v0];[1:v]scale=240:320[v1];[2:v]scale=240:320[v2];[3:v]scale=240:320[v3];[4:v]scale=240:320[v4];[v0][v1][v2][v3][v4]xstack=inputs=5:layout=0_0|w0_0|w0+w1_0|0_h0|w0_h0:fill=black[outv];[0:a][1:a][2:a][3:a][4:a]amix=inputs=5[a]" -map "[outv]" -map "[a]" -ac 2 240x320.mp4
Другие вопросы по тегам