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:
CodePudding user response:
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