多个 CompositeVideoClips 的 Moviepy Transition 问题
Moviepy Transition issues with multiple CompositeVideoClips
我正在尝试使用 moviepy 创建视频幻灯片,并在幻灯片之间进行向上滑动。如果它们只是 ImageClip,我可以让过渡正常工作,但是当我使用 CompositeVideoClip 向图像添加文本时,它停止工作。如果我只有一个 CompositeVideoClip 和其余的 ImageClips,它工作正常,但是一旦我有多个 CompositeVideoClips,它就会开始崩溃。
我不确定这是 moviepy 的错误,还是我设置它的方式。
这是我的代码:
from moviepy.editor import *
H = 720
W = 1280
SIZE = (W, H)
HX = H + H * .10 # increase size 10%
WX = W + W * .10
bold_font = 'Liberation-Sans-Bold'
plain_font = 'Liberation-Sans'
def slide_out(clip, duration, height, counter):
def calc(t, counter, duration, h):
ts = t - (counter * duration)
val = min(-45, h*(duration-ts))
return ('center', val)
return clip.set_pos(lambda t: calc(t, counter, duration, height))
def add_transition(clip_size, counter, clip):
# reverse the count to get slide number.
counter = clip_size - 1 - counter
return slide_out(clip.resize(height=HX, width=WX), 3, HX, counter)
img_1 = ImageClip("/pics/1.jpg").set_duration(4).set_start(0).resize(height=H, width=W) # 3-8
txt_1 = TextClip("title 1", font=bold_font, color='white', fontsize=64, interline=9).set_duration(2).set_start(1).set_pos(('right', 360)).crossfadein(.3)
stxt_1 = TextClip("sub title 1", font=plain_font, color='white', fontsize=80, interline=9).set_duration(1.5).set_start(1.5).set_pos(('right', 440)).crossfadein(.3)
img_2 = ImageClip("/pics/2.jpg").set_duration(4).set_start(3).resize(height=H, width=W) # 3-8
txt_2 = TextClip("title 2", font=bold_font, color='white', fontsize=64, interline=9).set_duration(3).set_start(3.5).set_pos(('right', 360)).crossfadein(.3)
stxt_2 = TextClip("sub title 2", font=plain_font, color='white', fontsize=80, interline=9).set_duration(2.5).set_start(3.5).set_pos(('right', 440)).crossfadein(.3)
# slides images with text on top.
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]) #.set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]) #.set_duration(4)
clips = [slide_2, slide_1] # reverse because we want the first slides on top.
slides = [add_transition(len(clips), x, clip) for x, clip in enumerate(clips)]
final_clip = CompositeVideoClip(slides, size=SIZE).set_duration(8)
final_clip.write_videofile("/pics/vids/video.mp4", fps=24, audio_codec="aac")
我尝试了几种不同的方法,看看我是否能弄清楚发生了什么。如果你能提供任何帮助,那就太好了。
选项 1
If if slide_1 设置了持续时间,而 slide_2 和 final_clip 没有设置持续时间。完成的视频的持续时间为 4,总持续时间为 4。它将显示完整的第一张幻灯片,并且仅显示第二张幻灯片的第一秒。
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]).set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2])
final_clip = CompositeVideoClip(slides, size=SIZE)
结果
选项 2
如果slide_1和slide_2不设置持续时间,但final_clip确实有持续时间8。它是8秒长但第二张图片只显示1秒(在 t=3 到 t=4),然后消失并留下文本。
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1])
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2])
final_clip = CompositeVideoClip(slides, size=SIZE).set_duration(8)
结果
选项 3.
如果所有三个都设置了持续时间。 slide_1 工作正常,但幻灯片 2 只显示 1 秒,然后在其余时间变黑。
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]).set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]).set_duration(4)
final_clip = CompositeVideoClip(slides, size=SIZE).set_duration(8)
结果
选项 4.
如果其中 none 个设置了持续时间。与 2.
相同
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1])
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2])
final_clip = CompositeVideoClip(slides, size=SIZE)
结果
选项 5.
如果幻灯片 2 有持续时间,但 slide_1 和 final_clip 没有。与 1.
相同
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1])
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]).set_duration(4)
final_clip = CompositeVideoClip(slides, size=SIZE)
结果
请测试下面的代码,然后你会发现CompositeVideoClip
背后的机制
from moviepy.editor import *
H = 720
W = 1280
SIZE = (W, H)
HX = H + H * .10 # increase size 10%
WX = W + W * .10
bold_font = 'Liberation-Sans-Bold'
plain_font = 'Liberation-Sans'
img_1 = ImageClip("bbb.jpeg").set_duration(4).set_start(0).resize(height=H, width=W) # 3-8
txt_1 = TextClip("title 1", font=bold_font, color='white', fontsize=64, interline=9).set_duration(2).set_start(1).set_pos(('right', 360)).crossfadein(.3)
stxt_1 = TextClip("sub title 1", font=plain_font, color='white', fontsize=80, interline=9).set_duration(1.5).set_start(1.5).set_pos(('right', 440)).crossfadein(.3)
img_2 = ImageClip("aaa.jpg").set_duration(8).set_start(4).resize(height=H, width=W) # 3-8
# look the img_2's set_duration and set_start,the same as txt_2 and stxt_2
txt_2 = TextClip("title 2", font=bold_font, color='white', fontsize=64, interline=9).set_duration(7).set_start(4.5).set_pos(('right', 360)).crossfadein(.3)
stxt_2 = TextClip("sub title 2", font=plain_font, color='white', fontsize=80, interline=9).set_duration(6).set_start(5.5).set_pos(('right', 440)).crossfadein(.3)
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]).set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]).set_duration(8)
clips = [slide_2, slide_1]
final_clip = CompositeVideoClip(clips, size=SIZE).set_duration(8)
final_clip.write_videofile("video.mp4", fps=12, audio_codec="aac")
所有奇怪的行为都是由videopy.video.compositeVideoClip.py
中的代码引起的
# compute duration
ends = [c.end for c in self.clips]
if not any([(e is None) for e in ends]):
self.duration = max(ends)
self.end = max(ends)
我正在尝试使用 moviepy 创建视频幻灯片,并在幻灯片之间进行向上滑动。如果它们只是 ImageClip,我可以让过渡正常工作,但是当我使用 CompositeVideoClip 向图像添加文本时,它停止工作。如果我只有一个 CompositeVideoClip 和其余的 ImageClips,它工作正常,但是一旦我有多个 CompositeVideoClips,它就会开始崩溃。
我不确定这是 moviepy 的错误,还是我设置它的方式。
这是我的代码:
from moviepy.editor import *
H = 720
W = 1280
SIZE = (W, H)
HX = H + H * .10 # increase size 10%
WX = W + W * .10
bold_font = 'Liberation-Sans-Bold'
plain_font = 'Liberation-Sans'
def slide_out(clip, duration, height, counter):
def calc(t, counter, duration, h):
ts = t - (counter * duration)
val = min(-45, h*(duration-ts))
return ('center', val)
return clip.set_pos(lambda t: calc(t, counter, duration, height))
def add_transition(clip_size, counter, clip):
# reverse the count to get slide number.
counter = clip_size - 1 - counter
return slide_out(clip.resize(height=HX, width=WX), 3, HX, counter)
img_1 = ImageClip("/pics/1.jpg").set_duration(4).set_start(0).resize(height=H, width=W) # 3-8
txt_1 = TextClip("title 1", font=bold_font, color='white', fontsize=64, interline=9).set_duration(2).set_start(1).set_pos(('right', 360)).crossfadein(.3)
stxt_1 = TextClip("sub title 1", font=plain_font, color='white', fontsize=80, interline=9).set_duration(1.5).set_start(1.5).set_pos(('right', 440)).crossfadein(.3)
img_2 = ImageClip("/pics/2.jpg").set_duration(4).set_start(3).resize(height=H, width=W) # 3-8
txt_2 = TextClip("title 2", font=bold_font, color='white', fontsize=64, interline=9).set_duration(3).set_start(3.5).set_pos(('right', 360)).crossfadein(.3)
stxt_2 = TextClip("sub title 2", font=plain_font, color='white', fontsize=80, interline=9).set_duration(2.5).set_start(3.5).set_pos(('right', 440)).crossfadein(.3)
# slides images with text on top.
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]) #.set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]) #.set_duration(4)
clips = [slide_2, slide_1] # reverse because we want the first slides on top.
slides = [add_transition(len(clips), x, clip) for x, clip in enumerate(clips)]
final_clip = CompositeVideoClip(slides, size=SIZE).set_duration(8)
final_clip.write_videofile("/pics/vids/video.mp4", fps=24, audio_codec="aac")
我尝试了几种不同的方法,看看我是否能弄清楚发生了什么。如果你能提供任何帮助,那就太好了。
选项 1
If if slide_1 设置了持续时间,而 slide_2 和 final_clip 没有设置持续时间。完成的视频的持续时间为 4,总持续时间为 4。它将显示完整的第一张幻灯片,并且仅显示第二张幻灯片的第一秒。
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]).set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2])
final_clip = CompositeVideoClip(slides, size=SIZE)
结果
选项 2
如果slide_1和slide_2不设置持续时间,但final_clip确实有持续时间8。它是8秒长但第二张图片只显示1秒(在 t=3 到 t=4),然后消失并留下文本。
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1])
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2])
final_clip = CompositeVideoClip(slides, size=SIZE).set_duration(8)
结果
选项 3.
如果所有三个都设置了持续时间。 slide_1 工作正常,但幻灯片 2 只显示 1 秒,然后在其余时间变黑。
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]).set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]).set_duration(4)
final_clip = CompositeVideoClip(slides, size=SIZE).set_duration(8)
结果
选项 4.
如果其中 none 个设置了持续时间。与 2.
相同
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1])
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2])
final_clip = CompositeVideoClip(slides, size=SIZE)
结果
选项 5.
如果幻灯片 2 有持续时间,但 slide_1 和 final_clip 没有。与 1.
相同
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1])
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]).set_duration(4)
final_clip = CompositeVideoClip(slides, size=SIZE)
结果
请测试下面的代码,然后你会发现CompositeVideoClip
from moviepy.editor import *
H = 720
W = 1280
SIZE = (W, H)
HX = H + H * .10 # increase size 10%
WX = W + W * .10
bold_font = 'Liberation-Sans-Bold'
plain_font = 'Liberation-Sans'
img_1 = ImageClip("bbb.jpeg").set_duration(4).set_start(0).resize(height=H, width=W) # 3-8
txt_1 = TextClip("title 1", font=bold_font, color='white', fontsize=64, interline=9).set_duration(2).set_start(1).set_pos(('right', 360)).crossfadein(.3)
stxt_1 = TextClip("sub title 1", font=plain_font, color='white', fontsize=80, interline=9).set_duration(1.5).set_start(1.5).set_pos(('right', 440)).crossfadein(.3)
img_2 = ImageClip("aaa.jpg").set_duration(8).set_start(4).resize(height=H, width=W) # 3-8
# look the img_2's set_duration and set_start,the same as txt_2 and stxt_2
txt_2 = TextClip("title 2", font=bold_font, color='white', fontsize=64, interline=9).set_duration(7).set_start(4.5).set_pos(('right', 360)).crossfadein(.3)
stxt_2 = TextClip("sub title 2", font=plain_font, color='white', fontsize=80, interline=9).set_duration(6).set_start(5.5).set_pos(('right', 440)).crossfadein(.3)
slide_1 = CompositeVideoClip([img_1, txt_1, stxt_1]).set_duration(4)
slide_2 = CompositeVideoClip([img_2, txt_2, stxt_2]).set_duration(8)
clips = [slide_2, slide_1]
final_clip = CompositeVideoClip(clips, size=SIZE).set_duration(8)
final_clip.write_videofile("video.mp4", fps=12, audio_codec="aac")
所有奇怪的行为都是由videopy.video.compositeVideoClip.py
# compute duration
ends = [c.end for c in self.clips]
if not any([(e is None) for e in ends]):
self.duration = max(ends)
self.end = max(ends)