You can do this manually with ffmpeg
, and of course it can all be scripted if you prefer.
Get silent timestamps
Get silence with the silencedetect filter:
ffmpeg -i input.mp3 -af silencedetect -f null -
Note the default minimum length for silence is set to 2 seconds, but it can be adjusted. See ffmpeg -h filter=silencedetect
.
There is also a silenceremove filter.
Example output using awk
:
$ ffmpeg -i input.mp3 -af silencedetect=d=0.5 -f null - |& awk '/silencedetect/ {print $4,$5}'
silence_start: 1.20837
silence_end: 1.92546
silence_start: 3.51778
silence_end: 4.0881
silence_start: 6.40315
silence_end: 7.7922
Split
There are a few methods to split.
segment muxer
Example of splitting with the segment muxer:
ffmpeg -i input.mp3 -f segment -segment_times 1.20837,1.92546,3.51778,4.0881,6.40315,7.7922 -reset_timestamps 1 -map 0:a -c:a copy output_%03d.mp3
You will need to delete the silent segments. You could perform a Bash loop on the output files, use silencedetect to find these segments, then delete/move them if you want to script that process.
Note the use of -c:a copy
which enables stream copy mode so your MP3 does not get re-encoded to avoid generation loss.
-ss
and -t
or -to
Using these options will omit the silent segments but is more work to make the commands:
ffmpeg -i input.mp3 -to 1.20837 -c copy output_01.mp3
ffmpeg -i input.mp3 -ss 1.92546 -to 3.51778 -c copy output_02.mp3
…and so on.
Or do it in one command:
ffmpeg -i input.mp3 -to 1.20837 -c copy output_01.mp3 -ss 1.92546 -to 3.51778 -c copy output_02.mp3
As in the segment muxer command this also uses stream copy.