Reputation: 13
I'm trying to create a video that keeps the proportions of the original (horizontal) video centered. Also, there should be a blurred background around the video that fills the entire screen. This should result in a vertical video with a small video superimposed on it with the proportions of the horizontal video preserved. The input video has a resolution: width 960 and 540 heght. My current code:
from moviepy import VideoFileClip, ColorClip, CompositeVideoClip, ImageClip, concatenate_videoclips, vfx
def x1(t):
return 960 * (t / video.duration)
def y1(t):
return 1920 * (t / video.duration)
scaled_clip = video.resized(new_size=(960, 1920))
blurred_clip = scaled_clip.with_effects([vfx.HeadBlur(fx=x1, fy=y1, radius=20)])
blurred_clip = blurred_clip.with_position('center')
composite_clip = CompositeVideoClip([blurred_clip , scaled_clip])
composite_clip.write_videofile('output.mp4', codec='libx264', audio_codec="aac", fps=video.fps)
I recently started learning MoviePy, I found in the documentation that HeadBlur is used in a similar way, but I didn't find any examples. Generally on the internet the information is only about versions earlier than 2.0.0. The earlier versions used Blur and the current version uses HeadBlur, but it doesn't blur my video. Also I'm not sure if the x1 and y1 functions are calculating the coordinates for blur correctly Any reply would be appreciated.
Version Python: 3.11 Version Moviepy: 2.1.1 Version Pillow: 11.0.0 Version ffmpeg-python: 0.2.0
Upvotes: 0
Views: 135
Reputation: 1
I was having the same problem, and I found out the solution after tweaking with the variables for a while. So first you need to get a bigger radius, because the video is probably bigger than 20, so I just put a randomly big number like 9999, but if you do just that it will not blur, it will give an opaque color, so you need then to change the intensity. So in short, it would be something like this:
from moviepy.video.fx import HeadBlur
def fx(t):
return background.w * (t / background.duration) # X position (center)
def fy(t):
return background.h * (t / background.duration) # Y position (center)
radius = 9999 # it is enough because it will crop on the video dimensions anyway
background = background.with_effects([HeadBlur(fx,fy,radius, intensity=50)])
Maybe there are better ways to do this, and this blur is kind of weird because it is just a circular blur and will not cover the whole screen.
An alternative blur could be fx.SuperSample, but it doesn't give quite the results you might want (it's motion blur rather than full blur) so it's worse in some way.
For actual full blur I'm afraid I don't know as well..
Upvotes: 0