import cv2 import subprocess from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip, AudioFileClip from moviepy.video.fx import all as vfx import numpy as np from pathlib import Path import tempfile class VideoProcessor: def __init__(self): self.temp_dir = tempfile.mkdtemp() def extract_audio(self, video_path): """Extract audio from video file""" try: video = VideoFileClip(video_path) audio_path = Path(self.temp_dir) / "audio.wav" video.audio.write_audiofile(str(audio_path), logger=None) video.close() return str(audio_path) except Exception as e: raise Exception(f"Audio extraction failed: {str(e)}") def extract_clip(self, video_path, start_time, end_time): """Extract a segment from video""" try: video = VideoFileClip(video_path) clip = video.subclip(start_time, end_time) # Resize to 9:16 for shorts target_width = 1080 target_height = 1920 # Calculate scaling scale = max(target_width / clip.w, target_height / clip.h) new_w = int(clip.w * scale) new_h = int(clip.h * scale) # Resize and crop clip_resized = clip.resize((new_w, new_h)) # Center crop x_center = new_w / 2 y_center = new_h / 2 x1 = int(x_center - target_width / 2) y1 = int(y_center - target_height / 2) clip_cropped = clip_resized.crop( x1=x1, y1=y1, x2=x1 + target_width, y2=y1 + target_height ) output_path = Path(self.temp_dir) / f"clip_{start_time}_{end_time}.mp4" clip_cropped.write_videofile( str(output_path), codec='libx264', audio_codec='aac', logger=None ) video.close() clip.close() clip_resized.close() clip_cropped.close() return str(output_path) except Exception as e: raise Exception(f"Clip extraction failed: {str(e)}") def add_captions(self, video_path, captions_data): """Add animated captions to video""" try: video = VideoFileClip(video_path) clips = [video] for caption in captions_data['captions']: # Create text clip txt_clip = TextClip( caption['text'], fontsize=captions_data['fontsize'], color=captions_data['color'], stroke_color=captions_data['stroke_color'], stroke_width=captions_data['stroke_width'], font='Arial-Bold', method='caption', size=(video.w * 0.9, None) ) # Position and timing txt_clip = txt_clip.set_position(('center', 'center')) txt_clip = txt_clip.set_start(caption['start']) txt_clip = txt_clip.set_duration(caption['duration']) # Add animation if captions_data['animation'] == 'pop': txt_clip = txt_clip.crossfadein(0.2) clips.append(txt_clip) # Compose final video final_video = CompositeVideoClip(clips) output_path = video_path.replace('.mp4', '_captioned.mp4') final_video.write_videofile( output_path, codec='libx264', audio_codec='aac', logger=None ) video.close() final_video.close() return output_path except Exception as e: raise Exception(f"Caption addition failed: {str(e)}") def add_sound_effects(self, video_path, sound_effects): """Add sound effects to video at specific timestamps""" try: # This would integrate with sound effect library # For now, return original video return video_path except Exception as e: raise Exception(f"Sound effect addition failed: {str(e)}")