-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvideo.py
More file actions
77 lines (70 loc) · 2.85 KB
/
video.py
File metadata and controls
77 lines (70 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import ffmpeg
import os
# note for variable naming:
# image = ai generated image
# frame = video frame
# length = duration in seconds
# Define FFmpeg processing
class Video:
def __init__(self, id: int):
self.id = id
self.image_dir = os.path.expanduser(f"images/{id}")
self.output_fps = 30
# main video
def render_main(self):
main_lenght: int = 42-2 # length of the main part of the reel
image_length: float = 2.0 # duration of each image is displayed
zoom_level: float = 1.001
(
ffmpeg.input(os.path.join(self.image_dir, "*.png"), pattern_type="glob", loop=1)
# upscale to fix jitter from zoom
.filter(
"scale",
w="5000",
h="-1", # maintain aspect ratio
)
# zoom per image, zoom variable resets every input image
.filter("zoompan",
z=f"zoom*{zoom_level}",
d=self.output_fps * image_length, # d = duration of each image
x="iw/2-(iw/zoom/2)",
y="ih/2-(ih/zoom/2)",
s="720x1280")
.output(f"images/{self.id}/reel_main.mp4", vcodec="libx264", r=self.output_fps, pix_fmt="yuv420p", t=main_lenght) # H.264 codec
.run(overwrite_output=True)
)
# fast intro
def render_intro(self):
intro_length: float = 1.9
image_length: float = 0.2
zoom_level: float = 1.01
(
ffmpeg.input(os.path.join(self.image_dir, "*.png"), pattern_type="glob", loop=1)
# upscale to fix jitter from zoom
.filter(
"scale",
w="5000",
h="-1", # maintain aspect ratio
)
# zoom per image, zoom variable resets every input image
.filter("zoompan",
z=f"zoom*{zoom_level}",
d=self.output_fps * image_length, # d = duration of each image
x="iw/2-(iw/zoom/2)",
y="ih/2-(ih/zoom/2)",
s="720x1280")
.output(f"images/{self.id}/reel_intro.mp4", vcodec="libx264", r=self.output_fps, pix_fmt="yuv420p", t=intro_length)
.run(overwrite_output=True)
)
def render_total(self):
intro = ffmpeg.input(f"images/{self.id}/reel_intro.mp4")
main = ffmpeg.input(f"images/{self.id}/reel_main.mp4")
video = ffmpeg.concat(intro, main, v=1, a=0)
audio = ffmpeg.input(f"images/{self.id}/audio.wav")
ffmpeg.output(video,
audio.audio,
f"images/{self.id}/reel_total.mp4",
shortest=None, # Stops encoding when the shortest input ends
vcodec="libx264", # Avoid re-encoding video
acodec="aac" # Encode audio to AAC
).run(overwrite_output=True)