""" broll.py --------------------------------------- AI B-Roll Injection System (V8) Purpose: - Detect topics in transcript - Map topics → generic stock B-roll assets - Overlay or replace segments - Improve retention & visual variety Works in CPU-only environments. No external API dependency required. """ import os import random import subprocess # ===================================================== # STOCK B-ROLL LIBRARY (LOCAL FALLBACK) # ===================================================== DEFAULT_BROLL = { "money": "assets/broll/money.mp4", "success": "assets/broll/success.mp4", "business": "assets/broll/business.mp4", "phone": "assets/broll/phone.mp4", "tech": "assets/broll/tech.mp4", "people": "assets/broll/people.mp4", "talking": "assets/broll/talking.mp4", "default": "assets/broll/default.mp4", } # ===================================================== # TOPIC DETECTION # ===================================================== def detect_topic(text): """ Simple keyword-based topic classifier. Lightweight (no ML dependency). """ text = text.lower() if any(w in text for w in ["money", "rich", "income", "profit"]): return "money" if any(w in text for w in ["business", "startup", "company"]): return "business" if any(w in text for w in ["phone", "mobile", "iphone", "android"]): return "phone" if any(w in text for w in ["tech", "ai", "software", "computer"]): return "tech" if any(w in text for w in ["success", "win", "achieve"]): return "success" if any(w in text for w in ["people", "person", "man", "woman"]): return "people" if any(w in text for w in ["talk", "speak", "say"]): return "talking" return "default" # ===================================================== # SEGMENT ANALYZER # ===================================================== def extract_segments(words, segment_length=8): """ Converts transcript words into grouped segments. """ segments = [] buffer = [] for w in words: buffer.append(w) if len(buffer) >= segment_length: segments.append(buffer) buffer = [] if buffer: segments.append(buffer) return segments # ===================================================== # B-ROLL MATCHING ENGINE # ===================================================== def match_broll(segment): """ Map transcript segment → B-roll video """ text = " ".join([w["word"] for w in segment]) topic = detect_topic(text) return DEFAULT_BROLL.get(topic, DEFAULT_BROLL["default"]) # ===================================================== # B-ROLL INSERTION (FFMPEG OVERLAY STRATEGY) # ===================================================== def overlay_broll(base_video, broll_video, output_path, start_time, duration): """ Overlays B-roll using ffmpeg. Lightweight crossfade approach. """ cmd = [ "ffmpeg", "-y", "-i", base_video, "-i", broll_video, "-filter_complex", f"[1:v]scale=1080:1920,format=rgba[ov];" f"[0:v][ov]overlay=enable='between(t,{start_time},{start_time+duration})'", "-c:v", "libx264", "-preset", "ultrafast", "-c:a", "copy", output_path ] subprocess.run(cmd, check=True) # ===================================================== # MAIN PIPELINE # ===================================================== def insert_broll(video_path, words=None): """ Full B-roll injection pipeline """ if not words: # fallback: return original video return video_path segments = extract_segments(words) current_video = video_path outputs = [] for i, segment in enumerate(segments): broll = match_broll(segment) output_file = f"broll_output_{i}.mp4" start_time = segment[0]["start"] duration = segment[-1]["end"] - start_time try: overlay_broll( current_video, broll, output_file, start_time, duration ) current_video = output_file outputs.append(output_file) except Exception as e: print(f"[BROLL ERROR] Segment {i}: {e}") continue return outputs[-1] if outputs else video_path # ===================================================== # ADVANCED VERSION (V8 EXTENSION) # ===================================================== def smart_broll_engine(words, hook_boost=True): """ Enhanced version: - prioritizes hook segments - increases emotional pacing """ segments = extract_segments(words) prioritized = [] for seg in segments: text = " ".join([w["word"] for w in seg]).lower() score = 0 if any(k in text for k in ["you", "this", "stop", "now"]): score += 2 if hook_boost and len(seg) < 5: score += 1 prioritized.append((score, seg)) prioritized.sort(reverse=True, key=lambda x: x[0]) final_video = None for _, seg in prioritized: final_video = insert_broll(final_video or "input.mp4", seg) return final_video