Spaces:
Running
Running
import os | |
from moviepy.editor import (VideoFileClip, ImageClip, CompositeVideoClip, AudioFileClip, concatenate_videoclips) | |
import ImportantVariables | |
from ImportantVariables import PATHS, check_paths_exist | |
from moviepy.editor import ColorClip | |
# Add background image behind the video | |
def add_bg_image_on_video(video_clip, image_clip, target_width=1920, target_height=1080): | |
print("add_bg_image_on_video") | |
final_clip = CompositeVideoClip([image_clip, video_clip.set_position(("center", "center"))]) | |
return final_clip | |
def find_width_of_x(width,height): | |
x=int((width-height*(9/16))/2) | |
return x | |
# Add an image (logo/banner/subscribe button) on top of a video | |
def add_image_to_video(shorts_video_clip, image_clip, width_of_image, height_of_image=0, position=(0, 0)): | |
print("add_image_to_video") | |
if height_of_image == 0: | |
image_clip = image_clip.resize(width=width_of_image) | |
else: | |
image_clip = image_clip.resize(width=width_of_image, height=height_of_image) | |
final_clip = CompositeVideoClip([shorts_video_clip, image_clip.set_position(position)]) | |
return final_clip | |
# Add logo to the video | |
def add_logo_to_video(final_shorts_video_clip, logo_image_clip, bg_image_clip_width, shorts_video_clip_width): | |
print("add_logo_to_video") | |
width_of_image = (bg_image_clip_width - shorts_video_clip_width) / 2 | |
height_of_image = 0 | |
x = 0 | |
y = "center" | |
position = (x, y) | |
if width_of_image >= (final_shorts_video_clip.h // 4): | |
final_clip = add_image_to_video(final_shorts_video_clip, logo_image_clip, width_of_image, height_of_image, | |
position) | |
return final_clip | |
else: | |
return final_shorts_video_clip | |
# Add banner to the video | |
def add_banner_to_video(final_shorts_video_clip, banner_image_clip): | |
print("add_banner_to_video") | |
w,h =final_shorts_video_clip.size | |
print(w,h) | |
width_of_image=find_width_of_x(w,h) | |
print("width_of_image",width_of_image) | |
height_of_image = 0 | |
x = "right" | |
y = "top" | |
position = (x, y) | |
final_clip = add_image_to_video(final_shorts_video_clip, banner_image_clip, width_of_image, height_of_image, | |
position) | |
return final_clip | |
# Add subscribe button to the video | |
def add_subscribe_png(final_shorts_video_clip, subscribe_image_clip, bg_image_clip_width, shorts_video_clip_width): | |
print("add_subscribe_png") | |
width_of_image = (bg_image_clip_width - shorts_video_clip_width) / 2 | |
height_of_image = 0 | |
x = "right" | |
y = "center" | |
position = (x, y) | |
if width_of_image >= (final_shorts_video_clip.h // 4): | |
final_clip = add_image_to_video(final_shorts_video_clip, subscribe_image_clip, width_of_image, height_of_image, | |
position) | |
return final_clip | |
else: | |
return final_shorts_video_clip | |
def add_like_share_subscribe_animation(final_shorts_video_clip, animation_clip_path): | |
try: | |
print("add_like_share_subscribe_animation") | |
# Load the animation clip | |
animation_clip = VideoFileClip(animation_clip_path) | |
# Repeat the animation clip every 10 seconds | |
main_video_duration = final_shorts_video_clip.duration | |
repeated_clips = [] | |
start_time = 0 | |
while start_time < main_video_duration: | |
clip = animation_clip.set_start(start_time).set_duration( | |
min(animation_clip.duration, main_video_duration - start_time)) | |
repeated_clips.append(clip) | |
start_time += 10 # Add animation every 10 seconds | |
# Combine all repeated animations | |
animation_sequence = concatenate_videoclips(repeated_clips) | |
w,h=final_shorts_video_clip.size | |
# Resize the animation clip if necessary | |
animation_sequence = animation_sequence.resize(height=h/5.1) # Example: Resize to a height of 100px | |
position = ("center", "bottom") # Position: Centered horizontally, bottom vertically | |
# Overlay the animation onto the main video | |
final_clip = CompositeVideoClip([final_shorts_video_clip, animation_sequence.set_position(position)]) | |
return final_clip | |
except Exception as e: | |
print(f"Error adding animation: {e}") | |
return final_shorts_video_clip | |
# Main function to process a single video | |
def add_main_features(shorts_video_path): | |
global shorts_video_clip | |
dimensions = get_video_dimensions(shorts_video_path) | |
if dimensions: | |
width, height = dimensions | |
if is_16_9(width, height): | |
print(f"β Video is 16:9. Cropping to 9:16...") | |
shorts_video_clip = crop_to_9_16(shorts_video_path) | |
else: | |
print(f"β Video is not 16:9, no cropping needed.") | |
shorts_video_clip = VideoFileClip(shorts_video_path) | |
print(f"β Video Clip Loaded: {shorts_video_clip}") | |
max_duration = 0.5 | |
# clip_duration = min(max_duration, shorts_video_clip.duration) | |
# shorts_video_clip = shorts_video_clip.subclip(0, clip_duration) | |
bg_image_clip = ImageClip(PATHS["background"]).set_duration(shorts_video_clip.duration) | |
banner_image_clip = ImageClip(PATHS["banner"]).set_duration(shorts_video_clip.duration) | |
logo_image_clip = ImageClip(PATHS["logo"]).set_duration(shorts_video_clip.duration) | |
subscribe_png_clip = ImageClip(PATHS["subscribe"]).set_duration(shorts_video_clip.duration) | |
print("subscribe_png_clip",subscribe_png_clip) | |
print("π bg_image_clip before resize:", bg_image_clip) | |
print(f"π Background image size: {bg_image_clip.size}") | |
bg_image_clip = ColorClip(size=(1280, 720), color=(255, 0, 0)) # Red background | |
bg_image_clip = bg_image_clip.set_duration(shorts_video_clip.duration) | |
print("β Test background created") | |
print("β bg_image_clip resized successfully!") # If this doesn't print, script is freezing here | |
print("π bg_image_clip after resize:", bg_image_clip) | |
bg_image_clip_width = bg_image_clip.w | |
shorts_video_clip_width = shorts_video_clip.w | |
print("shorts_video_clip_width",shorts_video_clip_width) | |
# Add background image | |
final_shorts_video_clip = add_bg_image_on_video(shorts_video_clip, bg_image_clip) | |
# Add logo | |
final_shorts_video_clip = add_logo_to_video(final_shorts_video_clip, logo_image_clip, bg_image_clip_width,shorts_video_clip_width) | |
# Add banner | |
final_shorts_video_clip = add_banner_to_video(final_shorts_video_clip, banner_image_clip) | |
# Add subscribe png | |
final_shorts_video_clip = add_subscribe_png(final_shorts_video_clip, subscribe_png_clip, bg_image_clip_width,shorts_video_clip_width) | |
return final_shorts_video_clip | |
# Concatenate multiple videos | |
def concatenate_videos(video_directory): | |
video_clips = [] | |
target_width = 1920 | |
target_height = 1080 | |
for filename in os.listdir(video_directory): | |
if filename.endswith(('.mp4', '.avi', '.mov')): | |
video_path = os.path.join(video_directory, filename) | |
print(f"Processing: {video_path}") | |
try: | |
video_clip = add_main_features(video_path) | |
if video_clip and video_clip.duration > 0: | |
video_clip = video_clip.without_audio() | |
video_clip = video_clip.resize(width=target_width, height=target_height) | |
video_clip = video_clip.set_fps(30) | |
video_clips.append(video_clip) | |
else: | |
print(f"Skipping invalid clip: {video_path}") | |
except Exception as e: | |
print(f"Error processing {video_path}: {e}") | |
if video_clips: | |
print(f"Concatenating {len(video_clips)} video clips...") | |
final_clip = concatenate_videoclips(video_clips, method="compose") | |
return final_clip | |
else: | |
print("No valid video files found in the directory.") | |
return None | |
# Add audio to concatenated video | |
def concatenate_videos_with_audio(video_directory, audio_file): | |
audio_clip = AudioFileClip(audio_file) | |
video_clip = concatenate_videos(video_directory) | |
animation_clip_path = PATHS["animation"] | |
video_clip = add_like_share_subscribe_animation(video_clip, animation_clip_path) | |
if video_clip is None: | |
raise ValueError("No valid video clips to concatenate.") | |
if audio_clip.duration < video_clip.duration: | |
audio_clip = audio_clip.set_duration(video_clip.duration) | |
elif video_clip.duration < audio_clip.duration: | |
audio_clip = audio_clip.set_duration(video_clip.duration) | |
# video_clip = video_clip.set_audio(audio_clip) | |
return video_clip | |
# Main function | |
def main(): | |
video_directory = PATHS["input_videos"] | |
audio_file = PATHS["audio"] | |
final_clip = concatenate_videos_with_audio(video_directory, audio_file) | |
final_clip.write_videofile(PATHS["output_video"], codec="libx264", audio_codec="aac") | |
print("Video created successfully!") | |
def main_for_one_vedio(input_video_path,output_vedio_path): | |
missing_paths = check_paths_exist(PATHS) | |
print(missing_paths) | |
animation_clip_path = PATHS["animation"] | |
print(animation_clip_path) | |
final_clip = add_main_features(input_video_path) | |
print("hello") | |
# final_clip = add_like_share_subscribe_animation(final_clip, animation_clip_path) | |
final_clip.write_videofile(output_vedio_path, codec="libx264", audio_codec="aac") | |
print("Video created successfully!") | |
def get_video_dimensions(video_path): | |
clip = VideoFileClip(video_path) | |
width, height = clip.size # Get (width, height) | |
clip.close() | |
print(width, height) | |
return width, height | |
def is_16_9(width, height): | |
aspect_ratio = width / height | |
print(aspect_ratio) | |
return abs(aspect_ratio - (16 / 9)) < 0.01 | |
def crop_to_9_16(video_path): | |
clip = VideoFileClip(video_path) | |
width, height = clip.size | |
new_width = int(height * 9 / 16) # Calculate new width for 9:16 | |
crop_x = (width - new_width) // 2 # Crop equally from left & right | |
cropped_clip = clip.crop(x1=crop_x, x2=crop_x + new_width) | |
return cropped_clip | |
def main_for_many_vedios(input_folder_path,output_folder_path): | |
print("hello") | |
for filename in os.listdir(input_folder_path): | |
if filename.endswith(".mp4"): | |
input_video_path = os.path.join(input_folder_path, filename) | |
name, _ = os.path.splitext(filename) | |
output_video_path = os.path.join(output_folder_path, f"{filename}_process.mp4") | |
main_for_one_vedio(input_video_path, output_video_path) | |
print(f"Processed {filename}") | |
def main_for_me(): | |
input_video_folder_path = PATHS["input_folder_path"] | |
output_video_folder_path=ImportantVariables.create_output_videos_folder() | |
main_for_many_vedios(input_video_folder_path,output_video_folder_path) | |
if __name__ == "__main__": | |
main_for_me() | |