import cv2
import numpy as np
import subprocess
import os
import random
import math
from concurrent.futures import ProcessPoolExecutor

# --- Settings ---
OUTPUT_DIR = r"C:\Users\Bot\Documents\ffmpeg_bg"
NUM_VIDEOS = 100  
DURATION = 20  
FPS = 30
WIDTH, HEIGHT = 1920, 1080
TOTAL_FRAMES = DURATION * FPS

if not os.path.exists(OUTPUT_DIR):
    os.makedirs(OUTPUT_DIR)

# Soft, aesthetically pleasing color palettes (BGR format for OpenCV)
MODERN_COLORS = [
    (255, 190, 120), # Neon Orange
    (255, 220, 120), # Cyber Cyan
    (180, 255, 140), # Matrix Green
    (255, 160, 220), # Futuristic Purple
    (120, 220, 255), # Electric Blue
    (200, 200, 200), # Metallic Silver
    (255, 210, 180)  # Soft Tech Peach
]
def get_ffmpeg_process(filename):
    """Initializes ffmpeg with NVENC GPU hardware acceleration."""
    command = [
        'ffmpeg', '-y', '-f', 'rawvideo', '-vcodec', 'rawvideo',
        '-s', f'{WIDTH}x{HEIGHT}', '-pix_fmt', 'bgr24', '-r', str(FPS),
        '-i', '-', '-vf', 'scale=1920:1080,fps=30,format=yuv420p',
        '-c:v', 'h264_nvenc', '-preset', 'fast', '-b:v', '5M', '-pix_fmt', 'yuv420p',
        '-c:a', 'aac', '-b:a', '192k', filename
    ]
    return subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

# ==========================================
# 10 COMPLETE MODERN ANIMATION ENGINES
# ==========================================

def draw_organic_ribbons(img, f, color, variant):
    """Engine 0: Smooth overlapping sine wave ribbons"""
    t = f * (0.01 + variant * 0.002)
    for i in range(5):
        pts = []
        for x in range(0, WIDTH + 50, 50):
            y = HEIGHT // 2 + math.sin(x * 0.005 + t + i) * (150 + variant * 20) + math.cos(x * 0.002 - t) * 100
            pts.append([x, int(y)])
        pts = np.array(pts, np.int32).reshape((-1, 1, 2))
        cv2.polylines(img, [pts], False, color, 20 + variant * 5)

def draw_soft_bokeh(img, f, color, variant):
    """Engine 1: Floating out-of-focus orbs / light leaks"""
    t = f * 0.02
    random.seed(variant * 100) # Ensure consistent layout for this specific video
    for _ in range(15 + variant):
        start_x = random.randint(0, WIDTH)
        start_y = random.randint(0, HEIGHT)
        speed_x = random.uniform(-2, 2)
        speed_y = random.uniform(-2, 2)
        radius = random.randint(100, 400 + variant * 20)
       
        x = int(start_x + math.sin(t * speed_x) * 200)
        y = int(start_y + math.cos(t * speed_y) * 200)
        cv2.circle(img, (x, y), radius, color, 40 + variant * 5)

def draw_plexus_network(img, f, color, variant):
    """Engine 2: Modern tech network lines connecting dots"""
    t = f * 0.05
    random.seed(variant * 10)
    nodes = [{'x': random.randint(0, WIDTH), 'y': random.randint(0, HEIGHT), 'vx': random.uniform(-1,1), 'vy': random.uniform(-1,1)} for _ in range(30 + variant * 2)]
   
    for node in nodes:
        node['x'] = (node['x'] + node['vx'] * t) % WIDTH
        node['y'] = (node['y'] + node['vy'] * t) % HEIGHT
        cv2.circle(img, (int(node['x']), int(node['y'])), 8, color, -1)
       
        for other in nodes:
            dist = math.hypot(node['x'] - other['x'], node['y'] - other['y'])
            if 0 < dist < 200 + (variant * 15):
                cv2.line(img, (int(node['x']), int(node['y'])), (int(other['x']), int(other['y'])), color, 2)

def draw_floating_icons(img, f, color, variant):
    """Engine 3: Clean, modern floating UI shapes (play buttons, crosses, rings)"""
    t = f * 0.03
    spacing = 150 + variant * 20
    for x in range(100, WIDTH, spacing):
        for y in range(100, HEIGHT, spacing):
            offset_y = int(math.sin(x * 0.01 + t) * (50 + variant * 5))
            center = (x, y + offset_y)
           
            icon_type = (x + y + variant) % 3
            if icon_type == 0: # Play button (Triangle)
                pts = np.array([[center[0]-20, center[1]-20], [center[0]-20, center[1]+20], [center[0]+20, center[1]]], np.int32)
                cv2.fillPoly(img, [pts], color)
            elif icon_type == 1: # Plus / Cross
                cv2.line(img, (center[0]-20, center[1]), (center[0]+20, center[1]), color, 8)
                cv2.line(img, (center[0], center[1]-20), (center[0], center[1]+20), color, 8)
            else: # Hollow Dot
                cv2.circle(img, center, 15, color, 5)

def draw_liquid_blobs(img, f, color, variant):
    """Engine 4: Abstract morphing liquid shapes"""
    t = f * (0.04 + variant * 0.002)
    cx, cy = WIDTH // 2, HEIGHT // 2
    pts = []
    points_count = 8 + variant
    for i in range(points_count):
        angle = (2 * math.pi / points_count) * i
        r = 300 + math.sin(t + i * 1.5) * (150 + variant * 10) + math.cos(t * 0.8 + i) * 100
        pts.append([int(cx + math.cos(angle) * r), int(cy + math.sin(angle) * r)])
   
    pts = np.array(pts, np.int32).reshape((-1, 1, 2))
    cv2.fillPoly(img, [pts], color)

