Skip to main content

Agent-first video cutting library — declarative JSON edits powered by FFmpeg

Project description

CutAgent

Agent-first video cutting library — declarative JSON edits powered by FFmpeg.

CI Python 3.10+ License: MIT

CutAgent is designed from the ground up for AI agents and programmatic video editing. Every CLI command outputs structured JSON. Every operation is composable through a declarative Edit Decision List (EDL) format. No GUI, no human-formatted text — just clean machine-readable interfaces for professional video cutting.

Why CutAgent?

  • Agent-first: Every command returns structured JSON — built for LLM tool use, not human eyes
  • Declarative EDL: Describe your edit as a JSON document, execute it in one call
  • Zero runtime dependencies: Pure Python + FFmpeg — or pip install 'cutagent[ffmpeg]' to bundle everything
  • Content intelligence: Scene detection, silence detection, audio levels, keyframe analysis, beat detection
  • Professional operations: Trim, split, concat, reorder, extract, fade with crossfade transitions
  • Audio-aware editing: Mix background music, adjust volume, replace audio, normalize loudness (EBU R128)
  • Structured errors: Error codes, recovery hints, and context in every failure response

Requirements

  • Python 3.10+
  • FFmpeg and FFprobe (see setup options below)

Installation

pip install cutagent

With bundled FFmpeg (no separate install needed):

pip install 'cutagent[ffmpeg]'

This uses static-ffmpeg to auto-download ffmpeg + ffprobe binaries on first use. Works on Windows, macOS (Intel + Apple Silicon), and Linux.

From source (development):

git clone https://github.com/DaKev/cutagent.git
cd cutagent
pip install -e ".[dev]"

FFmpeg Setup

CutAgent needs ffmpeg and ffprobe. It searches for them in this order:

  1. Environment variables CUTAGENT_FFMPEG / CUTAGENT_FFPROBE (exact path to binary)
  2. Environment variable CUTAGENT_FFMPEG_DIR (directory containing both binaries)
  3. System PATH (ffmpeg / ffprobe on $PATH)
  4. static-ffmpeg package (if installed via pip install 'cutagent[ffmpeg]')
  5. imageio-ffmpeg package (ffmpeg only, if installed)

Platform-specific install (if not using cutagent[ffmpeg]):

Platform Command
macOS brew install ffmpeg
Ubuntu/Debian sudo apt install ffmpeg
Windows winget install ffmpeg or choco install ffmpeg

Verify your setup:

cutagent doctor

This checks for ffmpeg/ffprobe, reports versions, and flags any issues.

Quick Start

Python API

from cutagent import probe, trim, execute_edl

# Inspect a video
info = probe("interview.mp4")
print(info.duration, info.width, info.height)

# Trim a segment
result = trim("interview.mp4", start="00:02:15", end="00:05:40", output="clip.mp4")

# Execute a full edit decision list
edl = {
    "version": "1.0",
    "inputs": ["interview.mp4"],
    "operations": [
        {"op": "trim", "source": "interview.mp4", "start": "00:02:15", "end": "00:05:40"},
        {"op": "trim", "source": "interview.mp4", "start": "00:12:00", "end": "00:14:30"},
        {"op": "concat", "segments": ["$0", "$1"]}
    ],
    "output": {"path": "highlight.mp4", "codec": "copy"}
}
result = execute_edl(edl)

CLI (AI-Native — all output is JSON)

# Discover capabilities (returns machine-readable schema)
cutagent capabilities

# Probe a video
cutagent probe interview.mp4

# Get keyframe positions
cutagent keyframes interview.mp4

# Detect scene boundaries
cutagent scenes interview.mp4 --threshold 0.3

# Build a full content summary (scenes + silence + audio levels)
cutagent summarize interview.mp4

# Trim
cutagent trim interview.mp4 --start 00:02:15 --end 00:05:40 -o clip.mp4

# Split at multiple points
cutagent split interview.mp4 --at 00:05:00,00:10:00 --prefix segment

# Concatenate
cutagent concat clip1.mp4 clip2.mp4 -o merged.mp4

# Extract audio
cutagent extract interview.mp4 --stream audio -o audio.aac

# Detect musical beats (for rhythm-aligned cuts)
cutagent beats interview.mp4

# Mix background music into a video
cutagent mix interview.mp4 --audio music.mp3 --mix-level 0.2 -o with_music.mp4

# Adjust audio volume
cutagent volume interview.mp4 --gain-db 6.0 -o louder.mp4

