Zulko / moviepy

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

Text Alignment and Multiple TextClips not working in moviepy #1977

Open ItachiUchiha5277 opened 1 year ago

ItachiUchiha5277 commented 1 year ago

moviepy version: 1.0.3 python version: 3.8.0 OS: Windows 11 ImageMagick Version 7.1.1

I have a VideoClip on which I am trying to put multiple TextClips

audioclip = AudioFileClip("title.mp3")

# fetching minecraft parkour clip
clip = VideoFileClip("minecraft_parkour.mp4").subclip(2,2+audioclip.duration+0.4)

# cropping the minecraft parkour video to a portrait
(w, h) = clip.size
crop_width = h * 9/16
x1, x2 = (w - crop_width)//2, (w+crop_width)//2
y1, y2 = 0, h

croppedClip = clip.crop(x1=x1, y1=y1, x2=x2, y2=y2)
vid = croppedClip.set_audio(audioclip)
print(vid.size)
###### ----- TODO: Fix error in adding multiple textclips
txt_1 = TextClip("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an", size=vid.size, align='West', fontsize=35, color ='white', method='caption').set_duration(5)
txt_2 = TextClip("Idk", align='West', fontsize=20, color ='white', method='caption').set_duration(5)

txt_1 = txt_1.set_position(('center', 'top'))
txt_2 = txt_2.set_position(('center', 'left'))
a = CompositeVideoClip([vid, txt_1, txt_2])

a.write_videofile('video.mp4', fps=25)

Expected Result:

Expected Result

Actual Result:
Actual Result

ItachiUchiha5277 commented 1 year ago

Please ignore the "66.7%" on the 2nd image

TheHimanshuRastogi commented 1 year ago

In the txt_1 object, you passed a parameter size whose value is vid.size but it should be less than the size of the video for example if the size of the video is (1080, 1920) then the size of TextClip should be (800, 1920). Note: height doesn't matter much if method is set to caption.

Now the text will only be written in 800 pixels as you pass another parameter method=caption, it'll wrap the text within 800 pixels. you can pass size=(800, 1000) or size=(800, vid.size[-1]) or size=(800, None) (to auto adjust height).

Next: to position it you should use pixels, instead of passing ('center', 'top'), you could use ('center', 100). And if you want your text 2 to be placed 100 pixels from text 1 then you can use (for text 2) ('center', txt_1.h+100). Note: to use txt.h+100 the height of the first text should be None so that it'll auto determine height, eg: size=(800, None).

I hope you find it well, Thanks.