videotrim


Namevideotrim JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
SummaryA fast, efficient video trimming and manipulation toolkit
upload_time2025-10-13 21:53:32
maintainerNone
docs_urlNone
authorTalmo Pereira
requires_python>=3.12
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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)

```bash
# 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

```bash
# 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

```bash
# Using pip
pip install videotrim

# Or using uv
uv pip install videotrim
```

### Install from Source

```bash
# 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

```bash
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

```bash
# 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

```bash
# 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

```bash
# 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

```python
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

```python
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

```python
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

```python
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

```python
from videotrim import concatenate_videos, TrimMode

# Concatenate multiple videos
concatenate_videos(
    ["part1.mp4", "part2.mp4", "part3.mp4"],
    "full.mp4",
    mode=TrimMode.COPY
)
```

### Utility functions

```python
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

```bash
# 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

```bash
# 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

```bash
# 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.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "videotrim",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": null,
    "author": "Talmo Pereira",
    "author_email": "Talmo Pereira <talmo@talmolab.org>",
    "download_url": "https://files.pythonhosted.org/packages/e1/20/a4b16604222806a219b950d61be6c6c602d15bf9aa3f9daf002f3901aa5e/videotrim-0.2.0.tar.gz",
    "platform": null,
    "description": "# videotrim\n\nA fast, efficient video trimming and manipulation toolkit built on Python.\n\n## Features\n\n- **Fast Video I/O**: Efficient video reading and writing with `imageio` and PyAV backends\n- **Frame-Accurate Trimming**: Precise frame-level control with re-encoding support\n- **Lossless Copy Mode**: Ultra-fast trimming using ffmpeg's copy mode (when frame accuracy isn't critical)\n- **Auto Start Detection**: Automatically detect when video content begins using motion-based detection (perfect for removing \"hand at start\" frames)\n- **Frame Extraction**: Export individual frames as images\n- **Video Concatenation**: Merge multiple videos into one\n- **Flexible CLI**: Powerful command-line interface with timestamp and frame-based operations\n- **Python API**: Full-featured library for programmatic video manipulation\n\n## Quick Start\n\n### Run without installation (using uv)\n\n```bash\n# Install uv if you haven't already\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Run videotrim directly\nuvx videotrim --help\n\n# Trim a video (frames 100-500)\nuvx videotrim trim input.mp4 output.mp4 --start 100 --end 500\n\n# Trim by timestamps\nuvx videotrim trim input.mp4 output.mp4 --start-time 00:10 --end-time 00:30\n```\n\n### Install as a tool\n\n```bash\n# Install videotrim as a tool\nuv tool install videotrim\n\n# Run directly\nvideotrim --help\nvideotrim info input.mp4\nvideotrim trim input.mp4 output.mp4 -s 100 -e 500\n\n# Update to latest version\nuv tool upgrade videotrim\n```\n\n## Installation\n\n### Install from PyPI\n\n```bash\n# Using pip\npip install videotrim\n\n# Or using uv\nuv pip install videotrim\n```\n\n### Install from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/talmolab/videotrim.git\ncd videotrim\n\n# Install with uv\nuv pip install -e .\n\n# Or with dev dependencies\nuv pip install -e \".[dev]\"\n```\n\n## Command Line Usage\n\n### Get video information\n\n```bash\nvideotrim info input.mp4\n```\n\nOutput:\n```\nFile: input.mp4\nSize: 1,234,567 bytes\nDuration: 00:01:23.456\nFPS: 30.00\nFrames: 2,504\nResolution: 1920x1080\nCodec: h264\n```\n\n### Trim videos\n\n```bash\n# Trim by frame range (frame-accurate with re-encoding)\nvideotrim trim input.mp4 output.mp4 --start 100 --end 500\n\n# Trim by timestamps (skip first 30 seconds, save next 5 seconds)\nvideotrim trim input.mp4 output.mp4 --start-time 00:30 --end-time 00:35 --mode encode\n\n# Trim by timestamps with shorthand\nvideotrim trim input.mp4 output.mp4 --start-time 00:10 --end-time 00:30\n\n# Fast copy mode (no re-encoding, may not be frame-accurate)\nvideotrim trim input.mp4 output.mp4 -s 100 -e 500 --mode copy\n\n# High quality encode\nvideotrim trim input.mp4 output.mp4 -s 100 -e 500 --mode encode --quality 10\n\n# Auto mode (automatically choose copy or encode)\nvideotrim trim input.mp4 output.mp4 -s 100 -e 500 --mode auto\n\n# Auto-detect start frame (removes \"hand at start\" frames)\nvideotrim trim input.mp4 output.mp4 --auto-detect-start --end 1000\n\n# Auto-detect with verbose output to see detection process\nvideotrim trim input.mp4 output.mp4 -a -e 1000 -v\n\n# Auto-detect with custom parameters for fine-tuning\nvideotrim trim input.mp4 output.mp4 -a --detect-coarse-samples 15 --detect-downsample 2\n```\n\n### Extract frames\n\n```bash\n# Extract all frames as PNG\nvideotrim extract input.mp4 frames/\n\n# Extract specific range\nvideotrim extract input.mp4 frames/ --start 100 --end 500\n\n# Extract every 10th frame\nvideotrim extract input.mp4 frames/ --step 10\n\n# Extract as JPEG with custom prefix\nvideotrim extract input.mp4 frames/ --format jpg --prefix frame_\n```\n\n### Concatenate videos\n\n```bash\n# Fast concatenation (copy mode)\nvideotrim concat output.mp4 part1.mp4 part2.mp4 part3.mp4\n\n# With re-encoding for compatibility\nvideotrim concat output.mp4 part1.mp4 part2.mp4 --mode encode\n```\n\n## Python API\n\n### Basic trimming\n\n```python\nfrom videotrim import trim_video, TrimMode\n\n# Trim with frame-accurate encoding\ntrim_video(\n    \"input.mp4\",\n    \"output.mp4\",\n    start_frame=100,\n    end_frame=500,\n    mode=TrimMode.ENCODE\n)\n\n# Fast copy mode\ntrim_video(\n    \"input.mp4\",\n    \"output.mp4\",\n    start_frame=100,\n    end_frame=500,\n    mode=TrimMode.COPY\n)\n\n# Auto-detect start frame (removes \"hand at start\" frames)\ntrim_video(\n    \"input.mp4\",\n    \"output.mp4\",\n    auto_detect_start=True,\n    end_frame=1000\n)\n\n# Auto-detect with custom parameters\ntrim_video(\n    \"input.mp4\",\n    \"output.mp4\",\n    auto_detect_start=True,\n    end_frame=1000,\n    auto_detect_params={\n        'coarse_samples': 15,\n        'downsample_factor': 2,\n        'verbose': True\n    }\n)\n```\n\n### Start frame detection\n\n```python\nfrom videotrim import detect_start_frame\n\n# Detect where video content actually starts\nstart_frame = detect_start_frame(\"input.mp4\")\nprint(f\"Content starts at frame {start_frame}\")\n\n# With verbose output to see detection process\nstart_frame = detect_start_frame(\"input.mp4\", verbose=True)\n\n# With custom parameters for fine-tuning\nstart_frame = detect_start_frame(\n    \"input.mp4\",\n    coarse_samples=15,              # More initial samples\n    downsample_factor=2,             # Less aggressive downsampling\n    binary_search_samples_per_iteration=7,  # More samples per iteration\n    final_window_size=5              # Smaller final window\n)\n```\n\n### Video I/O\n\n```python\nfrom videotrim import VideoReader, VideoWriter\n\n# Read video\nwith VideoReader(\"input.mp4\") as reader:\n    print(f\"FPS: {reader.fps}\")\n    print(f\"Frames: {reader.frame_count}\")\n    print(f\"Resolution: {reader.width}x{reader.height}\")\n\n    # Read specific frame\n    frame = reader.read_frame(42)\n\n    # Read frame range\n    frames = reader.read_frames(100, 200)\n\n    # Iterate through all frames\n    for frame in reader:\n        process_frame(frame)\n\n# Write video\nwith VideoWriter(\"output.mp4\", fps=30.0, quality=8) as writer:\n    for frame in frames:\n        writer.write_frame(frame)\n```\n\n### Frame extraction\n\n```python\nfrom videotrim import extract_frames\n\n# Extract all frames\nnum_frames = extract_frames(\"input.mp4\", \"frames/\")\n\n# Extract every 10th frame\nnum_frames = extract_frames(\n    \"input.mp4\",\n    \"frames/\",\n    step=10,\n    format=\"png\"\n)\n```\n\n### Video concatenation\n\n```python\nfrom videotrim import concatenate_videos, TrimMode\n\n# Concatenate multiple videos\nconcatenate_videos(\n    [\"part1.mp4\", \"part2.mp4\", \"part3.mp4\"],\n    \"full.mp4\",\n    mode=TrimMode.COPY\n)\n```\n\n### Utility functions\n\n```python\nfrom videotrim.utils import (\n    get_video_info,\n    frame_to_timestamp,\n    timestamp_to_frame,\n    parse_time_string,\n    format_timestamp\n)\n\n# Get video metadata\ninfo = get_video_info(\"input.mp4\")\nprint(info)\n\n# Convert between frames and timestamps\ntimestamp = frame_to_timestamp(150, fps=30.0)  # 5.0 seconds\nframe = timestamp_to_frame(5.0, fps=30.0)  # 150\n\n# Parse time strings\nseconds = parse_time_string(\"01:23:45.5\")  # 5025.5\n\n# Format timestamps\ntime_str = format_timestamp(5025.5)  # \"01:23:45.500\"\n```\n\n## Development\n\n### Running from Source\n\n```bash\n# Clone and enter directory\ngit clone https://github.com/talmolab/videotrim.git\ncd videotrim\n\n# Install in development mode with dev dependencies\nuv pip install -e \".[dev]\"\n\n# Run the CLI\npython -m videotrim --help\nvideotrim --help  # After installation\n```\n\n### Running Tests\n\n```bash\n# Install dev dependencies if not already installed\nuv pip install -e \".[dev]\"\n\n# Run tests\npytest\n\n# Run with coverage\npytest --cov=videotrim --cov-report=html\n\n# Run specific test file\npytest tests/test_io.py\n\n# Run with verbose output\npytest -v\n```\n\n### Code Quality\n\n```bash\n# Format and lint with ruff\nruff check src/ tests/\nruff format src/ tests/\n\n# Auto-fix issues\nruff check --fix src/ tests/\n```\n\n## Requirements\n\n- Python \u2265 3.12\n- numpy\n- imageio\n- imageio-ffmpeg\n- av (PyAV)\n- opencv-python\n- click\n\nOptional:\n- ffmpeg (for fast copy mode trimming and concatenation)\n\n## Architecture\n\nvideotrim is built with a modular architecture:\n\n- **`videotrim.io`**: Core video I/O with `VideoReader` and `VideoWriter` classes\n- **`videotrim.trim`**: Trimming operations with multiple modes (copy/encode/auto)\n- **`videotrim.detection`**: Motion-based start frame detection using hierarchical search\n- **`videotrim.utils`**: Utility functions for time/frame conversions and validation\n- **`videotrim.cli`**: Command-line interface built with Click\n\nThe library uses `imageio` with PyAV backend for frame-accurate video operations, and optionally uses `ffmpeg` directly for ultra-fast copy mode operations.\n\n### Auto Start Detection\n\nThe motion-based start detection feature uses a hierarchical approach:\n1. **Phase 1 - Coarse Sampling**: Sample frames uniformly across the video\n2. **Phase 2 - Region Identification**: Find the region with highest motion change\n3. **Phase 3 - Binary Search**: Refine detection within that region\n\nThis 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.\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A fast, efficient video trimming and manipulation toolkit",
    "version": "0.2.0",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "4d9330d5d9382784a930b3b623d01442644766be6f55649516214b7c2be242e3",
                "md5": "a9b79e5ecd5b85765d435f4d1aae500e",
                "sha256": "70453dd1cb1e35711affbb269ef2205c44e977a56708decc39e04ed128b68c63"
            },
            "downloads": -1,
            "filename": "videotrim-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a9b79e5ecd5b85765d435f4d1aae500e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 19189,
            "upload_time": "2025-10-13T21:53:30",
            "upload_time_iso_8601": "2025-10-13T21:53:30.818374Z",
            "url": "https://files.pythonhosted.org/packages/4d/93/30d5d9382784a930b3b623d01442644766be6f55649516214b7c2be242e3/videotrim-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e120a4b16604222806a219b950d61be6c6c602d15bf9aa3f9daf002f3901aa5e",
                "md5": "a10fafdaf289491140f03317f635c1ee",
                "sha256": "229bccc88eb32cf6fcbe087e337d64cda7fe2dcaae81f761f0dcaf33b950f161"
            },
            "downloads": -1,
            "filename": "videotrim-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a10fafdaf289491140f03317f635c1ee",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 15391,
            "upload_time": "2025-10-13T21:53:32",
            "upload_time_iso_8601": "2025-10-13T21:53:32.350229Z",
            "url": "https://files.pythonhosted.org/packages/e1/20/a4b16604222806a219b950d61be6c6c602d15bf9aa3f9daf002f3901aa5e/videotrim-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-13 21:53:32",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "videotrim"
}
        
Elapsed time: 2.03139s