Upload Moviepy.py
Browse files- Moviepy.py +107 -0
Moviepy.py
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from moviepy.editor import *
|
2 |
+
import json
|
3 |
+
|
4 |
+
def load_json_output(output_query_response):
|
5 |
+
# Convert JSON string to Python dictionary
|
6 |
+
return json.loads(output_query_response)
|
7 |
+
|
8 |
+
def extract_audio_from_video(video_path):
|
9 |
+
video = VideoFileClip(video_path)
|
10 |
+
audio_path = "audio/current_audio.mp3"
|
11 |
+
if video.audio is not None:
|
12 |
+
video.audio.write_audiofile(audio_path)
|
13 |
+
print("Audio file has been extracted from the video")
|
14 |
+
return audio_path
|
15 |
+
else:
|
16 |
+
print("No audio found in the video.")
|
17 |
+
return None
|
18 |
+
|
19 |
+
def get_explosion_segments(json_data):
|
20 |
+
# creating an empty array for the results
|
21 |
+
result = []
|
22 |
+
# iterate over every explosion occurrence and find start, end, best values using the ml algorithm
|
23 |
+
for i in json_data["value"]:
|
24 |
+
result.append([i["start"], i["end"], i["best"]])
|
25 |
+
|
26 |
+
# update start_explosion_time and end_explosion_time for each explosion occurrence
|
27 |
+
for explosion in result:
|
28 |
+
best_time = explosion[2]
|
29 |
+
best_time_seconds = sum(x * int(t) for x, t in zip([3600, 60, 1], best_time.split(":")))
|
30 |
+
start_explosion_time_seconds = best_time_seconds - 2
|
31 |
+
end_explosion_time_seconds = best_time_seconds + 1
|
32 |
+
explosion[0] = "{:02d}:{:02d}:{:02d}".format(start_explosion_time_seconds // 3600,
|
33 |
+
(start_explosion_time_seconds % 3600 // 60),
|
34 |
+
start_explosion_time_seconds % 60)
|
35 |
+
explosion[1] = "{:02d}:{:02d}:{:02d}".format(end_explosion_time_seconds // 3600,
|
36 |
+
(end_explosion_time_seconds % 3600 // 60),
|
37 |
+
end_explosion_time_seconds % 60)
|
38 |
+
return result
|
39 |
+
|
40 |
+
def create_final_audio(current_audio_path, haptic_audio_path, explosion_segments):
|
41 |
+
current_audio = AudioFileClip(current_audio_path) # location of the uploaded video
|
42 |
+
# define the segments for the audio clips
|
43 |
+
final_audio_segments = []
|
44 |
+
#haptic_audio_path = haptic_audio_url
|
45 |
+
haptic_audio = AudioFileClip(haptic_audio_path)
|
46 |
+
|
47 |
+
# Iterate through each explosion occurrence and create audio segments
|
48 |
+
for explosion in explosion_segments:
|
49 |
+
best_explosion_time = explosion[2]
|
50 |
+
best_explosion_time_seconds = sum(x * int(t) for x, t in zip([3600, 60, 1], best_explosion_time.split(":")))
|
51 |
+
|
52 |
+
# Adjust the duration of the haptic audio to match the duration of the explosion
|
53 |
+
haptic_audio_duration = haptic_audio.duration
|
54 |
+
haptic_audio_clip = haptic_audio.subclip(0, haptic_audio_duration)
|
55 |
+
|
56 |
+
# Create an audio clip starting from the best explosion time
|
57 |
+
explosion_audio_clip = current_audio.subclip(best_explosion_time_seconds - 1,
|
58 |
+
best_explosion_time_seconds + haptic_audio_duration)
|
59 |
+
|
60 |
+
# Concatenate the haptic audio clip with the explosion audio clip
|
61 |
+
final_audio = concatenate_audioclips([explosion_audio_clip, haptic_audio_clip])
|
62 |
+
final_audio_segments.append(final_audio)
|
63 |
+
|
64 |
+
# concatenate final audio segments
|
65 |
+
final_audio = concatenate_audioclips(final_audio_segments)
|
66 |
+
# Match the audio duration with the video duration
|
67 |
+
final_audio = final_audio.set_duration(current_audio.duration)
|
68 |
+
return final_audio
|
69 |
+
|
70 |
+
def master_audio(audio_clip):
|
71 |
+
# Apply audio mastering techniques here
|
72 |
+
# Example: loudness normalization, equalization, compression, etc.
|
73 |
+
# Replace the following line with your audio mastering process
|
74 |
+
mastered_audio = audio_clip.fx(afx.audio_normalize)
|
75 |
+
return mastered_audio
|
76 |
+
|
77 |
+
def save_audio(audio_clip, file_path):
|
78 |
+
audio_clip.write_audiofile(file_path)
|
79 |
+
print("Enhanced audio has been created")
|
80 |
+
|
81 |
+
def without_audio(video_clip):
|
82 |
+
return video_clip.without_audio()
|
83 |
+
|
84 |
+
def combine_video_audio(video_clip, audio_clip):
|
85 |
+
return video_clip.set_audio(audio_clip)
|
86 |
+
|
87 |
+
def save_video(video_clip, file_path):
|
88 |
+
video_clip.write_videofile(file_path, fps=60)
|
89 |
+
print("Final video has been created")
|
90 |
+
|
91 |
+
def process_video(current_video_path, output_query_response):
|
92 |
+
json_data = load_json_output(output_query_response)
|
93 |
+
audio_path = extract_audio_from_video(current_video_path)
|
94 |
+
if audio_path:
|
95 |
+
explosion_segments = get_explosion_segments(json_data)
|
96 |
+
final_audio = create_final_audio(audio_path, explosion_segments)
|
97 |
+
final_audio_mastered = master_audio(final_audio)
|
98 |
+
save_audio(final_audio_mastered, "output.mp3")
|
99 |
+
|
100 |
+
current_video = VideoFileClip(current_video_path)# Extracting audio from the video
|
101 |
+
extracted_video = without_audio(current_video)
|
102 |
+
|
103 |
+
final_video = combine_video_audio(extracted_video, final_audio_mastered)
|
104 |
+
save_video(final_video, "final_video.mp4")
|
105 |
+
|
106 |
+
|
107 |
+
|