Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

talmo/videotrim

Repository files navigation

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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages