I want to move an image in multiple steps, where the background is a video. Currently this is my code:
waterClip = ImageClip("watermark.png").set_position(lambda t: (np.exp(10*t - 10*titleTime) * -1, 75)).
Its a watermark that displays at the top left of the video, which quickly slides away to the left in a smooth fashion.
However, I want it to “pop” out towards the right, before sliding all the way to the left. So I think I would need 2 steps, the first one moving the image towards the right, and the second moving it all the way to the left (which the code above does)
How would I do this?
Thanks!
EDIT:
Here is all my code:
import numpy as np from moviepy.editor import * from moviepy.video.fx.all import crop import random finalList = [] cum = 10 first = 4 backName = random.choice(os.listdir("backgroundVid/")) backTemp = VideoFileClip("backgroundVid/" + backName).without_audio() # chooses a random video from a folder, all 59s long and 1280x720 60fps if backTemp.duration >= cum: backTemp = backTemp.subclip(0, cum) elif backTemp.duration < cum: backTemp = backTemp.loop(duration = cum) (w, h) = backTemp.size if (w == 720) & (h == 1280): back = backTemp else: backCropped = crop(backTemp, width= h/(w/h), height=h, x_center=w/2, y_center=h/2) back = backCropped.resize((720,1280)) # resizes video to 720x1280 finalList.append(back) image = ImageClip('watermark.png', duration=10) image = image.set_position(lambda t: (np.exp(10*t - 10*first) * -1, 75)) image.fps = 60 finalList.append(image) videoTemp = CompositeVideoClip(finalList) videoTemp.write_videofile("TEST_FinalVideoTT" + ".mp4")
And here is what it currently looks like:
Advertisement
Answer
I am not sure that I got it exactly as you indented…
The main concept is dividing the movement to two stages:
Moving to the left:
((np.exp(10*(t - first))*(-1)
Moving to the right (
most_left_col = -image.size[0]
):most_left_col - np.exp(10*(t-end_t))*(-1))
The lambda
may be as follows:
image = image.set_position(lambda t: ((np.exp(10*(t - first))*(-1) if t < end_t else most_left_col - np.exp(10*(t-end_t))*(-1)), 100))
end_t
is computed in such way that np.exp(10*(end_t - first))*(-1) = most_left_col
.
The result is that end_t = np.log(-most_left_col)/10 + first
That way when the entire watermark is out of the image, it starts moving to the other direction.
Cone sample:
import numpy as np from moviepy.editor import * #ffmpeg -y -f lavfi -i color=black:size=720x1280:rate=10:duration=10 -vcodec libx264 original_video.mp4 #ffmpeg -y -f lavfi -i testsrc=size=720x1280:rate=1:duration=1 -frames 1 -update 1 watermark.png finalList = [] first = 4 backTemp = VideoFileClip("original_video.mp4").without_audio() (w, h) = backTemp.size back = backTemp # The example assumes that backTemp resolution is 720x1280, and duration is 10 seconds finalList.append(back) image = ImageClip('watermark.png', duration=10) most_left_col = -image.size[0] end_t = np.log(-most_left_col)/10 + first image = image.set_position(lambda t: ((np.exp(10*(t - first))*(-1) if t < end_t else most_left_col - np.exp(10*(t-end_t))*(-1)), 100)) image.fps = 10 # Set to 10 fps for testing finalList.append(image) videoTemp = CompositeVideoClip(finalList) videoTemp.write_videofile("TEST_FinalVideoTT" + ".mp4")
For testing we may create original_video.mp4
and watermark.png
using FFmpeg CLI:
ffmpeg -y -f lavfi -i color=black:size=720x1280:rate=10:duration=10 -vcodec libx264 original_video.mp4
ffmpeg -y -f lavfi -i testsrc=size=720x1280:rate=1:duration=1 -frames 1 -update 1 watermark.png