Skip to content

Latest commit

Β 

History

History
453 lines (363 loc) Β· 10.9 KB

File metadata and controls

453 lines (363 loc) Β· 10.9 KB

API Reference πŸ“‹

This document provides technical details about Auto Clipper's internal APIs and data structures.

πŸ—οΈ Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   CLI Interface │───▢│   Core Engine   │───▢│   Output Files  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚
         β–Ό                       β–Ό                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Input Parser   β”‚    β”‚   AI Analyzer   β”‚    β”‚  Video Clipper  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚
         β–Ό                       β–Ό                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   yt-dlp        β”‚    β”‚   Gemini API    β”‚    β”‚     FFmpeg      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“Š Data Structures

Core Types

Clip

#[derive(Deserialize, Serialize, Debug)]
struct Clip {
    /// Start timestamp in HH:MM:SS format
    start: String,
    /// End timestamp in HH:MM:SS format
    end: String,
    /// Output filename
    output: String,
}

ClipConfig

#[derive(Deserialize, Debug)]
struct ClipConfig {
    /// Path to input video file
    input_video: String,
    /// List of clips to generate
    clips: Vec<Clip>,
}

Gemini API Types

GeminiResponse

#[derive(Deserialize)]
struct GeminiResponse {
    candidates: Vec<GeminiCandidate>,
}

#[derive(Deserialize)]
struct GeminiCandidate {
    content: GeminiContentResponse,
}

#[derive(Deserialize)]
struct GeminiContentResponse {
    parts: Vec<GeminiPartResponse>,
}

#[derive(Deserialize)]
struct GeminiPartResponse {
    text: String,
}

πŸ”§ Core Functions

Main Entry Point

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>>

Description: Main application entry point that handles command-line arguments and orchestrates the clipping process.

Parameters: None (uses std::env::args())

Returns: Result<(), Box<dyn std::error::Error>>

Usage:

./auto-clipper "https://youtube.com/watch?v=VIDEO_ID"
./auto-clipper config.json

Video Information Functions

get_video_info

async fn get_video_info(url: &str) -> Result<String, Box<dyn std::error::Error>>

Description: Extracts video title and metadata from YouTube URL using yt-dlp.

Parameters:

  • url: &str - YouTube video URL

Returns: Result<String, Box<dyn std::error::Error>> - Video title and duration

Example:

let info = get_video_info("https://www.youtube.com/watch?v=dQw4w9WgXcQ").await?;
// Returns: "Rick Astley - Never Gonna Give You Up (Official Video)\n213"

get_video_duration

async fn get_video_duration(file: &str) -> Result<f64, Box<dyn std::error::Error>>

Description: Gets video duration in seconds using ffprobe.

Parameters:

  • file: &str - Path to video file

Returns: Result<f64, Box<dyn std::error::Error>> - Duration in seconds

Example:

let duration = get_video_duration("video.mp4").await?;
// Returns: 213.043084

Download Functions

download_video

async fn download_video(url: &str) -> Result<String, Box<dyn std::error::Error>>

Description: Downloads video from YouTube URL using yt-dlp.

Parameters:

  • url: &str - YouTube video URL

Returns: Result<String, Box<dyn std::error::Error>> - Path to downloaded file

Configuration:

  • Format: best[height<=720]
  • Output: video.%(ext)s

Example:

let file_path = download_video("https://www.youtube.com/watch?v=VIDEO_ID").await?;
// Returns: "video.mp4"

AI Analysis Functions

analyze_with_gemini

async fn analyze_with_gemini(
    video_info: &str, 
    duration: f64
) -> Result<String, Box<dyn std::error::Error>>

Description: Analyzes video content using Gemini AI to suggest viral clips.

Parameters:

  • video_info: &str - Video title and metadata
  • duration: f64 - Video duration in seconds

Returns: Result<String, Box<dyn std::error::Error>> - JSON response with clip suggestions

API Endpoint: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent

Request Format:

{
  "contents": [{
    "parts": [{
      "text": "Analyze this YouTube video and suggest 3-5 viral-worthy clips..."
    }]
  }]
}

Response Format:

{
  "candidates": [{
    "content": {
      "parts": [{
        "text": "```json\n{\"input_video\": \"video.mp4\", \"clips\": [...]}\n```"
      }]
    }
  }]
}

🎬 Video Processing

FFmpeg Integration

Clip Generation Command

ffmpeg -i {input_video} -ss {start} -to {end} -c copy -avoid_negative_ts make_zero {output} -y

