I'm thinking of using ffmpeg to automate a simple video task. I have lots of action videos that go like this, quiet/boring -> loud/exciting -> quiet/boring. Allowing for a few seconds at the start and end of the exciting part I'd like to cut the quiet/boring bits. Can anyone give me some help on the filter/filters I might use?
I'm not well-versed with Unix shell scripting, and also only have basic proficiency in Windows scripting, so I can only offer a pseudocode flow of the script:
1) Break up your full video into N-second segments of only audio (into a temporary folder)
ffmpeg -i GoProFull.mp4 -vn -c:a copy -segment_time n -f segment GP%03d.mp4
Obviously, this will generate a sequence of MP4s where GPx.mp4 represents the n
second audio starting at n*x
seconds. You can get the exact value by running
ffprobe -i GPx.mp4
and parsing for Start: XX.YYYYYY
2) Run ffmpeg with the volumedetect
filter on each of the files
ffmpeg -i GPx.mp4 -af volumedetect -f null - 2> GPx.log
This will produce an output with the final lines looking like this.
[Parsed_volumedetect_0 @ 0000000002584880] n_samples: 575488
[Parsed_volumedetect_0 @ 0000000002584880] mean_volume: -6.6 dB
[Parsed_volumedetect_0 @ 0000000002584880] max_volume: 0.0 dB
[Parsed_volumedetect_0 @ 0000000002584880] histogram_0db: 54799
There may be multiple histogram lines depending on your audio, but the mean and max are on the 2nd and 3rd lines.
3) Now your script should parse those last lines of each log
Check the detected mean and max volumes of each segment. Depending on how long your exciting parts are, and how much of a quiet interval there may be within an exciting segment, decide on whether to use the mean or max (or some evaluating expression involving both) and record the qualifying segment names in a formatted text file. Probably remove the prefix and keep only the unpadded numbers for the next part.
4) Prepare cut list
In the text file containing the numbers of the qualifying segments, collect consecutive segments together, so if your list is 3,4,7,11,13,14,15,18
then you want to treat it as 3+4, 7, 11, 13+14+15, and 18
5) Run ffmpeg to generate the cuts
Now for each cut, use the trim
and atrim
filter to make the cut. For a cut consisting of multiple segments starting with GPx
and ending with GPy
, the time codes for the cut is n*x - top
seconds to n*(y+1) + tail
seconds. You can use ffprobe to get the precise numbers.
ffmpeg -i GoProFull.mp4 -vf "trim=n*x-top:n*(y+1)+tail,setpts=PTS-STARTPTS" -af "atrim=n*x-top:n*(y+1)+tail,asetpts=PTS-STARTPTS" -{video and audio encoding parameters} GPcut-X.mp4
where X is the index of each generated segment.
Output each generated filename, one on each line, into a text file of the form
file 'GPcut-X.mp4'
6) Make into one video.
Run
ffmpeg -f concat -i cutlist.txt -c copy GoPro-Highlights.mp4
where cutlist.txt
is the text file created in step 5.
-
@Mulvya, I split the video into segments of 1 second, and the mean_volume of all of'em were alike. What could be the problem? Since I'm searching for pauses in speech, I can't go beyond 2 or 3 seconds. – Saeed Neamati Dec 15 '15 at 5:26