Automatically detect TV show intros and end credits using audio fingerprinting.
This project provides a Python command line tool that identifies recurring intro and credits segments across video files. It enables features similar to “Skip Intro” and “Skip Credits” found in platforms like Plex or Jellyfin.
The system leverages:
- Chromaprint (fpcalc) for audio fingerprint generation
- FFmpeg / ffprobe for audio extraction and duration detection
- A sliding window similarity algorithm for robust matching
It is resilient to compression differences, small timing offsets, and minor audio quality variations.
- 🔎 Detect shared intro sequences
- 🎞 Detect recurring end credits
- 📂 Compare one source file against multiple targets
- 📁 Automatically analyze all
.mp4files in a folder - ⚙ Fully customizable detection parameters
- 📦 Structured JSON output for easy integration
- Python 3.10+
numpy
Install dependency:
pip install numpyRequired for audio extraction and duration detection.
Install:
Ubuntu/Debian
sudo apt install ffmpegmacOS
brew install ffmpegWindows Download from https://www.gyan.dev/ffmpeg/builds/ and add to PATH.
Verify installation:
ffmpeg -version
ffprobe -versionUsed for generating audio fingerprints.
Install:
Ubuntu/Debian
sudo apt install libchromaprint-toolsmacOS
brew install chromaprintWindows
Download from https://acoustid.org/chromaprint and add fpcalc to PATH.
Verify:
fpcalc -versiongit clone https://github.com/cvija1/skip-intro-credits.git
cd skip-intro-credits
pip install numpyEnsure ffmpeg, ffprobe, and fpcalc are accessible from your terminal.
Basic command:
python main.py source_video.mp4 target1.mp4 target2.mp4| Argument | Description |
|---|---|
source |
Reference video file |
targets |
One or more target files to compare |
--folder PATH |
Analyze all .mp4 files in folder |
--begin |
Analyze only intros |
--end |
Analyze only credits |
python main.py thrones-01.mp4 thrones-02.mp4 thrones-03.mp4python main.py thrones-01.mp4 --folder "/path/to/episodes" --beginpython main.py thrones-01.mp4 thrones-02.mp4 --endThe script prints detailed match information during execution and outputs a final JSON summary:
[
{
"source_file": "thrones-01.mp4",
"target_file": "thrones-02.mp4",
"intro_start": null,
"intro_end": 32,
"credits_start": 1282,
"credits_end": 1299
},
{
"source_file": "thrones-01.mp4",
"target_file": "thrones-03.mp4",
"intro_start": null,
"intro_end": 33,
"credits_start": 1285,
"credits_end": 1300
}
]- All intervals are expressed in seconds
nullindicates:- Intro starting at 0
- Credits ending too close to total duration
- If all fields are null then there is no matching
- Intro detection fingerprints the beginning directly
- Credits detection extracts the final N seconds using FFmpeg
Chromaprint generates a numeric signature representing the audio.
- Source fingerprint is divided into windows (e.g. 6 seconds)
- Each window slides across the target fingerprint
- Best alignment above similarity threshold is recorded
Results are structured per target for integration into:
- Media servers
- Databases
- Automation pipelines
Edit these parameters at the top of the script:
SAMPLE_LENGTH_SEC = 300
WINDOW_SEC = 6
STEP_SEC = 1
MIN_SIMILARITY = 0.82
MIN_OVERLAP_POINTS = 8
MAX_WORKERS = 4To adjust merging tolerance, modify the merge offset inside merge_overlapping_intervals.
- Command-line only (no GUI)
- Performance scales with:
- Sample length
- Number of target files
- Optimized for
.mp4(extend logic for other formats if needed)
Pull requests are welcome.
If you have feature ideas, improvements, or bug reports, open an issue.
MIT License.
- Chromaprint
- FFmpeg
Inspired by open-source