Skip to main content

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 imageio and 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 with VideoReader and VideoWriter classes
  • videotrim.trim: Trimming operations with multiple modes (copy/encode/auto)
  • videotrim.detection: Motion-based start frame detection using hierarchical search
  • videotrim.utils: Utility functions for time/frame conversions and validation
  • videotrim.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:

  1. Phase 1 - Coarse Sampling: Sample frames uniformly across the video
  2. Phase 2 - Region Identification: Find the region with highest motion change
  3. 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


Download files

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

Source Distribution

videotrim-0.2.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

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

videotrim-0.2.0-py3-none-any.whl (19.2 kB view details)

Uploaded Python 3

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

Hashes for videotrim-0.2.0.tar.gz
Algorithm Hash digest
SHA256 229bccc88eb32cf6fcbe087e337d64cda7fe2dcaae81f761f0dcaf33b950f161
MD5 a10fafdaf289491140f03317f635c1ee
BLAKE2b-256 e120a4b16604222806a219b950d61be6c6c602d15bf9aa3f9daf002f3901aa5e

See more details on using hashes here.

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

Hashes for videotrim-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 70453dd1cb1e35711affbb269ef2205c44e977a56708decc39e04ed128b68c63
MD5 a9b79e5ecd5b85765d435f4d1aae500e
BLAKE2b-256 4d9330d5d9382784a930b3b623d01442644766be6f55649516214b7c2be242e3

See more details on using hashes here.

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