Я пытаюсь создать видео слайд-шоу с помощью moviepy с переходом между слайдами вверх. Я могу заставить переход работать нормально, если это просто ImageClips, но когда я добавляю текст к изображениям с помощью CompositeVideoClip, он перестает работать. Если у меня есть только один CompositeVideoClip и остальные ImageClip, он работает нормально, но как только у меня есть более одного CompositeVideoClip, он начинает ломаться.
Я не уверен, является ли это ошибкой с 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
Если для слайда_1 установлена продолжительность, а для слайда_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.
если ни один из них не имеет установленной длительности. то же, что 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 имеет продолжительность, а слайд_1 и финальный_клип — нет. то же, что 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)