Couper un fichier en plusieurs morceaux sur du silence

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.

---

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *