Zulko / moviepy

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

how to keep the aspect ratio for my vertical video? #2192

Closed fcsouza closed 3 weeks ago

fcsouza commented 4 weeks ago

Hello, I wrote this code that uses a list of images in 1024x1024.

After that, I resize these images to 480x854.

With this, I created the video. I wanted it to cover the entire screen, but the final result is that it looks stretched on the screen. I wanted it to maintain the aspect ratio for vertical screens.

What am I doing wrong in my code? I am sending my video and another one that I hope to achieve the same result.

def build_image_clips(images, audio_file):
    audio = AudioFileClip(audio_file)
    audio_duration = audio.duration

    image_duration = audio_duration / len(images)

    video_clips = []

      for image_url in images:
          image_clip = ImageClip(image_url).set_fps(30).set_duration(image_duration)
          image_clip = image_clip.set_position("center").resize(newsize=(480, 854))
          image_clip = Zoom(
              image_clip, mode="in", position="center", speed=5.0
          ) 
          video_clips.append(image_clip)

    final_video = concatenate_videoclips(video_clips)
    final_video = CompositeVideoClip([images_clips], size=(480, 854))

    final_video.write_videofile(
     "output.mp4", fps=30, codec="libx264", audio_codec="aac"
    )

my objective is keep the aspect ratio for vertical videos.

https://github.com/Zulko/moviepy/assets/7094035/cbc1aaab-b533-4015-9480-8fcd51fac298

https://github.com/Zulko/moviepy/assets/7094035/01d6f0af-a3fa-4883-9bf1-b12ca496d5de

antonpetrov145 commented 3 weeks ago

Hello, so you can calculate the aspect ratio like this

ratio = int(video_width) / int(video_height)

then you can use this value to calculate the width when keeping the height

video_width = video_width * ratio

and pass these values to your functions

fcsouza commented 3 weeks ago

hi @antonpetrov145

i made the adjust to my code, but this is the output now.

https://github.com/Zulko/moviepy/assets/7094035/d943e121-ca2e-4ea1-b228-4018d3ee87aa

def build_image_clips(images, audio_file):
    audio = AudioFileClip(audio_file)
    audio_duration = audio.duration

    image_duration = audio_duration / len(images)

    video_clips = []
    ratio = int(480) / int(854)
    video_width = 480 * ratio

      for image_url in images:
          image_clip = ImageClip(image_url).set_fps(30).set_duration(image_duration)
          image_clip = image_clip.set_position("center").resize(width=video_width)
          image_clip = Zoom(
              image_clip, mode="in", position="center", speed=5.0
          ) 
          video_clips.append(image_clip)

    final_video = concatenate_videoclips(video_clips)
    final_video = CompositeVideoClip([final_video], size=(480, 854))

    final_video.write_videofile(
     "output.mp4", fps=30, codec="libx264", audio_codec="aac"
    )
antonpetrov145 commented 3 weeks ago

can you add the values to ComposeiteVideoClip too, and try with that

fcsouza commented 3 weeks ago

using this way, return a error.

cannot unpack non-iterable float object
def build_image_clips(images, audio_file):
    audio = AudioFileClip(audio_file)
    audio_duration = audio.duration

    image_duration = audio_duration / len(images)

    video_clips = []
    ratio = int(480) / int(854)
    video_width = 480 * ratio

      for image_url in images:
          image_clip = ImageClip(image_url).set_fps(30).set_duration(image_duration)
          image_clip = image_clip.set_position("center").resize(width=video_width)
          image_clip = Zoom(
              image_clip, mode="in", position="center", speed=5.0
          ) 
          video_clips.append(image_clip)

    final_video = concatenate_videoclips(video_clips)
    final_video = CompositeVideoClip([final_video], size=video_width)

    final_video.write_videofile(
     "output.mp4", fps=30, codec="libx264", audio_codec="aac"
    )
antonpetrov145 commented 3 weeks ago

seems your ratio or video_width is float instead of integer, can you check?

on resize you can use resize(newsize=(video_width, video_height))