Skip to main content

Command Palette

Search for a command to run...

Automating Viral Video Highlights with Python and Computer Vision

Updated
6 min read
Automating Viral Video Highlights with Python and Computer Vision
C

Software Engineer and Financial Freedom Advocate. I build and write about modern Python applications, computer vision, and automation. My mission is to use technology to simplify the journey toward financial independence.

Learn how to build your own AI video clipper using Python and OpenCV. This guide covers Optical Flow, motion detection algorithms, and automating the search for viral highlights.


Introduction

The Problem: You have a 3-hour podcast recording. Somewhere inside is a viral 30-second clip that could get a million views on TikTok. Finding it manually takes hours of scrubbing through timelines. What if your code could watch the video for you?

The Context: In the "Attention Economy," speed is everything. Tools like OpusClip and Munch are great, but they are expensive "black boxes." As a developer, building your own clipping engine gives you granular control over what defines a highlight, whether it's loud laughter, rapid movement, or a specific visual pattern.

What You'll Learn: In this post, we’ll dive deep into the Computer Vision techniques behind automated editing. You’ll learn:

  • How Optical Flow algorithms track motion pixel-by-pixel.

  • How to calculate "Motion Energy" to identify high-action segments.

  • How to implement a complete highlight detection script using Python and OpenCV.


Section 1: Understanding Optical Flow

The Concept

Videos are just a stack of images (frames) played in sequence. Optical Flow is the pattern of apparent motion of objects between two consecutive frames caused by the movement of the object or the camera.

For a computer to "see" motion, it compares Frame $T$ (current) with Frame $T-1$ (previous).

Sparse vs. Dense Flow

There are two main ways to calculate this:

  1. Sparse Optical Flow (Lucas-Kanade): Tracks a few specific points (like the corners of eyes or a mouth). Great for face tracking.

  2. Dense Optical Flow (Farneback): Calculates motion for every single pixel in the frame. This is computationally heavier but gives us a "heatmap" of global activity.

Key Takeaway: For finding "viral moments"—like a guest throwing their hands up, leaning forward intensely, or a crowd cheering—we use Dense Optical Flow. High global pixel movement usually correlates with high emotional energy.


Section 2: Implementing Dense Optical Flow

Setting Up

We will use cv2.calcOpticalFlowFarneback, a robust algorithm built into OpenCV.

Prerequisites:

pip install opencv-contrib-python numpy

The Code

Here is how we convert two frames into flow vectors:

import cv2
import numpy as np

# 1. Read two frames
cap = cv2.VideoCapture('podcast.mp4')
ret, frame1 = cap.read()
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

while True:
    ret, frame2 = cap.read()
    if not ret: break
    next_frame = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

    # 2. Calculate Dense Flow
    # Parameters: prev, next, flow, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags
    flow = cv2.calcOpticalFlowFarneback(prvs, next_frame, None, 0.5, 3, 15, 3, 5, 1.2, 0)

    # Update previous frame
    prvs = next_frame

Visual Aid: Think of flow as a 2D array where every pixel has an $(x, y)$ vector telling us how far it moved.


Section 3: Detecting "High Energy" Moments

Now that we have the motion vectors, we need to convert them into a single "Excitement Score."

The Math

We convert Cartesian coordinates $(x, y)$ into Polar coordinates (Magnitude and Angle).

  • Magnitude: Speed of motion.

  • Angle: Direction of motion.

We only care about Magnitude.

# Calculate Magnitude and Angle
mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])

# Calculate the mean motion of the entire frame
avg_motion = np.mean(mag)

# Define a threshold for "High Energy"
if avg_motion > 5.0:
    print("Action Detected!")

Common Pitfalls

  • ⚠️ Mistake 1: Camera Shake. If the camera moves, every pixel moves. The algorithm thinks it's a high-action scene.

    • Fix: Use stabilization or subtract the median motion vector.
  • ⚠️ Mistake 2: Noise. Grainy low-light footage creates fake "motion."

    • Fix: Apply a Gaussian Blur (cv2.GaussianBlur) before calculating flow.

Complete Working Example

Here is the full, robust script. It includes color visualization so you can "see" the motion.

import cv2
import numpy as np

def detect_highlights(video_path, threshold=2.0):
    cap = cv2.VideoCapture(video_path)

    # Read the first frame
    ret, frame1 = cap.read()
    if not ret:
        print("Error: Could not read video.")
        return

    # Convert to grayscale
    prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

    # Create HSV mask for coloring
    hsv = np.zeros_like(frame1)
    hsv[..., 1] = 255

    print(f"Analyzing {video_path}...")

    while True:
        ret, frame2 = cap.read()
        if not ret:
            break

        next_frame = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

        # Calculate Flow
        flow = cv2.calcOpticalFlowFarneback(prvs, next_frame, None, 0.5, 3, 15, 3, 5, 1.2, 0)

        # Get Magnitude (Speed)
        mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])

        # Visualization logic
        hsv[..., 0] = ang * 180 / np.pi / 2 # Color = Direction
        hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) # Brightness = Speed
        bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

        # Detection Logic
        avg_motion = np.mean(mag)
        timestamp = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0

        if avg_motion > threshold:
            print(f"🔥 Highlight at {timestamp:.2f}s (Score: {avg_motion:.2f})")
            # Draw red box on output
            cv2.rectangle(bgr, (0, 0), (bgr.shape[1], bgr.shape[0]), (0, 0, 255), 10)

        # Display result
        cv2.imshow('AI Highlight Detector', bgr)

        # Exit on 'q'
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

        prvs = next_frame

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    # Replace with your video path
    detect_highlights('clip.mp4')

Comparison: Custom Script vs. SaaS Tools

ApproachProsConsWhen to Use
Python ScriptFree, fully customizable, privacy-focused (local).Requires coding, no GUI, requires tuning thresholds.You have technical skills and want to process bulk files cheaply.
OpusClip / MunchPolished UI, adds captions automatically, face tracking included.Expensive ($20+/mo), long processing times, black-box logic.You want a "done-for-you" solution and have a budget.
Manual EditingPerfect creative control.Extremely slow, unscalable.High-stakes projects where every frame matters.

Troubleshooting

Issue 1: "The script detects nothing."

  • Cause: Your threshold is too high.

  • Solution: Lower the threshold to 0.5 or 1.0. Every video has different lighting and movement baselines.

Issue 2: "It runs too slowly."

  • Cause: Dense Optical Flow is CPU intensive.

  • Solution: Resize the frame before processing.

      frame2 = cv2.resize(frame2, (640, 360)) # Process at 360p
    

    This speeds up calculation by 4x-10x with minimal accuracy loss.


Conclusion

You’ve now built a functional "Virality Detector" that uses Computer Vision to find high-energy moments in video.

By combining this Motion Analysis with Audio Analysis (checking for volume spikes), you can build a clipping pipeline that rivals expensive SaaS tools—running entirely on your laptop for free.

Next Steps:

  • Try integrating Audio Volume detection to filter out silent movements (like a cameraman walking).

  • Use ffmpeg to automatically cut the detected timestamps into separate files.

  • Check out the full course "Video Clipping for Profits" for the complete agency roadmap.

Happy coding! 🎥


Additional Resources