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 sectionsMore 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
- Detect: Uses ffmpeg's
freezedetectfilter to find frozen/low-motion segments - Analyze: Calculates which portions to keep vs. remove
- Extract: Extracts active segments using ffmpeg
- 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.