Maximilian Freitag
Maximilian Freitag

Reputation: 1049

How can I loop a mp4 file in moviepy?

My current code is taking a mp4 video file, it adds a mp3 music file to it, the duration of the mp4 file is set to the length of the mp3 file, the clip is resized to 1920x1080 pixels and finally it saves and outputs the finished video.

Result: The finished video plays the mp4 file one time and then freezes until the mp3 file ends.

Result that I want: How can I make the mp4 file loop until the end of the mp3 file so it doesn't freeze after one play.


from moviepy.editor import *
import moviepy.editor as mp
import moviepy.video.fx.all as vfx


audio = AudioFileClip("PATH/TO/MP3_FILE")

clip = VideoFileClip("PATH/TO/MP4_FILE").set_duration(audio.duration)


# Set the audio of the clip
clip = clip.set_audio(audio)

#Resizing
clip_resized = clip.resize((1920, 1080)) 


#Code that doesn't work for looping
newClip = vfx.loop(clip_resized)


# Export the clip
clip_resized.write_videofile("movie_resized.mp4", fps=24)

The code itself works but the mp4 doesn't loop until the end. Thanks in advance.

Upvotes: 2

Views: 5561

Answers (3)

Marlin Mack
Marlin Mack

Reputation: 1

I tried reproducing this without having a background clip, but had no dice. I'm not sure if having a background image/clip gives the looped video something to attach to, but this code will let you loop a video for a specified time, which you should be able to specify with clip.duration

Apologies if this post doesn't fit general posting guidelines it's my first time.

media_clip = VideoFileClip(media, audio=True).fx(vfx.colorx, 0.75)
clip_duration = media_clip.duration
max_duration = 10  # Maximum duration in seconds
min_duration = 3

if clip_duration > max_duration:
    media_clip = media_clip.subclip(0, max_duration)

if clip_duration < min_duration:
    # Calculate the number of times to repeat the video to reach the desired duration
    num_repeats = int(min_duration / clip_duration) + 1

    # Create a list of repeated video clips
    repeated_clips = [media_clip] * num_repeats

    # Concatenate the repeated clips to create the final video
    final_clip = concatenate_videoclips(repeated_clips, method="compose")

    # Trim the final concatenated clip to the desired duration
    final_clip = final_clip.subclip(0, min_duration)
else:
    final_clip = media_clip

# Load the background image
background_clip = ImageClip('input.png', duration=final_clip.duration)



# Composite the media clip and background
composite_clip = CompositeVideoClip([background_clip, final_clip.set_position((x, y))])
composite_clip = composite_clip.set_duration(final_clip.duration)

# Write the final video
output_video = "output.mp4"
composite_clip.write_videofile(
    output_video,
    codec="libx264",
    audio_codec="aac",
    bitrate='1000k',
    preset='medium',
    ffmpeg_params=["-profile:v", "baseline", "-level", "3.0"],
    threads=4  # Number of threads for video encoding (adjust as needed)
)

Upvotes: 0

Amed
Amed

Reputation: 321

If you get this error :

OSError: Error in file ...video.mp4, Accessing time t=101.77-101.81 seconds, with clip duration=101 seconds,

This problem occured because the loop do not match with the audio of the final looped video file

So you have to extract the audio from the video file (or your custom audio file) and loop it too as the video file

    audio = AudioFileClip("video.mp4")#here i'm using the audio of the original video but if you have custom audio pass it here
    audio = afx.audio_loop(audio, duration=500) #you can use n=X too 
    clip1 = VideoFileClip("video.mp4")
    clip1 = vfx.loop(clip1, duration=500) #you can use n=X too 
    clip1 = clip1.set_audio(audio)
    clip1.write_videofile("movie.mp4")

Upvotes: 5

Bandit
Bandit

Reputation: 81

3 Years late on that one, but it's still the top result for this on google.

If you want to loop it for the duration of audio, moviepy has a simple loop function that you call from the clip you want to loop, it takes either the amount of loops or the duration of time to loop for.

So in your case it would be

loopedClip = clip_resized.loop(duration = audio.duration)

Or if you don't want to create a seperate clip then

clip_resized = clip_resized.loop(duration = audio.duration)

Upvotes: 7

Related Questions