import gradio as gr import cv2 import numpy as np import tempfile import os from PIL import Image, ImageEnhance, ImageFilter import random import math class AdvancedVideoTransformer: def __init__(self): self.transformations = [] def extract_frames(self, video_path): """Extract frames with metadata""" frames = [] cap = cv2.VideoCapture(video_path) if not cap.isOpened(): return [], 30 fps = int(cap.get(cv2.CAP_PROP_FPS)) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) for i in range(total_frames): ret, frame = cap.read() if not ret: break frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) cap.release() return frames, fps def save_video(self, frames, fps, output_path): """Save processed frames as video""" if not frames: return None h, w = frames[0].shape[:2] fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (w, h)) for frame in frames: out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)) out.release() return output_path # TRANSFORMATION METHODS def apply_geometric_transform(self, frame, transform_type="random"): """Apply geometric transformations to avoid duplicate detection""" h, w = frame.shape[:2] if transform_type == "random" or transform_type == "perspective": # Random perspective transform pts1 = np.float32([[0, 0], [w, 0], [0, h], [w, h]]) margin = min(w, h) * 0.1 pts2 = np.float32([ [random.uniform(0, margin), random.uniform(0, margin)], [w - random.uniform(0, margin), random.uniform(0, margin)], [random.uniform(0, margin), h - random.uniform(0, margin)], [w - random.uniform(0, margin), h - random.uniform(0, margin)] ]) matrix = cv2.getPerspectiveTransform(pts1, pts2) transformed = cv2.warpPerspective(frame, matrix, (w, h)) return transformed elif transform_type == "rotation": # Small rotation angle = random.uniform(-5, 5) center = (w // 2, h // 2) matrix = cv2.getRotationMatrix2D(center, angle, 1.0) rotated = cv2.warpAffine(frame, matrix, (w, h)) return rotated elif transform_type == "scale": # Slight scale variation scale = random.uniform(0.95, 1.05) new_w, new_h = int(w * scale), int(h * scale) scaled = cv2.resize(frame, (new_w, new_h)) # Pad or crop to original size if scale > 1: start_x = (new_w - w) // 2 start_y = (new_h - h) // 2 result = scaled[start_y:start_y+h, start_x:start_x+w] else: pad_x = (w - new_w) // 2 pad_y = (h - new_h) // 2 result = np.zeros((h, w, 3), dtype=np.uint8) result[pad_y:pad_y+new_h, pad_x:pad_x+new_w] = scaled return result return frame def apply_color_transformation(self, frame): """Comprehensive color transformation""" # Convert to PIL for easier processing pil_img = Image.fromarray(frame) # Random brightness adjustment brightness_factor = random.uniform(0.9, 1.1) enhancer = ImageEnhance.Brightness(pil_img) pil_img = enhancer.enhance(brightness_factor) # Random contrast adjustment contrast_factor = random.uniform(0.9, 1.1) enhancer = ImageEnhance.Contrast(pil_img) pil_img = enhancer.enhance(contrast_factor) # Random color saturation color_factor = random.uniform(0.8, 1.2) enhancer = ImageEnhance.Color(pil_img) pil_img = enhancer.enhance(color_factor) # Apply color grading img_array = np.array(pil_img, dtype=np.float32) # Random RGB channel adjustments r_mult = random.uniform(0.95, 1.05) g_mult = random.uniform(0.95, 1.05) b_mult = random.uniform(0.95, 1.05) img_array[:,:,0] *= r_mult img_array[:,:,1] *= g_mult img_array[:,:,2] *= b_mult # Clip values img_array = np.clip(img_array, 0, 255).astype(np.uint8) return img_array def apply_temporal_modification(self, frames): """Modify timing to avoid duplicate detection""" if len(frames) < 10: return frames modified_frames = [] # Add slight variations in frame timing for i, frame in enumerate(frames): # Occasionally duplicate or skip frames action = random.choices( ['keep', 'duplicate', 'skip'], weights=[0.8, 0.1, 0.1], k=1 )[0] if action == 'keep': modified_frames.append(frame) elif action == 'duplicate' and i > 0 and i < len(frames) - 1: # Add a slightly modified version of this frame modified_frame = frame.copy() # Add small noise noise = np.random.normal(0, 5, frame.shape) modified_frame = np.clip(modified_frame.astype(np.float32) + noise, 0, 255).astype(np.uint8) modified_frames.append(frame) modified_frames.append(modified_frame) # If 'skip', don't add the frame (effectively speeding up that part) return modified_frames if modified_frames else frames def apply_visual_effects(self, frame): """Add subtle visual effects to change appearance""" h, w = frame.shape[:2] # Add very subtle noise (imperceptible but changes pixel values) noise = np.random.normal(0, 2, frame.shape) frame_with_noise = np.clip(frame.astype(np.float32) + noise, 0, 255).astype(np.uint8) # Add subtle vignette effect center = (w // 2, h // 2) Y, X = np.ogrid[:h, :w] dist_from_center = np.sqrt((X - center[0])**2 + (Y - center[1])**2) max_dist = np.sqrt(center[0]**2 + center[1]**2) vignette = 1 - (dist_from_center / max_dist) * 0.1 # Very subtle vignette = np.stack([vignette] * 3, axis=2) frame_vignette = (frame_with_noise * vignette).astype(np.uint8) # Apply very slight blur to reduce sharpness differences frame_blurred = cv2.GaussianBlur(frame_vignette, (3, 3), 0) return frame_blurred def apply_content_rearrangement(self, frames): """Rearrange content structure to avoid duplicate detection""" if len(frames) < 20: return frames # Split into segments segment_size = max(10, len(frames) // 5) segments = [] for i in range(0, len(frames), segment_size): segment = frames[i:i+segment_size] if len(segment) > 0: segments.append(segment) if len(segments) < 2: return frames # Randomly reorder segments (but keep first and last for coherence) if len(segments) > 2: middle_segments = segments[1:-1] random.shuffle(middle_segments) segments = [segments[0]] + middle_segments + [segments[-1]] # Reconstruct video rearranged_frames = [] for segment in segments: rearranged_frames.extend(segment) return rearranged_frames def apply_comprehensive_transformation(self, video_path, intensity="medium"): """Apply all transformations for maximum uniqueness while preserving quality""" if not video_path: return None, "Please upload a video first" try: # Extract frames frames, fps = self.extract_frames(video_path) if not frames: return None, "Failed to extract frames" original_count = len(frames) print(f"Processing {original_count} frames...") # Apply geometric transformations print("Applying geometric transformations...") geo_frames = [] for i, frame in enumerate(frames): if intensity == "high": transform_type = random.choice(["perspective", "rotation", "scale"]) else: transform_type = "rotation" if i % 3 == 0 else "scale" transformed = self.apply_geometric_transform(frame, transform_type) geo_frames.append(transformed) # Apply color transformations print("Applying color transformations...") color_frames = [] for frame in geo_frames: transformed = self.apply_color_transformation(frame) color_frames.append(transformed) # Apply temporal modifications (for medium/high intensity) if intensity in ["medium", "high"]: print("Applying temporal modifications...") temporal_frames = self.apply_temporal_modification(color_frames) else: temporal_frames = color_frames # Apply content rearrangement (for high intensity) if intensity == "high": print("Applying content rearrangement...") rearranged_frames = self.apply_content_rearrangement(temporal_frames) else: rearranged_frames = temporal_frames # Apply visual effects print("Applying visual effects...") final_frames = [] for frame in rearranged_frames: transformed = self.apply_visual_effects(frame) final_frames.append(transformed) # Save video print("Saving final video...") output_path = tempfile.mktemp(suffix='.mp4') self.save_video(final_frames, fps, output_path) final_count = len(final_frames) status_msg = f"""✅ Video successfully transformed! 📊 Transformation Summary: - Original frames: {original_count} - Final frames: {final_count} - Intensity level: {intensity} - Applied transformations: Geometric, Color, Temporal, Visual Effects 🎯 Result: Video is now significantly different from original while maintaining quality. Perfect for avoiding duplicate content detection!""" return output_path, status_msg except Exception as e: return None, f"❌ Error: {str(e)}" # Create instance transformer = AdvancedVideoTransformer() # Create interface with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🎬 Advanced Video Transformer ### Transform videos to avoid duplicate content detection while maintaining quality """) with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 📤 Upload Your Video") video_input = gr.Video(label="Original Video") gr.Markdown("### ⚙️ Transformation Settings") intensity = gr.Radio( choices=["low", "medium", "high"], value="medium", label="Transformation Intensity", info="Higher intensity = more changes, better for avoiding detection" ) transform_btn = gr.Button("🚀 Transform Video", variant="primary", size="lg") gr.Markdown(""" ### 🎯 What This Does: - **Geometric Changes**: Rotation, scaling, perspective warping - **Color Adjustments**: Brightness, contrast, saturation variations - **Temporal Modifications**: Frame timing changes, occasional duplicates/skips - **Visual Effects**: Subtle noise, vignette, slight blur - **Content Rearrangement**: Segment reordering (high intensity only) All while preserving overall video quality! """) with gr.Column(scale=1): gr.Markdown("### 📥 Transformed Video") video_output = gr.Video(label="Transformed Video") status_output = gr.Textbox(label="Transformation Status", lines=10) # Examples section gr.Markdown(""" --- ### 💡 Recommended Settings: - **Low Intensity**: Minor changes, good for slight variations - **Medium Intensity**: Balanced approach, recommended for most use cases - **High Intensity**: Maximum changes, best for strict duplicate detection avoidance ### 📈 Quality Preservation Features: - Maintains original resolution - Preserves audio quality (if any) - Smooth transitions between frames - Minimal visible artifacts """) # Event handler transform_btn.click( fn=transformer.apply_comprehensive_transformation, inputs=[video_input, intensity], outputs=[video_output, status_output] ) # Launch demo.queue().launch()