Couper le fichier in.mp3 en plusieurs out_xxx.mp3 quand silence >= 0.5 secondes :
sox -V3 in.mp3 out_.mp3 silence 1 0.5 0.1% 1 0.5 0.1% : newfile : restart
---
Sinon, créer un fichier split_silence.sh :
# First denoise audio ## Get noise sample ffmpeg -i input.ogg -vn -ss 00:00:00 -t 00:00:01 noise-sample.wav ## Create noise profile sox noise-sample.wav -n noiseprof noise.prof ## Clean audio from noise sox input.ogg clean.wav noisered noise.prof 0.21 # Split audio by noise sox -V3 clean.wav output.wav silence 1 0.2 0.4% 1 0.2 0.4% : newfile : restart
---
En utilisant silencedetect de ffmpeg.
Select the required channels and get them through filters.
ffmpeg -i fichierIN -filter_complex "[0:a]silencedetect=n=-50dB:d=1[outa]" -map [outa] test1.mp3
This will give you the corresponding silent time periods and you can use them again to split the video. [0:a] refers to the first input file and map will get the filtered audio output to the output file.
avec ffmpeg
ffmpeg -i "input.mov" -af silencedetect=noise=-30dB:d=0.5 -f null - 2> vol.txt
Cela donnera :
[silencedetect @ 00000000004b02c0] silence_start: -0.0306667 [silencedetect @ 00000000004b02c0] silence_end: 1.42767 | silence_duration: 1.45833 [silencedetect @ 00000000004b02c0] silence_start: 2.21583 [silencedetect @ 00000000004b02c0] silence_end: 2.7585 | silence_duration: 0.542667 ... [silencedetect @ 00000000004b02c0] silence_start: 14.9843 [silencedetect @ 00000000004b02c0] silence_end: 16.5165 | silence_duration: 1.53217
You then generate commands to split from each silence end to the next silence start. You will probably want to add some handles of, say, 250 ms, so
ffmpeg -ss <silence_end - 0.25> -t <next_silence_start - silence_end + 0.25> -i input.mov word-N.mov
(I have skipped specifying audio/video parameters)
You'll want to write a script to scrape the console log and generate a structured (maybe CSV) file with the timecodes - one pair on each line: silence_end and the next silence_start . And then another script to generate the commands with each pair of numbers.
As a oneliner:
ffmpeg -i input.mkv -filter_complex "[0:a]silencedetect=n=-90dB:d=0.3[outa]" -map [outa] -f s16le -y /dev/null |& F='-aq 70 -v warning' perl -ne 'INIT { $ss=0; $se=0; } if (/silence_start: (\S+)/) { $ss=$1; $ctr+=1; printf "ffmpeg -nostdin -i input.mkv -ss %f -t %f $ENV{F} -y %03d.mkv\n", $se, ($ss-$se), $ctr; } if (/silence_end: (\S+)/) { $se=$1; } END { printf "ffmpeg -nostdin -i input.mkv -ss %f $ENV{F} -y %03d.mkv\n", $se, $ctr+1; }' | bash -x – Vi. Jun 13 '16 at 14:28
I now wonder if a) there is a way to ensure ffmpeg does not re-encode the pieces being produced this way, but just copies content to the pieces, b) what is the best way to put all the pieces back together, and c) how to automatically add perhaps an 0.2 seconds audio+video cross-dissolve between each piece, to make the result a bit more pleasant to the eye. This would make it the perfect script for editing video interviews!
To skip re-encoding add -c copy to the last ffmpeg command line.
---