Segment long audio recordings into short, bounded-length speech clips ready for transcription.
Designed for speech data collection from found audio (radio shows, podcasts, field recordings) in any language. Produces a flat directory of WAV segments plus a JSON manifest — ready to hand off to linguists for transcription.
Two-stage pipeline:
-
inaSpeechSegmenter — CNN-based classifier that labels audio regions as speech (male/female), music, or noise. Filters out non-speech and provides broad speaker gender tags.
-
Silero VAD — Runs on all speech regions to split at natural pauses, enforcing a maximum segment duration. Tunable silence threshold catches micro-pauses even in fast speech.
Requires Python 3.10+ and ffmpeg.
# Create a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -r requirements.txtmacOS: brew install ffmpeg
Ubuntu/Debian: apt install ffmpeg
python segment.py recording.mp3python segment.py ./my_recordings/When processing a directory, the script walks all subdirectories for audio files. The first-level subdirectory name is used as the source_id in the manifest (useful when audio is organized by source/station/speaker).
my_recordings/
├── Station_A/
│ ├── show1.mp3
│ └── show2.mp3
└── Station_B/
└── broadcast.mp3
python segment.py INPUT [OPTIONS]
positional arguments:
INPUT Audio file or directory of audio files
options:
-o, --output-dir DIR Output directory (default: output)
--max-duration SECS Max segment duration in seconds (default: 15)
--min-duration SECS Min segment duration in seconds (default: 1.0)
--min-silence MS Min silence for split detection in ms (default: 100)
Lower values catch shorter pauses. Try 50 for fast speakers.
--speech-pad MS Padding around speech segments in ms (default: 30)
--source-id NAME Source identifier for filenames and manifest
(overrides auto-detection from directory structure)
The defaults work well for most broadcast speech. Adjust for edge cases:
| Scenario | Suggestion |
|---|---|
| Fast speaker, few pauses | --min-silence 50 --speech-pad 30 |
| Slow/deliberate speech | --min-silence 300 --speech-pad 100 |
| Want longer segments for context | --max-duration 30 |
| Want shorter segments for annotation speed | --max-duration 10 |
| Noisy recording with short speech bursts | --min-duration 2.0 to filter out noise fragments |
output/
├── manifest.json # metadata for all segments
└── audio/ # WAV files (16kHz mono)
├── Station_A__show1__0000_male_3.28-15.37.wav
├── Station_A__show1__0001_female_15.41-24.91.wav
└── ...
[
{
"file": "audio/Station_A__show1__0000_male_3.28-15.37.wav",
"label": "male",
"start": 3.28,
"stop": 15.37,
"duration": 12.09,
"source_file": "show1.mp3",
"source_id": "Station_A"
}
]| Field | Description |
|---|---|
file |
Relative path to the WAV segment |
label |
Speaker gender tag from inaSpeechSegmenter (male, female, or speech) |
start / stop |
Timestamps in the original audio (seconds) |
duration |
Segment length in seconds |
source_file |
Original filename |
source_id |
Source identifier (from --source-id or inferred from directory) |
Any format ffmpeg can decode: MP3, WAV, MPEG, OGG, FLAC, M4A, WMA, AAC, MP4.
Based on the approach from cawoylel/Segmentation.
MIT