Parameters:

  • -i {input_video}: Input video file
  • -ss {start}: Start timestamp
  • -to {end}: End timestamp
  • -c copy: Stream copy (no re-encoding)
  • -avoid_negative_ts make_zero: Handle timestamp issues
  • -y: Overwrite output files

Performance: Stream copy mode provides fastest processing by avoiding re-encoding.

🌐 HTTP Client

Gemini API Communication

Request Method

let output = Command::new("curl")
    .args([
        "-X", "POST",
        "-H", "Content-Type: application/json",
        "-d", &format!("@{}", temp_file),
        &format!("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={}", api_key)
    ])
    .output()?;

Error Handling

  • Network timeouts
  • Invalid API keys
  • Rate limiting
  • Malformed responses

πŸ” Input Validation

URL Validation

fn is_youtube_url(input: &str) -> bool {
    input.starts_with("http") && 
    (input.contains("youtube.com") || input.contains("youtu.be"))
}

Timestamp Validation

fn validate_timestamp(timestamp: &str) -> Result<(), ValidationError> {
    // Validates HH:MM:SS or HH:MM:SS.mmm format
}

File Path Validation

fn validate_file_path(path: &str) -> Result<(), ValidationError> {
    // Checks file existence and permissions
}

πŸ“ Configuration Parsing

JSON Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "input_video": {
      "type": "string",
      "description": "Path to input video file"
    },
    "clips": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "pattern": "^\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?$"
          },
          "end": {
            "type": "string",
            "pattern": "^\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?$"
          },
          "output": {
            "type": "string"
          }
        },
        "required": ["start", "end", "output"]
      }
    }
  },
  "required": ["input_video", "clips"]
}

🚨 Error Types

Custom Error Types

#[derive(Debug)]
enum AutoClipperError {
    VideoDownloadError(String),
    AIAnalysisError(String),
    FFmpegError(String),
    ConfigurationError(String),
    NetworkError(String),
}

impl std::error::Error for AutoClipperError {}

Error Handling Patterns

// Network errors
if !output.status.success() {
    return Err(format!("API error: {}", String::from_utf8_lossy(&output.stderr)).into());
}

// File system errors
let config_content = fs::read_to_string(config_path).await
    .map_err(|e| format!("Failed to read config: {}", e))?;

// Parsing errors
let config: ClipConfig = serde_json::from_str(&config_content)
    .map_err(|e| format!("Invalid JSON config: {}", e))?;

πŸ”§ Environment Variables

Required Variables

GEMINI_API_KEY=your_api_key_here

Optional Variables

# Custom API endpoint
GEMINI_API_ENDPOINT=https://custom-endpoint.com

# Request timeout (seconds)
API_TIMEOUT=30

# Maximum video duration (seconds)
MAX_VIDEO_DURATION=3600

# Logging level
RUST_LOG=info

πŸ“Š Performance Metrics

Benchmarks

Operation Typical Time Factors
Video Download 10-30s Video size, network speed
AI Analysis 3-5s API response time
Clip Generation 1-3s per clip Stream copy mode
JSON Parsing <1ms File size

Memory Usage

  • Base application: ~10MB
  • Video processing: Depends on video size
  • Temporary files: Video size + clips

Optimization Tips

// Use stream copy for faster processing
.args(["-c", "copy"])

// Process clips sequentially to manage memory
for clip in clips.iter() {
    process_clip(clip).await?;
}

// Clean up temporary files
fs::remove_file(temp_file).await.ok();

πŸ§ͺ Testing

Unit Tests

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_timestamp_validation() {
        assert!(validate_timestamp("00:01:30").is_ok());
        assert!(validate_timestamp("invalid").is_err());
    }

    #[tokio::test]
    async fn test_video_duration() {
        let duration = get_video_duration("test_video.mp4").await;
        assert!(duration.is_ok());
    }
}

Integration Tests

#[tokio::test]
async fn test_full_workflow() {
    let config = ClipConfig {
        input_video: "test_video.mp4".to_string(),
        clips: vec![
            Clip {
                start: "00:00:10".to_string(),
                end: "00:00:20".to_string(),
                output: "test_clip.mp4".to_string(),
            }
        ],
    };
    
    // Test clip generation
    let result = process_clips(&config).await;
    assert!(result.is_ok());
}

πŸ”— External Dependencies

Rust Crates

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1.0", features = ["full"] }
dotenv = "0.15"

System Dependencies

  • FFmpeg: Video processing engine
  • yt-dlp: YouTube download utility
  • curl: HTTP client for API calls

API Dependencies

  • Gemini AI API: Content analysis
  • YouTube API: Video metadata (via yt-dlp)

Next Steps: Check the Development Guide for contributing to the codebase.