1

I am looking to join a set of video clips (with audio) using some short transitions (ideally crossfade) in a straightforward, automated and efficient way.

IE:

ClipA ---> ClipB --> ClipC --> ClipD
[aaaaaaaa][bbbbbbbb][cccccccc][dddddddd]
(--> indicate crossfades, not to scale!)

To clarify:

  • by straightforward, ideally it would involve using 'standard' tools (ie ones that I am already familiar with such ffmpeg, but less well-known tools like melt definitely qualify, and I'm willing to explore new horizons like MoviePy)
  • by automated I mean something that can be parameterised and put into a python/shell/etc script
  • by efficient I mean quick-to-encode or minimising re-encoding

At the moment I'm using python and ffmpeg to chop up a video file already in Matroska/h264/aac using the stream copy parameter (very fast) based on timecodes in a text file. Then melt sequentially strings these clips one after the other using short luma (crossfade) transitions (very slow due to re-encoding entire sequence).

It seems to me that out of these long video clips only a few seconds needs to be processed and re-encoded- the transitions themselves. The rest can be copied. Is there an already-extant / intuitive way of doing this? My naïve approach would be to further chop the clips into subclips, using melt to create the transitions, and using the concat filter to glue the mess together.

Eg:

ClipA1 ClipA2 ClipB1 ClipB2 ClipB3 ClipC1 ClipC2 ClipC3 ClipD1 Clip D2
[aaaaaaa] + [a][b] + [bbbbbb] + [b][c] + [cccccc] + [c][d] + [ddddddd]
(+ indicates concat-ing of subclips; [x][y] indicates a short xfade from x to y)

However, I am reticent to charge off on what may be a fool's errand as I anticipate melt/ffmpeg-related gotchas around timing of cuts and audio synchronisation; and I don't want to miss sections of video or audio due to I-frame placement or what have you. Plus I have a feeling I am not the first person to run into this, so I am curious as to how those smarter than I have solved this- my solutions tend to the naïve as I say!

Hope this has been clear. Cheers for reading and thanks in advance!


For context, my intention is to reduce unedited livestreamed video game footage into an interesting / "useful" video; that is cut out the boring fluff of loading stuff up, sorting connectivity issues etc. But it is also generalisable to highlights, a montage to show progression. Since it is something that in theory will come up every time there is new footage, I have a strong interest in doing it the most efficient (proactively laziest) way.

bertieb
  • 7,344
  • 36
  • 42
  • 54
  • I think [this](http://stackoverflow.com/questions/30395469/ffmpeg-audio-crossfade) is what you are looking for. But still it process the whole video. – Chamath Jun 23 '15 at 05:45
  • @Chamath thanks for that- yes it does incur a re-encode but it may in fact form part of the solution; see a related question I've asked: http://superuser.com/questions/931969/creating-videos-for-ffmpegs-concat-demuxer-to-avoid-a-large-re-encode – bertieb Jun 24 '15 at 11:52

2 Answers2

7

I didn't have time to test it but this should work if you want to go with MoviePy:

from moviepy.editor import *

clips = [ VideoFileClip("vid1.mp4"),
          VideoFileClip("vid2.mp4"),
          VideoFileClip("vid3.mp4"), ... ]


fade_duration = 1 # 1-second fade-in for each clip
clips = [clip.crossfadein(fade_duration) for clip in clips]

final_clip = concatenate_videoclips(clips, padding = -fade_duration)

# You can write any format, in any quality.
final_clip.write_videofile("final.mp4", bitrate="5000k")
Zulko
  • 171
  • 1
  • 1
    As I am unfamiliar with MoviePy, this is very useful- thank you! However, it incurs a transcode across the entire duration of video unfortunately; trying with 2 clips is giving a predicted ~2hr encode duration. Is this unavoidable or have I not used your sample code correctly? – bertieb Jun 23 '15 at 12:00
  • 1
    @bertieb same problem here, it takes too long, did you find anything efficient ? – Mathematics Jun 02 '19 at 11:11
-1

Here is another way to use the Python moviePy library to create fading effect between joint video clips. Tested on windows 10 with Python 3.x. I had to first install the moviepy from Windows command prompt where the python installation directory is like so:

C:\Users\...\Programs\Python\Python37\Scripts> pip3.7.exe install moviepy; 

Here's the full code to use the CompositeVideoClip method for joining three short video clips with CrossFadeIn effect added:

from moviepy.editor import *
# video lists and play time
clip1 = VideoFileClip("part1.mp4") #30s length
clip2 = VideoFileClip("part2.mp4") #12s
clip3 = VideoFileClip("part3.mp4") #20s

# Composite video and apply CrossFadeIn effect
video=CompositeVideoClip([clip1,
                          clip2.set_start(30).crossfadein(1),
                          clip3.set_start(32).crossfadein(1.5)])

#write to file
video.write_videofile("my_composite.mp4")

Further readings/examples, see this https://www.journaldev.com/46531/python-moviepy-video-editing

Harry
  • 154
  • 3
  • Thank you for answering an old question, but does this add anything beyond that the other answer using MoviePy? I use MoviePy and like it, but the issue with the other answer too is that it incurs a transcode across the entire video, which is very slow – bertieb Jan 08 '21 at 19:15
  • I tested the code by Zulko. When set duration time to 5 or 10 seconds, I couldn't notice any fade effect. Sending to 1 will just get you a seamless transition with no effect. Doesn't work well which motivates me to search for other solutions. The clips I used were very short so the speed is fine for merging them together and I could see the fading effect. – Harry Jan 08 '21 at 23:47