litellm / services /whisper /utils /broll.py
Ava2lon's picture
Upload 205 files
1425afc verified
Raw
History Blame Contribute Delete
5.31 kB
"""
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