Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -857,10 +857,11 @@ from moviepy.audio.AudioClip import CompositeAudioClip # For combining audio tr
|
|
857 |
|
858 |
# --- Functions ---
|
859 |
|
860 |
-
def merge_videos(video_files, logo_path1, logo_path2, music_path, output_path):
|
861 |
"""
|
862 |
Merge video clips, overlay two logos, and combine with background music.
|
863 |
The original video audio is preserved and mixed with the background music.
|
|
|
864 |
The merged video is written with the composite audio.
|
865 |
"""
|
866 |
# Load video clips (each with its own audio)
|
@@ -868,14 +869,14 @@ def merge_videos(video_files, logo_path1, logo_path2, music_path, output_path):
|
|
868 |
# Concatenate clips (preserving original audio)
|
869 |
final_clip = concatenate_videoclips(clips)
|
870 |
# Optional: Resize to a fixed resolution if needed
|
871 |
-
# final_clip = final_clip.
|
872 |
|
873 |
# Determine final duration
|
874 |
final_duration = final_clip.duration or sum(clip.duration for clip in clips)
|
875 |
|
876 |
# Calculate positions based on frame dimensions
|
877 |
final_width = final_clip.w # current width of the video
|
878 |
-
# Adjust positions: left logo inset a bit, right logo inset from right edge (logo width=70)
|
879 |
left_pos = (int(final_width * 0.02), 20)
|
880 |
right_pos = (int(final_width * 0.98) - 70, 20)
|
881 |
|
@@ -889,17 +890,18 @@ def merge_videos(video_files, logo_path1, logo_path2, music_path, output_path):
|
|
889 |
.with_position(right_pos)
|
890 |
.with_duration(final_duration))
|
891 |
|
892 |
-
# Load background music, adjust volume, and match duration
|
893 |
-
music = AudioFileClip(music_path).with_volume_scaled(
|
894 |
|
895 |
-
#
|
896 |
-
|
897 |
-
|
|
|
898 |
composite_audio = CompositeAudioClip([original_audio, music])
|
899 |
-
composite_clip =
|
900 |
|
901 |
# Write the merged video with composite audio
|
902 |
-
composite_clip.write_videofile(output_path, codec="libx264", fps=30)
|
903 |
|
904 |
# Close resources
|
905 |
composite_clip.close()
|
@@ -932,11 +934,11 @@ def add_captions_to_video(video_path, captions, output_path):
|
|
932 |
|
933 |
# Font parameters
|
934 |
font = cv2.FONT_HERSHEY_SIMPLEX
|
935 |
-
font_scale = 0.
|
936 |
thickness = 1
|
937 |
text_color = (0, 0, 0) # Black text
|
938 |
box_color = (0, 255, 255) # Yellow box (BGR)
|
939 |
-
margin =
|
940 |
|
941 |
frame_count = 0
|
942 |
while True:
|
@@ -997,6 +999,10 @@ logo_file1 = st.file_uploader("Upload Logo Image 1 (Top Left)", type=["png", "jp
|
|
997 |
logo_file2 = st.file_uploader("Upload Logo Image 2 (Top Right)", type=["png", "jpg", "jpeg"])
|
998 |
music_file = st.file_uploader("Upload Music File", type=["mp3", "wav"])
|
999 |
|
|
|
|
|
|
|
|
|
1000 |
# Create a persistent temporary directory in session state
|
1001 |
if 'temp_dir' not in st.session_state:
|
1002 |
st.session_state.temp_dir = tempfile.mkdtemp()
|
@@ -1009,7 +1015,7 @@ if 'intermediate_path' in st.session_state:
|
|
1009 |
# Step 1: Merge Videos Button
|
1010 |
if st.button("Merge Videos"):
|
1011 |
if video_files and logo_file1 and logo_file2 and music_file:
|
1012 |
-
# Save uploaded files into session_state.temp_dir
|
1013 |
video_paths = []
|
1014 |
for video in video_files:
|
1015 |
path = os.path.join(st.session_state.temp_dir, video.name)
|
@@ -1031,7 +1037,8 @@ if st.button("Merge Videos"):
|
|
1031 |
|
1032 |
# Define the intermediate output file path
|
1033 |
intermediate_path = os.path.join(st.session_state.temp_dir, "intermediate_output.mp4")
|
1034 |
-
merge_videos(video_paths, logo_path1, logo_path2, music_path, intermediate_path
|
|
|
1035 |
|
1036 |
# Determine total length of the merged video
|
1037 |
clip = VideoFileClip(intermediate_path)
|
|
|
857 |
|
858 |
# --- Functions ---
|
859 |
|
860 |
+
def merge_videos(video_files, logo_path1, logo_path2, music_path, output_path, orig_vol=1.0, music_vol=0.5):
|
861 |
"""
|
862 |
Merge video clips, overlay two logos, and combine with background music.
|
863 |
The original video audio is preserved and mixed with the background music.
|
864 |
+
The user can control the volumes of the original audio and background music.
|
865 |
The merged video is written with the composite audio.
|
866 |
"""
|
867 |
# Load video clips (each with its own audio)
|
|
|
869 |
# Concatenate clips (preserving original audio)
|
870 |
final_clip = concatenate_videoclips(clips)
|
871 |
# Optional: Resize to a fixed resolution if needed
|
872 |
+
# final_clip = final_clip.resize(newsize=(1080, 720))
|
873 |
|
874 |
# Determine final duration
|
875 |
final_duration = final_clip.duration or sum(clip.duration for clip in clips)
|
876 |
|
877 |
# Calculate positions based on frame dimensions
|
878 |
final_width = final_clip.w # current width of the video
|
879 |
+
# Adjust positions: left logo inset a bit, right logo inset from right edge (logo width=70 assumed)
|
880 |
left_pos = (int(final_width * 0.02), 20)
|
881 |
right_pos = (int(final_width * 0.98) - 70, 20)
|
882 |
|
|
|
890 |
.with_position(right_pos)
|
891 |
.with_duration(final_duration))
|
892 |
|
893 |
+
# Load background music, adjust volume using slider value, and match duration
|
894 |
+
music = AudioFileClip(music_path).with_volume_scaled(music_vol).with_duration(final_duration)
|
895 |
|
896 |
+
# Adjust original video audio using slider value
|
897 |
+
original_audio = final_clip.audio.with_volume_scaled(orig_vol)
|
898 |
+
|
899 |
+
# Composite the video with logos and audio tracks
|
900 |
composite_audio = CompositeAudioClip([original_audio, music])
|
901 |
+
composite_clip = CompositeVideoClip([final_clip, logo1, logo2]).with_audio(composite_audio)
|
902 |
|
903 |
# Write the merged video with composite audio
|
904 |
+
composite_clip.write_videofile(output_path, codec="libx264", fps=30, audio_codec="aac")
|
905 |
|
906 |
# Close resources
|
907 |
composite_clip.close()
|
|
|
934 |
|
935 |
# Font parameters
|
936 |
font = cv2.FONT_HERSHEY_SIMPLEX
|
937 |
+
font_scale = 0.5
|
938 |
thickness = 1
|
939 |
text_color = (0, 0, 0) # Black text
|
940 |
box_color = (0, 255, 255) # Yellow box (BGR)
|
941 |
+
margin = 3 # Margin around text for background box
|
942 |
|
943 |
frame_count = 0
|
944 |
while True:
|
|
|
999 |
logo_file2 = st.file_uploader("Upload Logo Image 2 (Top Right)", type=["png", "jpg", "jpeg"])
|
1000 |
music_file = st.file_uploader("Upload Music File", type=["mp3", "wav"])
|
1001 |
|
1002 |
+
# Sliders for controlling audio volumes
|
1003 |
+
original_audio_vol = st.slider("Original Video Audio Volume", min_value=0.0, max_value=1.0, value=1.0, step=0.05)
|
1004 |
+
music_audio_vol = st.slider("Background Music Volume", min_value=0.0, max_value=1.0, value=0.5, step=0.05)
|
1005 |
+
|
1006 |
# Create a persistent temporary directory in session state
|
1007 |
if 'temp_dir' not in st.session_state:
|
1008 |
st.session_state.temp_dir = tempfile.mkdtemp()
|
|
|
1015 |
# Step 1: Merge Videos Button
|
1016 |
if st.button("Merge Videos"):
|
1017 |
if video_files and logo_file1 and logo_file2 and music_file:
|
1018 |
+
# Save uploaded files into st.session_state.temp_dir
|
1019 |
video_paths = []
|
1020 |
for video in video_files:
|
1021 |
path = os.path.join(st.session_state.temp_dir, video.name)
|
|
|
1037 |
|
1038 |
# Define the intermediate output file path
|
1039 |
intermediate_path = os.path.join(st.session_state.temp_dir, "intermediate_output.mp4")
|
1040 |
+
merge_videos(video_paths, logo_path1, logo_path2, music_path, intermediate_path,
|
1041 |
+
orig_vol=original_audio_vol, music_vol=music_audio_vol)
|
1042 |
|
1043 |
# Determine total length of the merged video
|
1044 |
clip = VideoFileClip(intermediate_path)
|