def execute_python_script(script_code, context=None): """ Safely execute Python script with limited context Returns script output or error message """ import io import sys from contextlib import redirect_stdout, redirect_stderr if context is None: context = { 'video_path': None, 'frame_data': None, 'metadata': None } # Capture output output = io.StringIO() error = io.StringIO() try: with redirect_stdout(output), redirect_stderr(error): # Create restricted execution environment exec_globals = { '__builtins__': { 'print': print, 'str': str, 'int': int, 'float': float, 'list': list, 'dict': dict, 'tuple': tuple, 'range': range, 'len': len, 'enumerate': enumerate, 'zip': zip, 'min': min, 'max': max, 'sum': sum, 'abs': abs, 'round': round }, 'context': context } exec(script_code, exec_globals) if error.getvalue(): return f"Error: {error.getvalue()}" else: return output.getvalue() except Exception as e: return f"Error executing script: {str(e)}" def validate_python_script(script_code): """ Validate Python script syntax and restricted functions Returns (is_valid, error_message) """ import ast try: # Parse script into AST tree = ast.parse(script_code) # Check for disallowed nodes for node in ast.walk(tree): if isinstance(node, ast.Import): return (False, "Import statements are not allowed") if isinstance(node, ast.ImportFrom): return (False, "Import statements are not allowed") if isinstance(node, ast.Call): if isinstance(node.func, ast.Name): if node.func.id in ['eval', 'exec', 'open', 'execfile']: return (False, f"Function {node.func.id}() is not allowed") return (True, "Script is valid") except SyntaxError as e: return (False, f"Syntax error: {str(e)}") def extract_video_metadata(video_path): """ Extract technical metadata from video file Returns dictionary of metadata """ import cv2 from datetime import datetime import os cap = cv2.VideoCapture(video_path) if not cap.isOpened(): return None # Get basic 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 # Get file info file_stats = os.stat(video_path) created = datetime.fromtimestamp(file_stats.st_ctime) modified = datetime.fromtimestamp(file_stats.st_mtime) cap.release() return { 'filename': os.path.basename(video_path), 'path': video_path, 'resolution': f"{width}x{height}", 'fps': fps, 'duration': duration, 'frame_count': frame_count, 'size': file_stats.st_size, 'created': created, 'modified': modified } def extract_audio_metadata(audio_path): """ Extract technical metadata from audio file Returns dictionary of metadata """ import wave from datetime import datetime import os try: with wave.open(audio_path, 'rb') as audio_file: channels = audio_file.getnchannels() sample_width = audio_file.getsampwidth() framerate = audio_file.getframerate() frames = audio_file.getnframes() duration = frames / float(framerate) file_stats = os.stat(audio_path) created = datetime.fromtimestamp(file_stats.st_ctime) modified = datetime.fromtimestamp(file_stats.st_mtime) return { 'filename': os.path.basename(audio_path), 'path': audio_path, 'channels': channels, 'sample_width': sample_width, 'sample_rate': framerate, 'duration': duration, 'size': file_stats.st_size, 'created': created, 'modified': modified } except: return None def extract_exif_data(image_path): """ Extract EXIF metadata from image file Returns dictionary of EXIF data """ from PIL import Image, ExifTags from datetime import datetime import os try: img = Image.open(image_path) exif_data = img._getexif() if not exif_data: return None exif = {} for tag, value in exif_data.items(): decoded = ExifTags.TAGS.get(tag, tag) exif[decoded] = value # Get file info file_stats = os.stat(image_path) created = datetime.fromtimestamp(file_stats.st_ctime) modified = datetime.fromtimestamp(file_stats.st_mtime) exif['filename'] = os.path.basename(image_path) exif['path'] = image_path exif['size'] = file_stats.st_size exif['created'] = created exif['modified'] = modified return exif except: return None def detect_faces(frame, min_confidence=0.7): """ Detect faces in a frame using OpenCV DNN Returns list of face bounding boxes and confidence scores """ import cv2 import numpy as np # Load pre-trained face detection model model_file = "models/res10_300x300_ssd_iter_140000_fp16.caffemodel" config_file = "models/deploy.prototxt" net = cv2.dnn.readNetFromCaffe(config_file, model_file) (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) net.setInput(blob) detections = net.forward() faces = [] for i in range(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > min_confidence: box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) faces.append({ 'box': box.astype("int"), 'confidence': float(confidence) }) return faces def detect_objects(frame, min_confidence=0.5): """ Detect common objects using COCO-trained model Returns list of detected objects with confidence """ import cv2 import numpy as np # Load COCO class labels and model classes = [] with open("models/coco.names", "r") as f: classes = [line.strip() for line in f.readlines()] model_file = "models/yolov3.weights" config_file = "models/yolov3.cfg" net = cv2.dnn.readNetFromDarknet(config_file, model_file) (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(frame, 1/255.0, (416, 416), swapRB=True, crop=False) net.setInput(blob) layer_names = net.getLayerNames() output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] outputs = net.forward(output_layers) objects = [] for output in outputs: for detection in output: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if confidence > min_confidence: center_x = int(detection[0] * w) center_y = int(detection[1] * h) width = int(detection[2] * w) height = int(detection[3] * h) x = int(center_x - width / 2) y = int(center_y - height / 2) objects.append({ 'class': classes[class_id], 'confidence': float(confidence), 'box': (x, y, width, height) }) return objects def recognize_license_plate(frame): """ Attempt to recognize license plate text Returns detected text and confidence """ import pytesseract import cv2 # Preprocess frame for better OCR gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5,5), 0) thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] # Try to detect plates using contours contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if len(contours) == 2 else contours[1] for c in contours: x,y,w,h = cv2.boundingRect(c) aspect_ratio = w / float(h) # Check if contour matches typical plate aspect ratio if 2 < aspect_ratio < 5 and w > 100 and h > 30: plate_roi = frame[y:y+h, x:x+w] text = pytesseract.image_to_string(plate_roi, config='--psm 8') if text.strip(): return { 'text': text.strip(), 'box': (x,y,w,h) } return None def extract_frames(video_path, frames_dir, frame_rate=1): """ Extract frames from video at specified frame rate Returns list of frame file paths """ import cv2 import os if not os.path.exists(frames_dir): os.makedirs(frames_dir) vidcap = cv2.VideoCapture(video_path) fps = vidcap.get(cv2.CAP_PROP_FPS) frame_interval = int(fps / frame_rate) count = 0 frame_paths = [] success, image = vidcap.read() while success: if count % frame_interval == 0: frame_path = os.path.join(frames_dir, f"frame_{count}.jpg") cv2.imwrite(frame_path, image) frame_paths.append(frame_path) success, image = vidcap.read() count += 1 return frame_paths def apply_filters(frame, brightness=0, contrast=0, saturation=0, sharpness=0): """ Apply enhancement filters to a frame Returns processed frame """ import cv2 import numpy as np # Convert brightness/contrast values to OpenCV format alpha = 1 + contrast/100 beta = brightness # Apply brightness/contrast frame = cv2.convertScaleAbs(frame, alpha=alpha, beta=beta) # Convert to HSV for saturation adjustment hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) hsv[:,:,1] = hsv[:,:,1] * (1 + saturation/100) frame = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # Apply sharpening (unsharp mask) if sharpness > 0: blurred = cv2.GaussianBlur(frame, (0,0), 3) frame = cv2.addWeighted(frame, 1 + sharpness/100, blurred, -sharpness/100, 0) return frame def stabilize_video(input_path, output_path): """ Stabilize shaky video using OpenCV Returns path to stabilized video """ import cv2 # Implementation would use feature detection and motion estimation # This is a simplified placeholder cap = cv2.VideoCapture(input_path) fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, 30.0, (int(cap.get(3)), int(cap.get(4)))) # Actual stabilization algorithm would go here while cap.isOpened(): ret, frame = cap.read() if not ret: break out.write(frame) cap.release() out.release() return output_path def execute_python_script(script_code, context=None): """ Safely execute Python script with limited context Returns script output or error message """ import io import sys from contextlib import redirect_stdout, redirect_stderr if context is None: context = { 'video_path': None, 'frame_data': None, 'metadata': None } # Capture output output = io.StringIO() error = io.StringIO() try: with redirect_stdout(output), redirect_stderr(error): # Create restricted execution environment exec_globals = { '__builtins__': { 'print': print, 'str': str, 'int': int, 'float': float, 'list': list, 'dict': dict, 'tuple': tuple, 'range': range, 'len': len, 'enumerate': enumerate, 'zip': zip, 'min': min, 'max': max, 'sum': sum, 'abs': abs, 'round': round }, 'context': context } exec(script_code, exec_globals) if error.getvalue(): return f"Error: {error.getvalue()}" else: return output.getvalue() except Exception as e: return f"Error executing script: {str(e)}" def validate_python_script(script_code): """ Validate Python script syntax and restricted functions Returns (is_valid, error_message) """ import ast try: # Parse script into AST tree = ast.parse(script_code) # Check for disallowed nodes for node in ast.walk(tree): if isinstance(node, ast.Import): return (False, "Import statements are not allowed") if isinstance(node, ast.ImportFrom): return (False, "Import statements are not allowed") if isinstance(node, ast.Call): if isinstance(node.func, ast.Name): if node.func.id in ['eval', 'exec', 'open', 'execfile']: return (False, f"Function {node.func.id}() is not allowed") return (True, "Script is valid") except SyntaxError as e: return (False, f"Syntax error: {str(e)}") def extract_video_metadata(video_path): """ Extract technical metadata from video file Returns dictionary of metadata """ import cv2 from datetime import datetime import os cap = cv2.VideoCapture(video_path) if not cap.isOpened(): return None # Get basic 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 # Get file info file_stats = os.stat(video_path) created = datetime.fromtimestamp(file_stats.st_ctime) modified = datetime.fromtimestamp(file_stats.st_mtime) cap.release() return { 'filename': os.path.basename(video_path), 'path': video_path, 'resolution': f"{width}x{height}", 'fps': fps, 'duration': duration, 'frame_count': frame_count, 'size': file_stats.st_size, 'created': created, 'modified': modified } def extract_audio_metadata(audio_path): """ Extract technical metadata from audio file Returns dictionary of metadata """ import wave from datetime import datetime import os try: with wave.open(audio_path, 'rb') as audio_file: channels = audio_file.getnchannels() sample_width = audio_file.getsampwidth() framerate = audio_file.getframerate() frames = audio_file.getnframes() duration = frames / float(framerate) file_stats = os.stat(audio_path) created = datetime.fromtimestamp(file_stats.st_ctime) modified = datetime.fromtimestamp(file_stats.st_mtime) return { 'filename': os.path.basename(audio_path), 'path': audio_path, 'channels': channels, 'sample_width': sample_width, 'sample_rate': framerate, 'duration': duration, 'size': file_stats.st_size, 'created': created, 'modified': modified } except: return None def extract_exif_data(image_path): """ Extract EXIF metadata from image file Returns dictionary of EXIF data """ from PIL import Image, ExifTags from datetime import datetime import os try: img = Image.open(image_path) exif_data = img._getexif() if not exif_data: return None exif = {} for tag, value in exif_data.items(): decoded = ExifTags.TAGS.get(tag, tag) exif[decoded] = value # Get file info file_stats = os.stat(image_path) created = datetime.fromtimestamp(file_stats.st_ctime) modified = datetime.fromtimestamp(file_stats.st_mtime) exif['filename'] = os.path.basename(image_path) exif['path'] = image_path exif['size'] = file_stats.st_size exif['created'] = created exif['modified'] = modified return exif except: return None def detect_faces(frame, min_confidence=0.7): """ Detect faces in a frame using OpenCV DNN Returns list of face bounding boxes and confidence scores """ import cv2 import numpy as np # Load pre-trained face detection model model_file = "models/res10_300x300_ssd_iter_140000_fp16.caffemodel" config_file = "models/deploy.prototxt" net = cv2.dnn.readNetFromCaffe(config_file, model_file) (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) net.setInput(blob) detections = net.forward() faces = [] for i in range(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > min_confidence: box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) faces.append({ 'box': box.astype("int"), 'confidence': float(confidence) }) return faces def detect_objects(frame, min_confidence=0.5): """ Detect common objects using COCO-trained model Returns list of detected objects with confidence """ import cv2 import numpy as np # Load COCO class labels and model classes = [] with open("models/coco.names", "r") as f: classes = [line.strip() for line in f.readlines()] model_file = "models/yolov3.weights" config_file = "models/yolov3.cfg" net = cv2.dnn.readNetFromDarknet(config_file, model_file) (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(frame, 1/255.0, (416, 416), swapRB=True, crop=False) net.setInput(blob) layer_names = net.getLayerNames() output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] outputs = net.forward(output_layers) objects = [] for output in outputs: for detection in output: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if confidence > min_confidence: center_x = int(detection[0] * w) center_y = int(detection[1] * h) width = int(detection[2] * w) height = int(detection[3] * h) x = int(center_x - width / 2) y = int(center_y - height / 2) objects.append({ 'class': classes[class_id], 'confidence': float(confidence), 'box': (x, y, width, height) }) return objects def recognize_license_plate(frame): """ Attempt to recognize license plate text Returns detected text and confidence """ import pytesseract import cv2 # Preprocess frame for better OCR gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5,5), 0) thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] # Try to detect plates using contours contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if len(contours) == 2 else contours[1] for c in contours: x,y,w,h = cv2.boundingRect(c) aspect_ratio = w / float(h) # Check if contour matches typical plate aspect ratio if 2 < aspect_ratio < 5 and w > 100 and h > 30: plate_roi = frame[y:y+h, x:x+w] text = pytesseract.image_to_string(plate_roi, config='--psm 8') if text.strip(): return { 'text': text.strip(), 'box': (x,y,w,h) } return None def extract_frames(video_path, frames_dir, frame_rate=1): """ Extract frames from video at specified frame rate Returns list of frame file paths """ import cv2 import os if not os.path.exists(frames_dir): os.makedirs(frames_dir) vidcap = cv2.VideoCapture(video_path) fps = vidcap.get(cv2.CAP_PROP_FPS) frame_interval = int(fps / frame_rate) count = 0 frame_paths = [] success, image = vidcap.read() while success: if count % frame_interval == 0: frame_path = os.path.join(frames_dir, f"frame_{count}.jpg") cv2.imwrite(frame_path, image) frame_paths.append(frame_path) success, image = vidcap.read() count += 1 return frame_paths def apply_filters(frame, brightness=0, contrast=0, saturation=0, sharpness=0): """ Apply enhancement filters to a frame Returns processed frame """ import cv2 import numpy as np # Convert brightness/contrast values to OpenCV format alpha = 1 + contrast/100 beta = brightness # Apply brightness/contrast frame = cv2.convertScaleAbs(frame, alpha=alpha, beta=beta) # Convert to HSV for saturation adjustment hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) hsv[:,:,1] = hsv[:,:,1] * (1 + saturation/100) frame = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # Apply sharpening (unsharp mask) if sharpness > 0: blurred = cv2.GaussianBlur(frame, (0,0), 3) frame = cv2.addWeighted(frame, 1 + sharpness/100, blurred, -sharpness/100, 0) return frame def stabilize_video(input_path, output_path): """ Stabilize shaky video using OpenCV Returns path to stabilized video """ import cv2 # Implementation would use feature detection and motion estimation # This is a simplified placeholder cap = cv2.VideoCapture(input_path) fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, 30.0, (int(cap.get(3)), int(cap.get(4)))) # Actual stabilization algorithm would go here while cap.isOpened(): ret, frame = cap.read() if not ret: break out.write(frame) cap.release() out.release() return output_path Forensic Video Editor

Forensic Video Editor

Media Library

Surveillance_Camera_1.mp4
Bodycam_Officer_Johnson.mp4
Crime_Scene_Photo_1.jpg
911_Call_Recording.wav

Tools

Metadata

Video Enhancements

Brightness +15%
Contrast +20%
Saturation +10%
Sharpness +25%
00:12:34:15 / 00:23:45:00

Tags & Annotations

Suspicious Activity
00:02:15
Weapon Visible
00:05:42
License Plate
00:08:33
Person of Interest
00:12:07

Color Correction

Analysis Tools

Python Script

Made with DeepSite LogoDeepSite - 🧬 Remix