def draw_minimalist_sweeps(img, f, color, variant):
    """Engine 5: Diagonal Minimalist Sweeps"""
    offset = (f * (2 + variant * 0.5)) % 300
    thickness = 20 + variant * 5
    spacing = 150 + variant * 15
    for x in range(0, WIDTH + HEIGHT, spacing):
        cv2.line(img, (x - int(offset), 0), (x - HEIGHT - int(offset), HEIGHT), color, thickness)

def draw_radar_pulses(img, f, color, variant):
    """Engine 6: Radar / Sonar Pulses from center"""
    t = f * (0.03 + variant * 0.005)
    cx, cy = WIDTH // 2, HEIGHT // 2
    spacing = 80 + variant * 15
    for r in range(50, WIDTH, spacing):
        current_r = int((r + t * 50) % WIDTH)
        thickness = max(2, 20 - int(current_r * 0.015))
        cv2.circle(img, (cx, cy), current_r, color, thickness)

def draw_morphing_grid(img, f, color, variant):
    """Engine 7: Abstract Morphing / Wavy Grid"""
    t = f * 0.02
    spacing = 80 + variant * 10
    wave_amp = 50 + variant * 10
    for x in range(0, WIDTH, spacing):
        cv2.line(img, (x, 0), (int(x + math.sin(t + x * 0.01) * wave_amp), HEIGHT), color, 4)
    for y in range(0, HEIGHT, spacing):
        cv2.line(img, (0, y), (WIDTH, int(y + math.cos(t + y * 0.01) * wave_amp)), color, 4)

def draw_data_streams(img, f, color, variant):
    """Engine 8: Floating Data Streams (Vertical Code-like dashes)"""
    random.seed(variant * 55)
    for _ in range(60 + variant * 10):
        x = random.randint(0, WIDTH)
        speed = random.uniform(1, 3 + variant * 0.2)
        y = int((f * speed + random.randint(0, HEIGHT)) % HEIGHT)
        length = random.randint(20, 100 + variant * 10)
        cv2.line(img, (x, y), (x, y + length), color, 6 + (variant % 3) * 2)

def draw_rotating_orbitals(img, f, color, variant):
    """Engine 9: Slow Rotating 3D-like Orbitals"""
    t = f * (0.01 + variant * 0.002)
    cx, cy = WIDTH // 2, HEIGHT // 2
    num_rings = 4 + variant % 5
    for i in range(1, num_rings + 1):
        # Alternate rotation direction for each ring
        direction = 1 if i % 2 == 0 else -1
        angle = int(math.degrees(t * direction))
        cv2.ellipse(img, (cx, cy), (150 * i, 75 * i), angle, 0, 360, color, 6 + variant)


def apply_master_logic(overlay, f, color, logic_id):
    """Maps exactly 1 to 100 into 10 distinct engines with 10 math variations each"""
    engine_id = (logic_id - 1) // 10  # Results in 0 through 9
    variant = (logic_id - 1) % 10     # Results in 0 through 9
   
    if engine_id == 0: draw_organic_ribbons(overlay, f, color, variant)
    elif engine_id == 1: draw_soft_bokeh(overlay, f, color, variant)
    elif engine_id == 2: draw_plexus_network(overlay, f, color, variant)
    elif engine_id == 3: draw_floating_icons(overlay, f, color, variant)
    elif engine_id == 4: draw_liquid_blobs(overlay, f, color, variant)
    elif engine_id == 5: draw_minimalist_sweeps(overlay, f, color, variant)
    elif engine_id == 6: draw_radar_pulses(overlay, f, color, variant)
    elif engine_id == 7: draw_morphing_grid(overlay, f, color, variant)
    elif engine_id == 8: draw_data_streams(overlay, f, color, variant)
    elif engine_id == 9: draw_rotating_orbitals(overlay, f, color, variant)


# ==========================================
# MULTIPROCESSING RENDER WORKER
# ==========================================

def make_video(logic_id):
    filename = os.path.join(OUTPUT_DIR, f"modern_bg_{logic_id:03d}.mp4")
    print(f"Generating Video {logic_id}/100...")
   
    process = get_ffmpeg_process(filename)
   
    # OPACITY CLAMP: Strictly between 12% and 20%
    pattern_bgr = random.choice(MODERN_COLORS)
    opacity = random.uniform(0.12, 0.20)
   
    for f in range(TOTAL_FRAMES):
        # Base Pure White Canvas
        frame = np.full((HEIGHT, WIDTH, 3), (255, 255, 255), dtype=np.uint8)
        overlay = frame.copy()

        # Apply the master logic engine
        apply_master_logic(overlay, f, pattern_bgr, logic_id)

        # Blend overlay with pure white background at very low opacity
        cv2.addWeighted(overlay, opacity, frame, 1 - opacity, 0, frame)

        # Write frame to FFmpeg pipe
        process.stdin.write(frame.tobytes())

    process.stdin.close()
    process.wait()
    print(f"-> Finished Video {logic_id}")


if __name__ == '__main__':
    print(f"Starting Multi-Core Render Engine for {NUM_VIDEOS} Modern Videos...")
   
    # max_workers=5 handles 5 videos simultaneously to drastically boost CPU/GPU feed speed.
    # If your computer lags while rendering, you can lower this to 2 or 3.
    with ProcessPoolExecutor(max_workers=5) as executor:
        executor.map(make_video, range(1, NUM_VIDEOS + 1))
       
    print("ALL 100 VIDEOS COMPLETE! Check your output folder.")

0 comments:

Post a Comment

 
Top