videopython
Minimal, LLM-friendly Python library for programmatic video editing, processing, and AI video workflows.
Full documentation: videopython.com
Disclaimer: This project started as a hand-written hobby project, but most of the code is now produced by LLM agents. Humans still drive direction, approve changes, and own design decisions.
Installation
# Install FFmpeg first (macOS: brew install ffmpeg | Debian: apt-get install ffmpeg)
pip install videopython # core video/audio editing
pip install "videopython[ai]" # + ALL local AI features (GPU recommended)
pip install "videopython[ai,mcp]" # + MCP server for agent-driven editing
Python >=3.11, <3.14. AI features run locally — no cloud API keys required, but model weights are downloaded on first use. LLM-driven editing and scene captioning use a local Ollama server (ollama pull qwen3.6:27b). See the install guide for FFmpeg, Ollama, and hardware details.
Quick start
An edit is a plan — a dict (or JSON) validated and executed against the source files:
from videopython.editing import VideoEdit
edit = VideoEdit.from_dict({
"segments": [{
"source": "raw.mp4",
"start": 10.0,
"end": 20.0,
"operations": [
{"op": "resize", "width": 1080, "height": 1920},
{"op": "color_adjust", "saturation": 1.15, "contrast": 1.05},
{"op": "fade", "mode": "in", "duration": 0.5},
],
}],
})
edit.validate() # dry-run via metadata, no frames loaded
edit.run_to_file("output.mp4") # streams ffmpeg decode → effects → encode
run_to_file() streams, so memory stays bounded even for hour-long sources. Walk through it in Tutorial 1.
Automatic editing (local LLM)
Give AutoEditor your clips and a brief; a local Ollama vision model selects and orders the shots, and you get back a runnable VideoEdit:
from videopython.ai import AutoEditor, OllamaVisionLLM
editor = AutoEditor(planner=OllamaVisionLLM(model="qwen3.6:27b")) # ollama pull qwen3.6:27b
edit = editor.edit(
["clip_a.mp4", "clip_b.mp4", "clip_c.mp4"],
brief="A punchy 15-second teaser; lead with the most dynamic shot.",
)
edit.run_to_file("teaser.mp4")
The model picks scenes by id from a catalog built from scene detection + captions, so its temporal imprecision never reaches the render. See Let a local LLM edit for you.
AI generation
from videopython.ai import TextToImage, ImageToVideo, TextToSpeech
image = TextToImage().generate_image("A cinematic mountain sunrise")
video = ImageToVideo().generate_video(image=image)
audio = TextToSpeech().generate_audio("Welcome to videopython.")
video.add_audio(audio).save("ai_video.mp4")
LLM & AI agent integration
Putting an LLM in the loop works three ways, differing in who owns the model:
- Bring your own LLM — videopython gives your model the JSON Schema and a structured refine loop; your model authors the plans. Guide
AutoEditor— a local Ollama vision model is the planner. Guide- MCP server —
videopython-mcpexposes the pipeline as Model Context Protocol tools, so an agent like Claude drives editing with its own model. Guide
Mode 1 in brief: every operation is a Pydantic model whose fields are the JSON wire format, so VideoEdit.json_schema() hands your model a ready-made tool schema — a discriminated union over every LLM-exposed op (pass strict=True for provider grammar modes). Plans parse permissively and own their numeric bounds at validation, so a refine loop converges fast:
edit.check(meta)— collect every structured error in one pass, not just the firstedit.repair(meta)— auto-clamp mechanical violations (overruns, negatives) with a changelogedit.normalize_dimensions(meta, target)— make heterogeneous segments concat-compatible
Why it is built this way: LLM-first design.
Features
videopython.base—Video,VideoMetadata,FrameIterator,Transcription, and shared result types (BoundingBox,FaceTrack,SceneBoundary, ...). No AI dependencies.videopython.audio—Audiowith overlay, concat, normalize, time-stretch, silence detection, segment classification.videopython.editing—Operation/Effectfoundation,VideoEditplan runner with JSON Schema + streaming execution. Transforms (resize, crop, fps, speed, freeze, silence removal; cutting is the segment's own start/end) and effects (blur, zoom, color grading, vignette, Ken Burns, fade, overlays, animated subtitles).videopython.ai(install with[ai]) — generation (TextToVideo,ImageToVideo,TextToImage,TextToSpeech,TextToMusic), understanding (AudioToText,AudioClassifier,SceneVLM,FaceTracker,ObjectDetector,SemanticSceneDetector), theFaceTrackingCroptransform, theObjectDetectionOverlayeffect, and the full-pipelineVideoAnalyzer. Scene captioning and dubbing translation run on a local Ollama model.videopython.ai.auto_edit—AutoEditor+OllamaVisionLLM: plan and render an edit from sources + a one-line brief.videopython.ai.dubbing—VideoDubberfor voice-cloned revoicing with timing sync.videopython.mcp(install with[ai,mcp]) —videopython-mcp, an MCP stdio server exposing the auto-edit pipeline so an agent drives editing.
Documentation
The docs follow Diátaxis: four sections, each answering a different kind of question.
| Tutorials | Learn by doing — start here if you are new |
| How-to guides | Recipes for a specific goal |
| Reference | Classes, operations, parameters, wire format |
| Explanation | Why the library is shaped the way it is |
Development
See DEVELOPMENT.md for local setup, testing, docs, and the release workflow.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file videopython-0.55.1.tar.gz.
File metadata
- Download URL: videopython-0.55.1.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
145f2b49eda06497845da22ba8c2cc3714f28eef0e377157d34e81128376816b
|
|
| MD5 |
beaf0b5e7b1268fe115e1b084cc00121
|
|
| BLAKE2b-256 |
2a061dcfc3dee4f2d62b3113c490d09af168df13c9e6111f7520771f8d423181
|
Provenance
The following attestation bundles were made for videopython-0.55.1.tar.gz:
Publisher:
publish.yml on BartWojtowicz/videopython
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
videopython-0.55.1.tar.gz -
Subject digest:
145f2b49eda06497845da22ba8c2cc3714f28eef0e377157d34e81128376816b - Sigstore transparency entry: 2588913620
- Sigstore integration time:
-
Permalink:
BartWojtowicz/videopython@b40bed2331cfc056c6968465ae56da4985e499dd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BartWojtowicz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b40bed2331cfc056c6968465ae56da4985e499dd -
Trigger Event:
push
-
Statement type:
File details
Details for the file videopython-0.55.1-py3-none-any.whl.
File metadata
- Download URL: videopython-0.55.1-py3-none-any.whl
- Upload date:
- Size: 1.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
706c0f110b48921009a8718ca3f5153af00383f856aca60e82f80cdf2eaf023c
|
|
| MD5 |
a84d106c3b0dcf710c34a14ba9c8a1e7
|
|
| BLAKE2b-256 |
9dba06cfb65c3cd7c68d484fdf91d53e871bcdc4c965c21bbb4d66b70f721d02
|
Provenance
The following attestation bundles were made for videopython-0.55.1-py3-none-any.whl:
Publisher:
publish.yml on BartWojtowicz/videopython
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
videopython-0.55.1-py3-none-any.whl -
Subject digest:
706c0f110b48921009a8718ca3f5153af00383f856aca60e82f80cdf2eaf023c - Sigstore transparency entry: 2588914178
- Sigstore integration time:
-
Permalink:
BartWojtowicz/videopython@b40bed2331cfc056c6968465ae56da4985e499dd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BartWojtowicz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b40bed2331cfc056c6968465ae56da4985e499dd -
Trigger Event:
push
-
Statement type: