I have a list of 4 moviepy ImageClips that I want to concatenate and then export. I notice that when I export the concatenated videoclip, it starts exporting at ~60 it/s but it quickly drops to ~6 after a couple seconds. I suspect that the drop is when it reaches the third clip, which is significantly longer than the others. The first are less than half a minute, while the third clip is upwards of 10 minutes. The first two clips are generated in the following way:
background = Image.open("background.jpg")
new_background = background.resize((screen_width, screen_height))
new_background.save("temp/resized_background.png")
# Maybe I could speed this up by only resizing the background once, but that is irrelevant to this issue
image_clip = ImageClip(f"temp/resized_background.png")
audio_clip = AudioFileClip(f'temp/{random_file_name}.mp3')
video_clip = image_clip.set_audio(audio_clip)
video_clip.duration = audio_clip.duration
video_clip.fps = fps # fps=12
# Memory cleanup
del background
del new_background
del image_clip
del audio_clip
return video_clip
The third clip is created by the following code:
clips = []
for pic, audioFile in zip(self.images, self.audioFiles):
try:
audio_clip = AudioFileClip(f"temp/{audioFile}.mp3")
image_clip = ImageClip(f"temp/{pic}.png").resize((screen_height, screen_width))
# The images should already be this size, but also irrelevant here
except:
continue
video_clip = image_clip.set_audio(audio_clip)
video_clip.duration = audio_clip.duration
video_clip.fps = self.fps
clips.append(video_clip)
# Memory management
del image_clip
del audio_clip
del video_clip
unsilenced_video = concatenate_videoclips(clips, method="compose")
del clips
self.duration = unsilenced_video.duration
self.fullClip = unsilenced_video
del unsilenced_video
return self
I then made sure all of them are in a list in the correct order. Then I concatenate them
concat_clip = concatenate_videoclips(allClipsInOrder, method="compose")
# Put soft background music over the whole video
background = AudioFileClip("background_music.mp3").volumex(0.1)
full_background = afx.audio_loop(background, duration=concat_clip.duration)
final_audio = CompositeAudioClip([concat_clip.audio, full_background])
self.full_video = concat_clip.set_audio(final_audio)
And finally export them:
self.full_video.write_videofile("sample_name.mp4", fps=self.fps, codec='h264_nvenc', verbose=False)
I have an NVIDIA RTX 3060 laptop GPU, hence the codec. However, when I try to export it, task manager shows that my RAM is being eaten(90+%) and my GPU is hardly being used(like 5%). I have also tried the libx264 codec, specifying different amounts of threads and without specifying threads, which give pretty much the same result. I also tried specifying the bitrate, without any luck. I am not sure if I need to install anything else that might allow me to use my GPU more effectively or that there is another setting I could use.
The weird thing is that when I export each of the clips separately(that means without background music added, I don't think that that matters since it starts at high it/s with it too), it does stay at a reasonable export speed. All the clips should however have the same size and fps, so I don't know what the issue is. I understand that lowering the size would speed it up and disabling logger would too, but that would still mean the high difference in export speed for the concatenated clip and the separate clips.
Is there a way to make the exporting faster? Or is it better to export the clips separately and then try to concatenate them afterwards? By deleting variables, I tried to clear up some of my RAM which also helped a bit, but still doesn't fix the issue
FFMPEG with moviepy This source also shows something about CompositeVideoClip, but I could not get that to work and not sure if that fixes the issue, as that is for concatenating I think, not exporting.