Skip to content

Instantly share code, notes, and snippets.

@avanavana
Forked from vi/split_by_silence.sh
Last active March 25, 2021 14:01
Show Gist options
  • Save avanavana/d398542fcb09207542495ad146edfee1 to your computer and use it in GitHub Desktop.
Save avanavana/d398542fcb09207542495ad146edfee1 to your computer and use it in GitHub Desktop.
Using FFmpeg to split multimedia file into parts based on audio volume level
#!/bin/bash
# Modified from original to encode as mp3, renamed to 'splitaudio', and made the usage text more substantial
IN=$1
OUT=$2
true ${SD_PARAMS:="-55dB:d=0.3"};
true ${MIN_FRAGMENT_DURATION:="20"};
export MIN_FRAGMENT_DURATION
if [ -z "$OUT" ]; then
echo "Usage: splitaudio <input_file> <output_template>"
echo ""
echo "Depends on FFmpeg, Bash, Awk, Perl 5. Not tested on Mac or Windows."
echo ""
echo "Arguments:"
echo " <input_file> Media file with silences, to split"
echo " <output_template> A printf-style string such as output-%03d.mp3 which increments for each output file"
echo ""
echo "Environment variables (with their current values):"
echo " SD_PARAMS=$SD_PARAMS Parameters for FFmpeg's silencedetect filter: noise tolerance and minimal silence duration"
echo " MIN_FRAGMENT_DURATION=$MIN_FRAGMENT_DURATION Minimal fragment duration"
exit 1
fi
echo "Determining split points..." >& 2
SPLITS=$(
ffmpeg -v warning -i "$IN" -af silencedetect="$SD_PARAMS",ametadata=mode=print:file=-:key=lavfi.silence_start -vn -sn -f s16le -y /dev/null \
| grep lavfi.silence_start= \
| cut -f 2-2 -d= \
| perl -ne '
our $prev;
INIT { $prev = 0.0; }
chomp;
if (($_ - $prev) >= $ENV{MIN_FRAGMENT_DURATION}) {
print "$_,";
$prev = $_;
}
' \
| sed 's!,$!!'
)
echo "Splitting points are $SPLITS"
ffmpeg -v warning -i "$IN" -c:a mp3 -map 0 -f segment -segment_times "$SPLITS" "$OUT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment