Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.praison.ai/llms.txt

Use this file to discover all available pages before exploring further.

Video Highlights Reel Planner

Plan video highlight clips from transcripts—identify the best moments without heavy video editing.

Problem Statement

Who: Video editors, content creators, social media managers
Why: Finding highlight-worthy moments in long videos is time-consuming. AI can identify key moments from transcripts.
Planning Only: This recipe focuses on identifying and planning clips, not actual video editing. Keep dependencies minimal for maximum portability.

What You’ll Build

A recipe that analyzes transcripts and outputs a structured clip plan with timestamps and titles.

Input/Output Contract

InputTypeRequiredDescription
transcript_textstringYes*Transcript with timestamps
video_pathstringYes*Path to video (alternative)
highlight_goalstringNoWhat to highlight (default: engaging)
max_clipsintegerNoMaximum clips to identify (default: 10)
*One of transcript_text or video_path is required.
OutputTypeDescription
clip_plan_jsonarrayPlanned clips with timestamps
title_suggestionsarraySuggested titles for each clip
okbooleanSuccess indicator

Prerequisites

export OPENAI_API_KEY=your_key_here
pip install praisonaiagents

Step-by-Step Build

1

Create Recipe Directory

mkdir -p ~/.praisonai/templates/simple-video-highlights-reel-planner
cd ~/.praisonai/templates/simple-video-highlights-reel-planner
2

Create TEMPLATE.yaml

name: simple-video-highlights-reel-planner
version: "1.0.0"
description: "Plan video highlight clips from transcripts"
author: "PraisonAI"
license: "MIT"

tags:
  - video
  - highlights
  - planning
  - content

requires:
  env:
    - OPENAI_API_KEY
  packages:
    - praisonaiagents

inputs:
  transcript_text:
    type: string
    description: "Transcript text with timestamps"
    required: false
  video_path:
    type: string
    description: "Path to video file (alternative)"
    required: false
  highlight_goal:
    type: string
    description: "What type of highlights to find"
    required: false
    default: "engaging"
    enum:
      - engaging
      - educational
      - funny
      - emotional
      - actionable
  max_clips:
    type: integer
    description: "Maximum number of clips to identify"
    required: false
    default: 10
    minimum: 1
    maximum: 50

outputs:
  clip_plan_json:
    type: array
    description: "Planned clips with timestamps and descriptions"
  title_suggestions:
    type: array
    description: "Suggested titles for clips"
  ok:
    type: boolean
    description: "Success indicator"

cli:
  command: "praison recipes run simple-video-highlights-reel-planner"
  examples:
    - 'praison recipes run simple-video-highlights-reel-planner --input ''{"transcript_text": "00:00 Welcome..."}'''

safety:
  dry_run_default: false
  requires_consent: false
  overwrites_files: false
  network_access: true
  pii_handling: false
3

Create recipe.py

# recipe.py
import os
import json
import re
from praisonaiagents import Agent, Task, AgentTeam

def run(input_data: dict, config: dict = None) -> dict:
    """Plan video highlight clips from transcript."""
    transcript_text = input_data.get("transcript_text")
    video_path = input_data.get("video_path")
    highlight_goal = input_data.get("highlight_goal", "engaging")
    max_clips = input_data.get("max_clips", 10)
    
    if not transcript_text and not video_path:
        return {"ok": False, "error": {"code": "MISSING_INPUT", "message": "Either transcript_text or video_path is required"}}
    
    if video_path and not transcript_text:
        if not os.path.exists(video_path):
            return {"ok": False, "error": {"code": "FILE_NOT_FOUND", "message": f"Video not found: {video_path}"}}
        return {"ok": False, "error": {"code": "NOT_IMPLEMENTED", "message": "Video transcription not implemented. Provide transcript_text."}}
    
    try:
        goal_guidelines = {
            "engaging": "Find moments that grab attention, surprising reveals, or compelling stories",
            "educational": "Find clear explanations, key insights, and teachable moments",
            "funny": "Find humorous moments, jokes, and entertaining segments",
            "emotional": "Find touching moments, inspiring stories, and emotional peaks",
            "actionable": "Find practical tips, how-to segments, and advice"
        }
        
        # Create highlight finder agent
        finder = Agent(
            name="Highlight Finder",
            role="Video Content Analyst",
            goal=f"Find the most {highlight_goal} moments",
            instructions=f"""
            You are a video content analyst specializing in finding highlights.
            Goal: {highlight_goal} - {goal_guidelines[highlight_goal]}
            
            For each highlight:
            - Identify start and end timestamps
            - Explain why it's highlight-worthy
            - Suggest a clip duration (15-60 seconds ideal)
            - Rate engagement potential (1-10)
            
            Find up to {max_clips} highlights.
            """,
        )
        
        # Create title generator
        titler = Agent(
            name="Title Generator",
            role="Social Media Specialist",
            goal="Create compelling clip titles",
            instructions="""
            You are a social media specialist.
            - Create catchy, clickable titles
            - Keep titles under 60 characters
            - Use power words and hooks
            - Match the content tone
            """,
        )
        
        # Define tasks
        find_task = Task(
            name="find_highlights",
            description=f"""
            Analyze this transcript and find up to {max_clips} {highlight_goal} highlights:
            
            {transcript_text[:10000]}
            
            Output as JSON array:
            [{{
                "start_time": "MM:SS",
                "end_time": "MM:SS",
                "description": "What happens",
                "why_highlight": "Why it's engaging",
                "engagement_score": 8
            }}]
            """,
            expected_output="JSON array of highlight clips",
            agent=finder,
        )
        
        title_task = Task(
            name="generate_titles",
            description="Generate compelling titles for each highlight clip",
            expected_output="List of titles matching each clip",
            agent=titler,
            context=[find_task],
        )
        
        # Execute
        agents = AgentTeam(
            agents=[finder, titler],
            tasks=[find_task, title_task],
        )
        
        result = agents.start()
        
        # Parse clips
        clips_text = result.get("find_highlights", "[]")
        clips = parse_clips(clips_text)
        
        # Parse titles
        titles_text = result.get("generate_titles", "")
        titles = [t.strip() for t in titles_text.split("\n") if t.strip() and len(t.strip()) > 5]
        
        return {
            "ok": True,
            "clip_plan_json": clips[:max_clips],
            "title_suggestions": titles[:max_clips],
            "artifacts": [],
            "warnings": [],
        }
        
    except Exception as e:
        return {"ok": False, "error": {"code": "PROCESSING_ERROR", "message": str(e)}}


def parse_clips(text: str) -> list:
    """Parse clip plan from agent output."""
    try:
        match = re.search(r'\[.*\]', text, re.DOTALL)
        if match:
            return json.loads(match.group())
    except json.JSONDecodeError:
        pass
    
    # Fallback parsing
    clips = []
    current_clip = {}
    
    for line in text.split('\n'):
        if 'start' in line.lower() and ':' in line:
            time_match = re.search(r'(\d{1,2}:\d{2}(?::\d{2})?)', line)
            if time_match:
                current_clip['start_time'] = time_match.group(1)
        elif 'end' in line.lower() and ':' in line:
            time_match = re.search(r'(\d{1,2}:\d{2}(?::\d{2})?)', line)
            if time_match:
                current_clip['end_time'] = time_match.group(1)
        elif 'description' in line.lower():
            current_clip['description'] = line.split(':', 1)[-1].strip()
        
        if current_clip.get('start_time') and current_clip.get('end_time'):
            clips.append(current_clip)
            current_clip = {}
    
    return clips
4

Create test_recipe.py

# test_recipe.py
import pytest
from recipe import run, parse_clips

def test_missing_input():
    result = run({})
    assert result["ok"] is False
    assert result["error"]["code"] == "MISSING_INPUT"

def test_parse_clips_json():
    text = '[{"start_time": "00:30", "end_time": "01:00", "description": "Key moment"}]'
    clips = parse_clips(text)
    assert len(clips) == 1
    assert clips[0]["start_time"] == "00:30"

def test_highlight_goals():
    valid_goals = ["engaging", "educational", "funny", "emotional", "actionable"]
    for goal in valid_goals:
        assert goal in valid_goals

@pytest.mark.integration
def test_end_to_end():
    transcript = """
    00:00 Welcome to today's video about productivity tips.
    02:30 Here's the number one tip that changed my life.
    05:00 Let me show you exactly how to implement this.
    10:00 The results were incredible - I saved 10 hours per week.
    15:00 Thanks for watching, don't forget to subscribe!
    """
    
    result = run({
        "transcript_text": transcript,
        "highlight_goal": "actionable",
        "max_clips": 5
    })
    
    assert result["ok"] is True
    assert len(result["clip_plan_json"]) > 0

Run Locally

# Basic usage
praison recipes run simple-video-highlights-reel-planner \
  --input '{"transcript_text": "00:00 Welcome..."}'

# Find funny moments
praison recipes run simple-video-highlights-reel-planner \
  --input '{"transcript_text": "...", "highlight_goal": "funny", "max_clips": 5}'

Deploy & Integrate: 6 Integration Models

from praisonai import recipe

# Load or define transcript
transcript = "00:00 Introduction to the topic..."

result = recipe.run(
    "simple-video-highlights-reel-planner",
    input={
        "transcript_text": transcript,
        "highlight_goal": "engaging",
        "max_clips": 10
    }
)

if result.ok:
    for i, clip in enumerate(result.output["clip_plan_json"]):
        title = result.output["title_suggestions"][i] if i < len(result.output["title_suggestions"]) else "Untitled"
        print(f"{clip['start_time']} - {clip['end_time']}: {title}")

Troubleshooting

Ensure your transcript includes timestamps. The recipe needs timing information to plan clips.
The recipe targets 15-60 second clips. For different durations, adjust the instructions in a custom fork.

Next Steps