-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvideo_assembly.py
More file actions
172 lines (121 loc) · 3.7 KB
/
Copy pathvideo_assembly.py
File metadata and controls
172 lines (121 loc) · 3.7 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import subprocess
import os
def video_assembly():
# PATHS
video_path = r"C:\Users\Nithish\Content_Automisation\videos\Fotnite.mp4"
audio_path = r"C:\Users\Nithish\Content_Automisation\audio\output.wav"
subtitle_path = r"C:\Users\Nithish\Content_Automisation\audio\subtitles.srt"
output_path = r"C:\Users\Nithish\Content_Automisation\output\final_reel.mp4"
# FILE TO STORE VIDEO OFFSET
offset_file = r"C:\Users\Nithish\Content_Automisation\video_offset.txt"
# CHECK FILES
print("\nChecking files...\n")
print("Video Exists:", os.path.exists(video_path))
print("Audio Exists:", os.path.exists(audio_path))
print("Subtitle Exists:", os.path.exists(subtitle_path))
# GET AUDIO DURATION
print("\nGetting audio duration...\n")
probe_command = [
"ffprobe",
"-v", "error",
"-show_entries",
"format=duration",
"-of",
"default=noprint_wrappers=1:nokey=1",
audio_path
]
probe_result = subprocess.run(
probe_command,
capture_output=True,
text=True
)
audio_duration = float(probe_result.stdout.strip())
print(f"Audio Duration: {audio_duration:.2f} seconds")
# LOAD PREVIOUS OFFSET
if os.path.exists(offset_file):
with open(offset_file, "r") as f:
start_time = float(f.read().strip())
else:
start_time = 0
print(f"\nStarting gameplay from: {start_time:.2f} seconds")
# SAVE NEXT OFFSET
next_offset = start_time + audio_duration
with open(offset_file, "w") as f:
f.write(str(next_offset))
print(f"Next reel will start from: {next_offset:.2f} seconds")
# FIX SUBTITLE PATH FOR FFMPEG
subtitle_path_ffmpeg = (
subtitle_path
.replace("\\", "/")
.replace(":", "\\:")
)
# SUBTITLE TOGGLE
USE_SUBTITLES = False
# VIDEO FILTERS
if USE_SUBTITLES:
video_filter = (
f"scale=1080:1920:force_original_aspect_ratio=increase,"
f"crop=1080:1920,"
f"subtitles='{subtitle_path_ffmpeg}':"
f"force_style='"
f"Alignment=10,"
f"Fontsize=32,"
f"Bold=1,"
f"PrimaryColour=&HFFFFFF&,"
f"OutlineColour=&H000000&,"
f"BorderStyle=1,"
f"Outline=4,"
f"Shadow=0,"
f"MarginV=250'"
)
else:
video_filter = (
"scale=1080:1920:force_original_aspect_ratio=increase,"
"crop=1080:1920"
)
# FFMPEG COMMAND
print("\nGenerating final reel...\n")
ffmpeg_command = [
"ffmpeg",
"-y",
# START VIDEO FROM OFFSET
"-ss", str(start_time),
# LOOP VIDEO IF TOO SHORT
"-stream_loop", "-1",
# VIDEO INPUT
"-i", video_path,
# AUDIO INPUT
"-i", audio_path,
# USE VIDEO ONLY FROM GAMEPLAY
"-map", "0:v:0",
# USE AUDIO ONLY FROM GENERATED AUDIO
"-map", "1:a:0",
# MATCH OUTPUT LENGTH TO AUDIO
"-t", str(audio_duration),
# VIDEO FILTERS
"-vf",
video_filter,
# VIDEO ENCODER
"-c:v", "libx264",
# AUDIO ENCODER
"-c:a", "aac",
# AUDIO SETTINGS
"-ar", "44100",
"-ac", "2",
"-b:a", "192k",
# QUALITY
"-preset", "fast",
"-crf", "23",
# TIMESTAMP FIX
"-avoid_negative_ts", "make_zero",
# STOP WHEN AUDIO ENDS
"-shortest",
output_path
]
# RUN FFMPEG
result = subprocess.run(ffmpeg_command)
if result.returncode == 0:
print("\nFinal reel generated successfully!")
print(f"\nSaved at:\n{output_path}")
else:
print("\nFFmpeg failed!")