Search code examples
pythonffmpegconcatenationtrimmoviepy

Concatenate Movies from Python List using MoviePy or FFmpeg


I have about 10,000 short videos that I am trying to make several longer videos from.

I've created these videos using MoviePy, but keep getting memory errors when trying to concatenate them back together.

In my code I have an outer loop going through each letter of the alphabet and getting the files that start with that letter.

From the returned video clips I get the length and and strip off the last 3.5 seconds (outro_clip_duration) of the video, and then add it into a Python list clips.

Where I'm stuck is I then want to take this list of trimmed videos and make one long long video from it.

I have all the files, I just need to trim them, concatenate them, and then export them as one.

I've tried many times with different MoviePy attempts and keep getting MemoryErrors so I gave up and took a swing at an ffmpeg solution seen here but it is not working out either.

The latest version of the main part of my code is here:

clips = []
outro_clip = mpy.VideoFileClip('Logo_Intro_w_Stinger_Large.mp4')
outro_clip_duration = outro_clip.duration
for def_image in vid_list_long:
    video_item = mpy.VideoFileClip('F:/sm_My_Video/sm_%s.mp4' % def_image)
    video_item_duration = video_item.duration
    clips.append(ffmpeg_extract_subclip(video_item,0,(video_item_duration - outro_clip_duration), targetname = def_image))

# #Append the outro_clip to the end 
clips.append(mpy.VideoFileClip('Logo_Intro_w_Stinger_Large.mp4',target_resolution = (h,w),audio=True))
slided_clips = [CompositeVideoClip([clip.fx( transfx.crossfadein, transition_seconds)]) for clip in clips]
#added 'method = compose' NEED TO TEST - supposedly removes the weird glitches.
c = concatenate_videoclips(slided_clips, method = 'compose')
c.write_videofile('F:/Extended_Play/%s_Extended_Play_vid.mp4' % letter,fps=23.98)

My PC is Windows 10 and I have 32 GB of RAM running Anaconda and Python 3.


Solution

  • You should try closing the clips once you're done using them by adding close_clip(video_item) at the end of your for loop, something like

    for def_image in vid_list_long:
        video_item = mpy.VideoFileClip('F:/sm_My_Video/sm_%s.mp4' % def_image)
        video_item_duration = video_item.duration
        clips.append(ffmpeg_extract_subclip(video_item,0,(video_item_duration - outro_clip_duration), targetname = def_image))
        close_clip(video_item)
    

    Where the close_clip() would look something like

    def close_clip(clip):
      try:
        clip.reader.close()
        if clip.audio != None:
          clip.audio.reader.close_proc()
          del clip.audio
        del clip
      except Exception as e:
        print("Error in close_clip() ", e)