Zulko / moviepy

Video editing with Python
https://zulko.github.io/moviepy/
MIT License
12.54k stars 1.57k forks source link

How to concatenate videos with crossfadein / crossfadeout ? #744

Closed PyB1l closed 5 years ago

PyB1l commented 6 years ago

Pure concatenate_videos, even if you apply fadein fadeout effects does not acctually overlaps videos. Can i achive the same result with CompositeVideoClip?

mgaitan commented 6 years ago

@PyB1l please, check this answer https://www.reddit.com/r/moviepy/comments/2f43e3/crossfades/ck7dzby

@Zulko @tburrows13 do you agree this should be explicited at least as an example in the docs?

and what about to add an extra (optional) argument to concatenate_videoclips named transition_effect as a string or function, to simplify these typical minimal usage? For instance, this case would be something like

concatenate_videoclips([v1, v2, v3], effect='crossfadein', padding=-2)
keikoro commented 5 years ago

Any update on this?

PyB1l commented 5 years ago

It seems it's not that trivial for a new user, i ended up doing something like this:

`

padding = 1.5 # padding option

video_clips = [VideoFileClip(video) for video in clip_list]  #  clips to concatenate

video_fx_list = [video_clips[0]]
# set padding to initial video

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('my-outfile', fps=24)` 

Nevertheless I think it should be as explicit example in documentation

steinathan commented 3 weeks ago

As of 2024, this is my hacky solution:

# list of video clips
image_clips = [
    ImageClip(f"/tmp/background_images/{i}.jpg").with_duration(5)
    for i in range(1, 6)
]

# list of effects
effects: list[Callable[[Clip], Clip]] = [
    lambda clip: zoom_in_effect(clip),
    lambda clip: zoom_out_effect(clip),
   # add more effects
]

padding = 1.5

for i in range(len(image_clips)):
    effect = random.choice(effects)
    if i != 0:
        image_clips[i] = effect(image_clips[i]).crossfadein(padding)  # type: ignore
    else:
        image_clips[i] = effect(image_clips[i])

final_clip = concatenate_videoclips(image_clips, method="compose")
final_clip.write_videofile(
    "/tmp/video.mp4",
    fps=17,
    preset="ultrafast",
)