try_hf_space / youtube_vedio_edit.py
amit0987's picture
Create app.py
1a33f31
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()