261 lines
8.7 KiB
Python
261 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
生成通用片尾动画
|
||
支持三种尺寸:16:9、3:4、9:16
|
||
|
||
用法:
|
||
# 16:9 横版(默认)
|
||
manim -qh --format=mp4 --fps=30 -o outro.mp4 outro_generator.py OutroAnimation
|
||
|
||
# 3:4 竖版
|
||
manim -qh --format=mp4 --fps=30 -o outro_3x4.mp4 outro_generator.py OutroAnimation3x4
|
||
|
||
# 9:16 竖版(手机全屏)
|
||
manim -qh --format=mp4 --fps=30 -o outro_9x16.mp4 outro_generator.py OutroAnimation9x16
|
||
|
||
加语音(每种尺寸都要加):
|
||
edge-tts --text "点关注,不迷路!" --voice zh-CN-YunxiNeural --rate="+10%" --write-media outro_voice.mp3
|
||
ffmpeg -y -i outro.mp4 -i outro_voice.mp3 -filter_complex "[1:a]adelay=1000|1000,apad=whole_dur=5.2[aout]" -map 0:v -map "[aout]" -c:v copy -c:a aac outro_with_voice.mp4
|
||
mv outro_with_voice.mp4 outro.mp4
|
||
"""
|
||
from manim import *
|
||
import os
|
||
|
||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
LOGO_PATH = os.path.join(SCRIPT_DIR, "logo.jpg")
|
||
|
||
|
||
class OutroAnimation(Scene):
|
||
"""16:9 横版片尾"""
|
||
def construct(self):
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(1.8)
|
||
qr_code.shift(UP * 0.8)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=48, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.6)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation3x4(Scene):
|
||
"""3:4 竖版片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 1080
|
||
config.pixel_height = 1440
|
||
config.frame_width = 8
|
||
config.frame_height = 10.67
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(2.2)
|
||
qr_code.shift(UP * 1.5)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=42, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.8)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation9x16(Scene):
|
||
"""9:16 竖版片尾(手机全屏)"""
|
||
def construct(self):
|
||
config.pixel_width = 1080
|
||
config.pixel_height = 1920
|
||
config.frame_width = 8
|
||
config.frame_height = 14.22
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(2.5)
|
||
qr_code.shift(UP * 2)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=40, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=1.0)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation1x1(Scene):
|
||
"""1:1 正方形片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 1024
|
||
config.pixel_height = 1024
|
||
config.frame_width = 8
|
||
config.frame_height = 8
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(2.0)
|
||
qr_code.shift(UP * 0.5)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=44, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.6)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation2x3(Scene):
|
||
"""2:3 竖版片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 832
|
||
config.pixel_height = 1248
|
||
config.frame_width = 8
|
||
config.frame_height = 12
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(2.0)
|
||
qr_code.shift(UP * 1.2)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=38, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.8)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation3x2(Scene):
|
||
"""3:2 横版片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 1248
|
||
config.pixel_height = 832
|
||
config.frame_width = 12
|
||
config.frame_height = 8
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(1.6)
|
||
qr_code.shift(UP * 0.6)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=46, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.5)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation4x3(Scene):
|
||
"""4:3 横版片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 1440
|
||
config.pixel_height = 1080
|
||
config.frame_width = 10.67
|
||
config.frame_height = 8
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(1.8)
|
||
qr_code.shift(UP * 0.7)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=46, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.6)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation4x5(Scene):
|
||
"""4:5 竖版片尾(Instagram)"""
|
||
def construct(self):
|
||
config.pixel_width = 864
|
||
config.pixel_height = 1080
|
||
config.frame_width = 8
|
||
config.frame_height = 10
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(2.0)
|
||
qr_code.shift(UP * 1.0)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=36, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.7)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation5x4(Scene):
|
||
"""5:4 横版片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 1080
|
||
config.pixel_height = 864
|
||
config.frame_width = 10
|
||
config.frame_height = 8
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(1.7)
|
||
qr_code.shift(UP * 0.6)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=44, color=WHITE)
|
||
title.next_to(qr_code, DOWN, buff=0.5)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
class OutroAnimation21x9(Scene):
|
||
"""21:9 超宽屏片尾"""
|
||
def construct(self):
|
||
config.pixel_width = 1536
|
||
config.pixel_height = 672
|
||
config.frame_width = 18.29
|
||
config.frame_height = 8
|
||
|
||
self.camera.background_color = "#1a1a2e"
|
||
|
||
qr_code = ImageMobject(LOGO_PATH)
|
||
qr_code.scale(1.3)
|
||
qr_code.shift(LEFT * 4)
|
||
|
||
title = Text("点点关注 一起学 AI", font="PingFang SC", font_size=52, color=WHITE)
|
||
title.shift(RIGHT * 2)
|
||
|
||
self.play(GrowFromCenter(qr_code), run_time=0.8)
|
||
self.play(Write(title), run_time=1.0)
|
||
self.play(qr_code.animate.scale(1.05), rate_func=there_and_back, run_time=0.4)
|
||
self.wait(3)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
print("生成片尾动画...")
|
||
print("\n16:9 横版:")
|
||
print(" manim -qh --format=mp4 --fps=30 -o outro.mp4 outro_generator.py OutroAnimation")
|
||
print("\n3:4 竖版:")
|
||
print(" manim -qh --format=mp4 --fps=30 -o outro_3x4.mp4 outro_generator.py OutroAnimation3x4")
|
||
print("\n9:16 竖版:")
|
||
print(" manim -qh --format=mp4 --fps=30 -o outro_9x16.mp4 outro_generator.py OutroAnimation9x16")
|