litellm / services /whisper /utils /pacing.py
Ava2lon's picture
Upload 205 files
1425afc verified
Raw
History Blame Contribute Delete
5.5 kB
"""
pacing.py
---------------------------------------
Retention & Pacing Optimization Engine (V8)
Purpose:
- Adjust video pacing for maximum retention
- Compress slow segments
- Emphasize high-value moments
- Create TikTok / Reels optimized flow
Works in CPU-only environments (FFmpeg-based).
"""
import subprocess
import os
# =====================================================
# CONFIG
# =====================================================
OUTPUT_FILE = "pacing_optimized.mp4"
SLOW_THRESHOLD = 1.25 # speed multiplier for slow segments
FAST_THRESHOLD = 1.75 # speed multiplier for filler segments
# =====================================================
# BASIC SEGMENT ESTIMATION (NO ML DEPENDENCY)
# =====================================================
def estimate_segment_value(text):
"""
Heuristic scoring system:
determines importance of spoken segment.
"""
text = text.lower()
high_value_keywords = [
"you", "secret", "important", "stop",
"crazy", "insane", "listen", "this",
"money", "success", "life", "truth"
]
filler_keywords = [
"um", "uh", "like", "you know", "so",
"actually", "basically"
]
score = 1.0
# boost high value words
for w in high_value_keywords:
if w in text:
score += 0.6
# penalize filler speech
for w in filler_keywords:
if w in text:
score -= 0.4
return max(0.5, min(score, 2.0))
# =====================================================
# SPEED MAP GENERATOR
# =====================================================
def build_speed_map(words):
"""
Converts transcript into pacing instructions
"""
segments = []
buffer = []
for w in words:
buffer.append(w)
# group into micro segments
if len(buffer) >= 6:
segments.append(buffer)
buffer = []
if buffer:
segments.append(buffer)
speed_map = []
for seg in segments:
text = " ".join([w["word"] for w in seg])
score = estimate_segment_value(text)
start = seg[0]["start"]
end = seg[-1]["end"]
# decide speed
if score > 1.4:
speed = 1.0 # keep normal (important content)
elif score > 1.0:
speed = 1.15 # slight compression
else:
speed = FAST_THRESHOLD # aggressive speed-up
speed_map.append({
"start": start,
"end": end,
"speed": speed
})
return speed_map
# =====================================================
# FFMEG FILTER BUILDER
# =====================================================
def build_filter(speed_map):
"""
Creates FFmpeg atempo + setpts filter chain
"""
filters = []
for i, seg in enumerate(speed_map):
start = seg["start"]
end = seg["end"]
speed = seg["speed"]
# video speed
filters.append(
f"[0:v]trim=start={start}:end={end},setpts=PTS/{speed}[v{i}]"
)
# audio speed
filters.append(
f"[0:a]atrim=start={start}:end={end},asetpts=PTS-STARTPTS,"
f"atempo={speed}[a{i}]"
)
v_streams = "".join([f"[v{i}]" for i in range(len(speed_map))])
a_streams = "".join([f"[a{i}]" for i in range(len(speed_map))])
filters.append(
f"{v_streams}{a_streams}concat=n={len(speed_map)}:v=1:a=1[outv][outa]"
)
return ";".join(filters)
# =====================================================
# MAIN ENGINE
# =====================================================
def optimize_pacing(video_path, words=None):
"""
Main entry point for V8 pacing system
"""
print("[PACING] Starting optimization...")
if not words:
print("[PACING] No transcript provided — returning original video")
return video_path
# Step 1: build speed map
speed_map = build_speed_map(words)
print(f"[PACING] Segments: {len(speed_map)}")
# Step 2: build ffmpeg filter
filter_complex = build_filter(speed_map)
output_path = OUTPUT_FILE
# Step 3: render optimized video
cmd = [
"ffmpeg", "-y",
"-i", video_path,
"-filter_complex", filter_complex,
"-map", "[outv]",
"-map", "[outa]",
"-c:v", "libx264",
"-preset", "ultrafast",
"-c:a", "aac",
output_path
]
subprocess.run(cmd, check=True)
print("[PACING] Done:", output_path)
return output_path
# =====================================================
# LIGHTWEIGHT MODE (FAST FALLBACK)
# =====================================================
def fast_pacing(video_path):
"""
Simple fallback: global speed-up only
"""
output = "fast_pacing.mp4"
cmd = [
"ffmpeg", "-y",
"-i", video_path,
"-filter_complex",
"[0:v]setpts=0.92*PTS[v];[0:a]atempo=1.08[a]",
"-map", "[v]",
"-map", "[a]",
"-c:v", "libx264",
"-preset", "ultrafast",
"-c:a", "aac",
output
]
subprocess.run(cmd, check=True)
return output
# =====================================================
# PUBLIC API
# =====================================================
def pacing_engine(video_path, words=None, mode="smart"):
"""
Entry point used by main.py
"""
if mode == "fast":
return fast_pacing(video_path)
return optimize_pacing(video_path, words)