speedrun

Automatically detect and remove freeze/low-motion regions from videos using ffmpeg.

Description

speedrun analyzes videos for frozen or low-motion segments (using ffmpeg's freezedetect filter) and removes them, stitching together only the active parts. Perfect for cleaning up screen recordings, presentation videos, or any footage with long static periods.

Installation

Install the gem:

gem install speedrun

Or add to your Gemfile:

gem 'speedrun'

Requirements

  • Ruby >= 3.2.0
  • ffmpeg (with freezedetect filter support)
  • ffprobe

Install ffmpeg via your package manager:

# macOS
brew install ffmpeg

# Ubuntu/Debian
apt-get install ffmpeg

# Arch Linux
pacman -S ffmpeg

Usage

Basic usage:

speedrun trim input.mp4

This creates input-trimmed.mp4 with frozen segments removed.

Options

speedrun trim INPUT [OUTPUT] [options]

Options:
  -n, --noise THRESHOLD        # Noise tolerance in dB (default: -70)
  -d, --duration SECONDS       # Minimum freeze duration in seconds (default: 1.0)
  --dry-run                    # Preview without processing
  -q, --quiet                  # Minimal output

Examples:
  speedrun trim video.mp4                                    # Creates video-trimmed.mp4
  speedrun trim video.mp4 output.mp4                         # Custom output name
  speedrun trim video.mp4 --noise -60                        # More sensitive detection
  speedrun trim video.mp4 --duration 2.0                     # Only remove freezes >= 2s
  speedrun trim video.mp4 --dry-run                          # Preview analysis only

Understanding the Noise Threshold

The --noise parameter controls how sensitive freeze detection is to small changes in the video:

  • Less negative values (like -60 dB) = More sensitive Detects freezes even when there's subtle motion or slight changes Use when you want to catch nearly-static sections

  • More negative values (like -80 dB) = Less sensitive Only detects freezes when frames are nearly identical Use when you want to preserve sections with minimal motion

The default of -70 dB works well for most screen recordings. If you're getting false positives (motion incorrectly flagged as frozen), try -80 dB. If freezes are being missed, try -60 dB.

Other Commands

speedrun version                   # Show version
speedrun help                      # Show help

How It Works

  1. Detect: Uses ffmpeg's freezedetect filter to find frozen/low-motion segments
  2. Analyze: Calculates which portions to keep vs. remove
  3. Extract: Extracts active segments using ffmpeg
  4. Stitch: Concatenates segments into final output

Development

After checking out the repo:

bin/setup                      # Install dependencies
bundle exec rake test          # Run test suite
bundle exec guard              # Auto-run tests on file changes

Testing

The codebase follows strict TDD with 100% test coverage. All ffmpeg calls are mocked for fast, isolated testing.

bundle exec rake test          # Run full test suite

Test Structure

  • Unit tests: All components tested in isolation with mocks
  • Integration tests: Full workflow with mocked FFmpeg
  • Fixtures: Sample ffmpeg/ffprobe outputs for realistic testing

Architecture

lib/speedrun/
├── version.rb        # Version constant
├── formatter.rb      # Time/duration/filesize formatters
├── ffmpeg.rb         # FFmpeg command wrappers & parsers
├── trimmer.rb        # Core video processing logic
└── cli.rb            # Thor-based CLI interface

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/benjaminjackson/speedrun.

License

The gem is available as open source under the terms of the MIT License.