1

Here, New in FFmpeg . I am using and testing in console in FFmpeg .

I already done with 2 video join with cross fading with this question : I am doing for 5 videos merging with cross fade I just done 90% in merging i just need to manage setpts=PTS-STARTPTS Just look into this 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

****Note that every input video big_buck.mp4 length is 5 sec ****. now see setpts=PTS-STARTPTS in code How to Manage that in every video Input????

I also see in variuos forums about that but i didnt find!!! Thank you

Harsh Bhavsar
  • 1,561
  • 4
  • 21
  • 39
  • See [here](http://video.stackexchange.com/a/17504/1871). That shows the method for crossfade. You'll have to concat the overlay output with the third video. – Gyan Jun 13 '16 at 07:25

2 Answers2

5

Use

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

The PTS has to be modified so that each new clip starts 1 second before the current combination of clips ends i.e. the 3rd clip should start fading in at 8 seconds, since the combination of the first two clips is 9 seconds (4 seconds of first clip + 1 second transition + 4 seconds of 2nd clip).

You don't need the fade out as the next clip is fading in on top. The concat is only required if you want a cut.


With audio crossfades:

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
Gyan
  • 85,394
  • 9
  • 169
  • 201
  • There is no cross fading (fade in-fade out between videos )between videos [checked as output result] .it just directly merging videos.. can u edit it ... @Mulvya – Harsh Bhavsar Jun 15 '16 at 04:17
  • Corrected. The timestamps should be changed after the fade. Alternatively, the `st` values for the fades can be changed. – Gyan Jun 15 '16 at 04:52
  • @Mulvya: When I run your command, there is a small problem. The output video is only 5 seconds instead of 25 second (5 seconds for each video). Can you please tell me how to fix it? – Luong Truong Jun 23 '16 at 04:02
  • Run your command with `-report` added and link to the logfile generated. – Gyan Jun 23 '16 at 06:14
  • 2
    When I try to use this, I get `No such filter: '' Error initializing complex filters. Invalid argument`. I'm using the second command as-is, substituting my own inputs. What might be happening? – Shea Hunter Belsky Aug 02 '17 at 18:43
  • Remove all whitespace in the filtergraph. – Gyan Aug 02 '17 at 18:51
  • @Mulvya I'm able to use your video crossfade, but the audio crossfade fails with the same error: `No such filter: ''`. I removed all whitespace in the filter. Do you see any issues with this? 3 videos each 10 secs: `ffmpeg -i v1.mp4 -i v2.mp4 -i v3.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS[v1];[1:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(9/TB)[v2];[2:v]format=yuva420p,fade=in:st=0:d=1:alpha=1,setpts=PTS-STARTPTS+(18/TB)[v3];[v1][v2]overlay[v12];[v12][v3]overlay,format=yuv420p[v];[1][2]acrossfade=d=1[a12];[a12][3]acrossfade=d=1[a];" -map [v] -map [a] result.mp4` – Chase Rocker Mar 19 '18 at 18:15
  • Remove the last semicolon. – Gyan Mar 19 '18 at 19:21
  • @Gyan I'm also getting `No such filter: ''`. I've tried removing all whitespace. If I remove the last semicolon, I get `Invalid file index 5 in filtergraph description`. Link to ffmpeg report output: https://pastebin.com/G1UfYMXP – IanB Oct 01 '18 at 01:11
  • Replace `[a123][4]acrossfade=d=1[a1234];[a1234][5]acrossfade=d=1[a];` with `[a123][4]acrossfade=d=1[a]` – Gyan Oct 01 '18 at 04:33
  • @Gyan that worked, thankyou. Please updated the answer. – IanB Oct 01 '18 at 21:56
  • Is there no way to simplify those convoluted last lines, or can the overlay/acrossfade filters only take two inputs at a time? – Hashim Aziz Jun 23 '21 at 22:54
3

Based on the Gyan's answer I have created a convenient Bash script video_crossfade.sh to crossfade any number of videos of different duration.

#!/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"

Example:

./video_crossfade.sh '*.MP4'

Result:

crossfade any number of images using ffmpeg

The script takes all videos form by wildcard pattern and uses ffprobe to get the video duration.

Eugene Khyst
  • 9,236
  • 7
  • 38
  • 65