# Replace audio track
cutagent replace-audio interview.mp4 --audio voiceover.mp3 -o replaced.mp4

# Normalize audio loudness (EBU R128)
cutagent normalize interview.mp4 -o normalized.mp4

# Validate an EDL without executing
cutagent validate edit.json

# Execute an EDL
cutagent execute edit.json

EDL Format

The Edit Decision List is a declarative JSON format for multi-step edits. Operations run sequentially; $N references the output of operation N:

{
  "version": "1.0",
  "inputs": ["interview.mp4", "broll.mp4", "background_music.mp3"],
  "operations": [
    {"op": "trim", "source": "$input.0", "start": "00:01:00", "end": "00:03:00"},
    {"op": "trim", "source": "$input.1", "start": "00:00:10", "end": "00:00:20"},
    {"op": "normalize", "source": "$0"},
    {"op": "fade", "source": "$1", "fade_in": 0.5, "fade_out": 0.5},
    {"op": "concat", "segments": ["$2", "$3"], "transition": "crossfade", "transition_duration": 0.5},
    {"op": "mix_audio", "source": "$4", "audio": "$input.2", "mix_level": 0.15}
  ],
  "output": {"path": "final.mp4", "codec": "libx264"}
}

Available operations: trim, split, concat, reorder, extract, fade, speed, mix_audio, volume, replace_audio, normalize

Architecture

┌──────────────────────────────────────────────────────────────────┐
│                     cutagent (CLI / Python API)                  │
├──────────────────┬─────────────────┬─────────────────────────────┤
│  cli.py          │  engine.py      │  validation.py              │
│  JSON output     │  EDL execution  │  Dry-run validation         │
├──────────────────┼─────────────────┼─────────────────────────────┤
│  probe.py        │  operations.py  │  models.py                  │
│  Media analysis  │  Video ops      │  Typed dataclasses          │
│  + beat detect   │  audio_ops.py   │                             │
│                  │  Audio ops      │                             │
├──────────────────┴─────────────────┴─────────────────────────────┤
│  ffmpeg.py  (subprocess wrappers)  │  errors.py  (error codes)   │
└──────────────────────────────────────────────────────────────────┘
  • ffmpeg.py is the only module that spawns subprocesses
  • models.py and errors.py have zero internal dependencies
  • All public functions return typed dataclasses, never raw dicts
  • The CLI outputs JSON exclusively — designed for machine consumption

Exit Codes

Code Meaning
0 Success
1 Validation error (bad input, invalid EDL)
2 Execution error (FFmpeg failed)
3 System error (FFmpeg not found, permissions)

Error Handling

Every error includes a code, message, and recovery suggestions:

{
  "error": true,
  "code": "TRIM_BEYOND_DURATION",
  "message": "End time 01:00:00 (3600.000s) exceeds duration (120.500s)",
  "recovery": [
    "Source duration is 120.500s — set end to 120.500 or less",
    "Run 'cutagent probe <file>' to check the actual duration"
  ],
  "context": {"source": "clip.mp4", "duration": 120.5, "end": "01:00:00"}
}

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines on:

  • Setting up the development environment
  • Architecture principles and code style
  • Adding new operations
  • The JSON output contract

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cutagent-0.2.0.tar.gz (63.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cutagent-0.2.0-py3-none-any.whl (53.2 kB view details)

Uploaded Python 3

File details

Details for the file cutagent-0.2.0.tar.gz.

File metadata

  • Download URL: cutagent-0.2.0.tar.gz
  • Upload date:
  • Size: 63.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cutagent-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f463b383d991956030570db1f6b2b787c1b88f7aa04041d36e0b0ea80e8061f9
MD5 235fc85c113f9711cff7053c7c84c7da
BLAKE2b-256 fb3821adf89a6c49e2e7aefa4483f8e15dbb9846f40baabcb7750170374e0807

See more details on using hashes here.

Provenance

The following attestation bundles were made for cutagent-0.2.0.tar.gz:

Publisher: publish.yml on DaKev/cutagent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cutagent-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: cutagent-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 53.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cutagent-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 192ef16accf2782cef002adce8131adcd1b04ac178b3cee9adc41c65f40a39b2
MD5 c5fa56d1a5662ec475eff8007cdf7969
BLAKE2b-256 02259328d3fa823f315fb52382ce191259f7f28905b76554f02700e9f54fa37a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cutagent-0.2.0-py3-none-any.whl:

Publisher: publish.yml on DaKev/cutagent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page