返回 MoneyPrinterTurbo
video_effects.py
根目录 / app / services / utils / video_effects.py
1 from moviepy import Clip, ColorClip, CompositeVideoClip, vfx
2
3
4 # FadeIn
5 def fadein_transition(clip: Clip, t: float) -> Clip:
6 return clip.with_effects([vfx.FadeIn(t)])
7
8
9 # FadeOut
10 def fadeout_transition(clip: Clip, t: float) -> Clip:
11 return clip.with_effects([vfx.FadeOut(t)])
12
13
14 # SlideIn
15 def slidein_transition(clip: Clip, t: float, side: str) -> Clip:
16 width, height = clip.size
17
18 # MoviePy 内置 SlideIn 在当前这条处理链里对全屏素材不稳定,
19 # 会出现“逻辑上应用了转场,但画面几乎看不出变化”的情况。
20 # 这里改成显式黑底 + 位移动画,保证转场效果可见且行为可控。
21 def position(current_time: float):
22 progress = min(max(current_time / max(t, 0.001), 0), 1)
23
24 if side == "left":
25 return (-width + width * progress, 0)
26 if side == "right":
27 return (width - width * progress, 0)
28 if side == "top":
29 return (0, -height + height * progress)
30 if side == "bottom":
31 return (0, height - height * progress)
32 return (0, 0)
33
34 background = ColorClip(size=(width, height), color=(0, 0, 0)).with_duration(
35 clip.duration
36 )
37 moving_clip = clip.with_position(position)
38 return CompositeVideoClip([background, moving_clip], size=(width, height)).with_duration(
39 clip.duration
40 )
41
42
43 # SlideOut
44 def slideout_transition(clip: Clip, t: float, side: str) -> Clip:
45 width, height = clip.size
46 transition_start = max(clip.duration - t, 0)
47
48 # SlideOut 同样改成显式位移,保证片段末尾能稳定滑出画面。
49 def position(current_time: float):
50 if current_time <= transition_start:
51 return (0, 0)
52
53 progress = min(
54 max((current_time - transition_start) / max(t, 0.001), 0), 1
55 )
56
57 if side == "left":
58 return (-width * progress, 0)
59 if side == "right":
60 return (width * progress, 0)
61 if side == "top":
62 return (0, -height * progress)
63 if side == "bottom":
64 return (0, height * progress)
65 return (0, 0)
66
67 background = ColorClip(size=(width, height), color=(0, 0, 0)).with_duration(
68 clip.duration
69 )
70 moving_clip = clip.with_position(position)
71 return CompositeVideoClip([background, moving_clip], size=(width, height)).with_duration(
72 clip.duration
73 )
74
74 lines PYTHON