import cv2 import numpy as np import pandas as pd import tempfile import os import ffmpeg from typing import Dict, Any, Optional, Tuple import time def extract_video_info(video_path: str) -> Dict[str, Any]: """Extract video information using OpenCV.""" cap = cv2.VideoCapture(video_path) if not cap.isOpened(): raise ValueError("Could not open video file") # Get video properties width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = cap.get(cv2.CAP_PROP_FPS) frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) duration = frame_count / fps cap.release() return { 'width': width, 'height': height, 'fps': fps, 'frame_count': frame_count, 'duration': duration } def create_timeline_figure(video_info: Dict[str, Any]) -> go.Figure: """Create a timeline visualization for the video.""" # Create timeline data time_points = np.linspace(0, video_info['duration'], 100) intensity = np.sin(time_points * 2) * 0.5 + 0.5 # Simulated intensity fig = go.Figure() fig.add_trace(go.Scatter( x=time_points, y=intensity, mode='lines', fill='tozeroy', name='Video Intensity' )) fig.update_layout( title="Video Timeline", xaxis_title="Time (seconds)", yaxis_title="Intensity", hovermode='x unified' ) return fig def apply_editing_effects( video_path: str, start_time: float, end_time: float, effects: List[str], filter_type: str, speed: float ) -> str: """Apply editing effects to the video using ffmpeg.""" # Create temporary output file output_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4').name # Build ffmpeg command cmd = [ 'ffmpeg', '-i', video_path, '-ss', str(start_time), '-to', str(end_time), '-vf', f"setpts={1/speed}*PTS" ] # Add effects if effects: effect_filters = [] if 'Fade In' in effects: effect_filters.append('fade=in:st=0:d=1') if 'Fade Out' in effects: effect_filters.append('fade=out:st={}:d=1'.format(end_time - 1)) if 'Blur' in effects: effect_filters.append('boxblur=5:1') if 'Sharpen' in effects: effect_filters.append('unsharp=5:5:1.0:5:5:0.0') if effect_filters: cmd.extend(['-vf', ','.join(effect_filters)]) # Add filter if filter_type != 'None': filter_map = { 'Grayscale': 'hue=s=0', 'Sepia': 'colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131', 'Vintage': 'lut3d=vintage.lut', 'Cool': 'lut3d=cool.lut', 'Warm': 'lut3d=warm.lut' } if filter_type in filter_map: cmd.extend(['-vf', filter_map[filter_type]]) # Add output cmd.extend(['-c:v', 'libx264', '-c:a', 'aac', output_file]) # Execute ffmpeg try: ffmpeg.run(cmd, overwrite_output=True, quiet=True) return output_file except Exception as e: raise RuntimeError(f"Error applying effects: {str(e)}") def process_video_upload(uploaded_file) -> Tuple[str, Dict[str, Any]]: """Process uploaded video file and return path and info.""" # Save uploaded file to temporary location temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') temp_file.write(uploaded_file.read()) temp_file.close() # Extract video info video_info = extract_video_info(temp_file.name) return temp_file.name, video_info