Search code examples
pythonvideoconcatenationtransitionmoviepy

How to add transitions between clips in moviepy?


My current attempt:

This is my current code:

from moviepy.editor import *

clips = [VideoFileClip('a.mp4'), VideoFileClip('b.mp4'), VideoFileClip('c.mp4')]
transitioned_clips = [demo_clip.crossfadein(2) for demo_clip in clips]
for_delivery = concatenate_videoclips(transitioned_clips)
for_delivery.write_videofile(target_path, fps=clip.fps, bitrate='%dK' % (bitrate), threads=50, verbose=False, logger=None, preset='ultrafast')

I also tried using CompositeVideoClip, but:

  1. It resulted in a completely black video.

  2. Even for the completely black video it took 50 times longer to write the video file than for without transitions.

My current output:

My current output is a video with the 3 videos concatenated (which is good), but no transitions between the clips (which is not good).

My goal:

My goal is to add the crossfadein transition for 2 seconds between the clips and concatenate the clips into one video and output it.

In other words, I want it like (in order from left to right):

|        |      +       |        |      +       |        |
| clip 1 | transition 1 | clip 2 | transition 2 | clip 3 |
|        |      +       |        |      +       |        |

Is there anyway to have transitions? Any help appreciated.


Solution

  • You could try this approach of manually setting the start time to handle the transitions.

    padding = 2
    
    video_clips = [VideoFileClip('a.mp4'), VideoFileClip('b.mp4'), VideoFileClip('c.mp4')]
    
    video_fx_list = [video_clips[0]]
    
    idx = video_clips[0].duration - padding
    for video in video_clips[1:]:
        video_fx_list.append(video.set_start(idx).crossfadein(padding))
        idx += video.duration - padding
    
    final_video = CompositeVideoClip(video_fx_list)
    final_video.write_videofile(target_path, fps=clip.fps) # add any remaining params
    

    Edit:
    Here's an attempt using concatenate:

    custom_padding = 2
    final_video = concatenate(
        [
            clip1,
            clip2.crossfadein(custom_padding),
            clip3.crossfadein(custom_padding)
        ],
        padding=-custom_padding,
        method="chain"
    )
    final_video.write_videofile(target_path, fps=clip.fps) # add any remaining params