A fast, efficient video trimming and manipulation toolkit
Project description
videotrim
A fast, efficient video trimming and manipulation toolkit built on Python.
Features
- Fast Video I/O: Efficient video reading and writing with
imageioand PyAV backends - Frame-Accurate Trimming: Precise frame-level control with re-encoding support
- Lossless Copy Mode: Ultra-fast trimming using ffmpeg's copy mode (when frame accuracy isn't critical)
- Auto Start Detection: Automatically detect when video content begins using motion-based detection (perfect for removing "hand at start" frames)
- Frame Extraction: Export individual frames as images
- Video Concatenation: Merge multiple videos into one
- Flexible CLI: Powerful command-line interface with timestamp and frame-based operations
- Python API: Full-featured library for programmatic video manipulation
Quick Start
Run without installation (using uv)
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Run videotrim directly
uvx videotrim --help
# Trim a video (frames 100-500)
uvx videotrim trim input.mp4 output.mp4 --start 100 --end 500
# Trim by timestamps
uvx videotrim trim input.mp4 output.mp4 --start-time 00:10 --end-time 00:30
Install as a tool
# Install videotrim as a tool
uv tool install videotrim
# Run directly
videotrim --help
videotrim info input.mp4
videotrim trim input.mp4 output.mp4 -s 100 -e 500
# Update to latest version
uv tool upgrade videotrim
Installation
Install from PyPI
# Using pip
pip install videotrim
# Or using uv
uv pip install videotrim
Install from Source
# Clone the repository
git clone https://github.com/talmolab/videotrim.git
cd videotrim
# Install with uv
uv pip install -e .
# Or with dev dependencies
uv pip install -e ".[dev]"
Command Line Usage
Get video information
videotrim info input.mp4
Output:
File: input.mp4
Size: 1,234,567 bytes
Duration: 00:01:23.456
FPS: 30.00
Frames: 2,504
Resolution: 1920x1080
Codec: h264
Trim videos
# Trim by frame range (frame-accurate with re-encoding)
videotrim trim input.mp4 output.mp4 --start 100 --end 500
# Trim by timestamps (skip first 30 seconds, save next 5 seconds)
videotrim trim input.mp4 output.mp4 --start-time 00:30 --end-time 00:35 --mode encode
# Trim by timestamps with shorthand
videotrim trim input.mp4 output.mp4 --start-time 00:10 --end-time 00:30
# Fast copy mode (no re-encoding, may not be frame-accurate)
videotrim trim input.mp4 output.mp4 -s 100 -e 500 --mode copy
# High quality encode
videotrim trim input.mp4 output.mp4 -s 100 -e 500 --mode encode --quality 10
# Auto mode (automatically choose copy or encode)
videotrim trim input.mp4 output.mp4 -s 100 -e 500 --mode auto
# Auto-detect start frame (removes "hand at start" frames)
videotrim trim input.mp4 output.mp4 --auto-detect-start --end 1000
# Auto-detect with verbose output to see detection process
videotrim trim input.mp4 output.mp4 -a -e 1000 -v
# Auto-detect with custom parameters for fine-tuning
videotrim trim input.mp4 output.mp4 -a --detect-coarse-samples 15 --detect-downsample 2
Extract frames
# Extract all frames as PNG
videotrim extract input.mp4 frames/
# Extract specific range
videotrim extract input.mp4 frames/ --start 100 --end 500
# Extract every 10th frame
videotrim extract input.mp4 frames/ --step 10
# Extract as JPEG with custom prefix
videotrim extract input.mp4 frames/ --format jpg --prefix frame_
Concatenate videos
# Fast concatenation (copy mode)
videotrim concat output.mp4 part1.mp4 part2.mp4 part3.mp4
# With re-encoding for compatibility
videotrim concat output.mp4 part1.mp4 part2.mp4 --mode encode
Python API
Basic trimming
from videotrim import trim_video, TrimMode
# Trim with frame-accurate encoding
trim_video(
"input.mp4",
"output.mp4",
start_frame=100,
end_frame=500,
mode=TrimMode.ENCODE
)
# Fast copy mode
trim_video(
"input.mp4",
"output.mp4",
start_frame=100,
end_frame=500,
mode=TrimMode.COPY
)
# Auto-detect start frame (removes "hand at start" frames)
trim_video(
"input.mp4",
"output.mp4",
auto_detect_start=True,
end_frame=1000
)
# Auto-detect with custom parameters
trim_video(
"input.mp4",
"output.mp4",
auto_detect_start=True,
end_frame=1000,
auto_detect_params={
'coarse_samples': 15,
'downsample_factor': 2,
'verbose': True
}
)
Start frame detection
from videotrim import detect_start_frame
# Detect where video content actually starts
start_frame = detect_start_frame("input.mp4")
print(f"Content starts at frame {start_frame}")
# With verbose output to see detection process
start_frame = detect_start_frame("input.mp4", verbose=True)
# With custom parameters for fine-tuning
start_frame = detect_start_frame(
"input.mp4",
coarse_samples=15, # More initial samples
downsample_factor=2, # Less aggressive downsampling
binary_search_samples_per_iteration=7, # More samples per iteration
final_window_size=5 # Smaller final window
)
Video I/O
from videotrim import VideoReader, VideoWriter
# Read video
with VideoReader("input.mp4") as reader:
print(f"FPS: {reader.fps}")
print(f"Frames: {reader.frame_count}")
print(f"Resolution: {reader.width}x{reader.height}")
# Read specific frame
frame = reader.read_frame(42)
# Read frame range
frames = reader.read_frames(100, 200)
# Iterate through all frames
for frame in reader:
process_frame(frame)
# Write video
with VideoWriter("output.mp4", fps=30.0, quality=8) as writer:
for frame in frames:
writer.write_frame(frame)
Frame extraction
from videotrim import extract_frames
# Extract all frames
num_frames = extract_frames("input.mp4", "frames/")
# Extract every 10th frame
num_frames = extract_frames(
"input.mp4",
"frames/",
step=10,
format="png"
)
Video concatenation
from videotrim import concatenate_videos, TrimMode
# Concatenate multiple videos
concatenate_videos(
["part1.mp4", "part2.mp4", "part3.mp4"],
"full.mp4",
mode=TrimMode.COPY
)
Utility functions
from videotrim.utils import (
get_video_info,
frame_to_timestamp,
timestamp_to_frame,
parse_time_string,
format_timestamp
)
# Get video metadata
info = get_video_info("input.mp4")
print(info)
# Convert between frames and timestamps
timestamp = frame_to_timestamp(150, fps=30.0) # 5.0 seconds
frame = timestamp_to_frame(5.0, fps=30.0) # 150
# Parse time strings
seconds = parse_time_string("01:23:45.5") # 5025.5
# Format timestamps
time_str = format_timestamp(5025.5) # "01:23:45.500"
Development
Running from Source
# Clone and enter directory
git clone https://github.com/talmolab/videotrim.git
cd videotrim
# Install in development mode with dev dependencies
uv pip install -e ".[dev]"
# Run the CLI
python -m videotrim --help
videotrim --help # After installation
Running Tests
# Install dev dependencies if not already installed
uv pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=videotrim --cov-report=html
# Run specific test file
pytest tests/test_io.py
# Run with verbose output
pytest -v
Code Quality
# Format and lint with ruff
ruff check src/ tests/
ruff format src/ tests/
# Auto-fix issues
ruff check --fix src/ tests/
Requirements
- Python ≥ 3.12
- numpy
- imageio
- imageio-ffmpeg
- av (PyAV)
- opencv-python
- click
Optional:
- ffmpeg (for fast copy mode trimming and concatenation)
Architecture
videotrim is built with a modular architecture:
videotrim.io: Core video I/O withVideoReaderandVideoWriterclassesvideotrim.trim: Trimming operations with multiple modes (copy/encode/auto)videotrim.detection: Motion-based start frame detection using hierarchical searchvideotrim.utils: Utility functions for time/frame conversions and validationvideotrim.cli: Command-line interface built with Click
The library uses imageio with PyAV backend for frame-accurate video operations, and optionally uses ffmpeg directly for ultra-fast copy mode operations.
Auto Start Detection
The motion-based start detection feature uses a hierarchical approach:
- Phase 1 - Coarse Sampling: Sample frames uniformly across the video
- Phase 2 - Region Identification: Find the region with highest motion change
- Phase 3 - Binary Search: Refine detection within that region
This approach samples only ~1-2% of frames, making it very efficient. Based on empirical testing, it achieves approximately 25 frame accuracy (typically <1 second error) for "hand at start" videos.
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
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 videotrim-0.2.0.tar.gz.
File metadata
- Download URL: videotrim-0.2.0.tar.gz
- Upload date:
- Size: 15.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.5.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
229bccc88eb32cf6fcbe087e337d64cda7fe2dcaae81f761f0dcaf33b950f161
|
|
| MD5 |
a10fafdaf289491140f03317f635c1ee
|
|
| BLAKE2b-256 |
e120a4b16604222806a219b950d61be6c6c602d15bf9aa3f9daf002f3901aa5e
|
File details
Details for the file videotrim-0.2.0-py3-none-any.whl.
File metadata
- Download URL: videotrim-0.2.0-py3-none-any.whl
- Upload date:
- Size: 19.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.5.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70453dd1cb1e35711affbb269ef2205c44e977a56708decc39e04ed128b68c63
|
|
| MD5 |
a9b79e5ecd5b85765d435f4d1aae500e
|
|
| BLAKE2b-256 |
4d9330d5d9382784a930b3b623d01442644766be6f55649516214b7c2be242e3
|